Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Terraform

Andy Gale
October 08, 2014

 Terraform

Lightening introduction to Terraform given at PHPSW on 8th October

Andy Gale

October 08, 2014
Tweet

More Decks by Andy Gale

Other Decks in Technology

Transcript

  1. Terraform
    Andy Gale
    DevOps Consultancy

    View full-size slide

  2. About me
    Andy Gale
    Web Consultant
    Hello Future
    http://hellofutu.re
    !
    @andygale
    @hellofutur3
    DevOps Consultancy

    View full-size slide

  3. Infrastructure as code
    • AWS ec2 instances
    • Digital Ocean droplets
    • Google Cloud Compute Engine
    • Dedicated boxes
    Ansible, Puppet, Chef
    DevOps Consultancy

    View full-size slide

  4. Terraform
    • AWS security groups, VPC, VPC Subnets,
    Amazon RDS
    • DNS with Digital Ocean, DNSimple, Route 53
    DevOps Consultancy

    View full-size slide

  5. Terraform
    http://www.terraform.io/downloads.html
    Install
    DevOps Consultancy

    View full-size slide

  6. Terraform
    Digital Ocean example
    resource "digitalocean_droplet" "web" {
    image = "ubuntu-14-04-x64"
    name = "web-1"
    region = "nyc2"
    size = "512mb"
    }
    DevOps Consultancy

    View full-size slide

  7. Terraform
    AWS security group example
    # Security group for web server
    !
    resource "aws_security_group" "hello_web" {
    name = "hello-elb-sg"
    description = "Security Group for web servers"
    !
    # HTTP access from anywhere
    ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    }
    }
    DevOps Consultancy

    View full-size slide

  8. Terraform
    AWS security group example
    $ terraform plan
    !
    + aws_security_group.hello_web
    description: "" => "Security Group for web servers"
    ingress.#: "" => "1"
    ingress.0.cidr_blocks.#: "" => "1"
    ingress.0.cidr_blocks.0: "" => "0.0.0.0/0"
    ingress.0.from_port: "" => "80"
    ingress.0.protocol: "" => "tcp"
    ingress.0.to_port: "" => "80"
    name: "" => "hello-elb-sg"
    owner_id: "" => ""
    !
    DevOps Consultancy

    View full-size slide

  9. Terraform
    AWS security group example
    $ terraform apply
    !
    aws_security_group.hello_web: Creating...
    description: "" => "Security Group for web servers"
    ingress.#: "" => "1"
    ingress.0.cidr_blocks.#: "" => "1"
    ingress.0.cidr_blocks.0: "" => "0.0.0.0/0"
    ingress.0.from_port: "" => "80"
    ingress.0.protocol: "" => "tcp"
    ingress.0.to_port: "" => "80"
    name: "" => "hello-elb-sg"
    owner_id: "" => ""
    aws_security_group.hello_web: Creation complete
    !
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

    View full-size slide

  10. # Security group for web server
    !
    resource "aws_security_group" "hello_web" {
    name = "hello-elb-sg"
    description = "Security Group for web servers"
    !
    # HTTP access from anywhere
    ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    }
    !
    ingress {
    from_port = 443
    to_port = 443
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    }
    }
    Adding HTTPS
    DevOps Consultancy

    View full-size slide

  11. $ terraform plan
    !
    -/+ aws_security_group.hello_web
    description: "Security Group for web servers" =>
    "Security Group for web servers"
    ingress.#: "1" => "2"
    ingress.0.cidr_blocks.#: "1" => "1"
    ingress.0.cidr_blocks.0: "0.0.0.0/0" => "0.0.0.0/0"
    ingress.0.from_port: "80" => "80"
    ingress.0.protocol: "tcp" => "tcp"
    ingress.0.to_port: "80" => "80"
    ingress.1.cidr_blocks.#: "" => "1"
    ingress.1.cidr_blocks.0: "" => "0.0.0.0/0"
    ingress.1.from_port: "" => "443"
    ingress.1.protocol: "" => "tcp"
    ingress.1.to_port: "" => "443"
    name: "hello-elb-sg" => "hello-elb-sg"
    owner_id: "803559457126" => ""
    vpc_id: "vpc-8f18e0ea" => "" (forces new
    resource)
    !
    !
    !
    DevOps Consultancy
    Terraform tells us what it will do

    View full-size slide

  12. $ terraform apply
    !
    aws_security_group.hello_web: Refreshing state... (ID: sg-393a8c5c)
    aws_security_group.hello_web: Destroying...
    aws_security_group.hello_web: Destruction complete
    aws_security_group.hello_web: Modifying...
    description: "Security Group for web servers" =>
    "Security Group for web servers"
    ingress.#: "1" => "2"
    ingress.0.cidr_blocks.#: "1" => "1"
    ingress.0.cidr_blocks.0: "0.0.0.0/0" => "0.0.0.0/0"
    ingress.0.from_port: "80" => "80"
    ingress.0.protocol: "tcp" => "tcp"
    ingress.0.to_port: "80" => "80"
    ingress.1.cidr_blocks.#: "" => "1"
    ingress.1.cidr_blocks.0: "" => "0.0.0.0/0"
    ingress.1.from_port: "" => "443"
    ingress.1.protocol: "" => "tcp"
    ingress.1.to_port: "" => "443"
    name: "hello-elb-sg" => "hello-elb-sg"
    owner_id: "803559457126" => ""
    vpc_id: "vpc-8f18e0ea" => ""
    aws_security_group.hello_web: Modifications complete
    !
    Apply complete! Resources: 0 added, 1 changed, 1 destroyed.
    Terraform applies configuration

    View full-size slide

  13. Adding an instance
    DevOps Consultancy

    View full-size slide

  14. Variables
    variable "access_key" {}
    variable "secret_key" {}
    !
    variable "key_name" {}
    variable "key_path" {}
    !
    variable "region" {
    default = "eu-west-1"
    }
    !
    variable "amis" {
    default = {
    eu-west-1 = "ami-f4b11183"
    us-east-1 = "ami-9aaa1cf2"
    us-west-2 = "ami-39501209"
    }
    }
    DevOps Consultancy

    View full-size slide

  15. Terraform
    terraform.tfvars
    access_key = "XXXXXXXXXXXXXXXXXXXX"
    secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    key_path = ".ssh/mykey.pem"
    key_name = "mykey"
    You’d likely keep this in .gitignore
    DevOps Consultancy

    View full-size slide

  16. resource "aws_instance" "web" {
    !
    connection {
    user = "ubuntu"
    key_file = "${var.key_path}"
    }
    !
    instance_type = "t2.micro"
    ami = "${lookup(var.amis, var.region)}"
    !
    key_name = "${var.key_name}"
    !
    security_groups = ["${aws_security_group.hello_web.name}"]
    !
    provisioner "remote-exec" {
    inline = [
    "sudo apt-get -y update",
    "sudo apt-get -y install nginx",
    "sudo service nginx start"
    ]
    }
    }
    DevOps Consultancy
    Create instance

    View full-size slide

  17. # Security group for web server
    !
    resource "aws_security_group" "hello_web" {
    name = "hello-elb-sg"
    description = "Security Group for web servers"
    !
    # HTTP access from anywhere
    ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    }
    !
    ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    }
    !
    }
    Adding SSH
    DevOps Consultancy

    View full-size slide

  18. $ terraform apply
    aws_security_group.hello_web: Creating...
    description: "" => "Security Group for web servers"
    ingress.#: "" => "2"
    ingress.0.cidr_blocks.#: "" => "1"
    ingress.0.cidr_blocks.0: "" => "0.0.0.0/0"
    ingress.0.from_port: "" => "22"
    ingress.0.protocol: "" => "tcp"
    ingress.0.to_port: "" => "22"
    ingress.1.cidr_blocks.#: "" => "1"
    ingress.1.cidr_blocks.0: "" => "0.0.0.0/0"
    ingress.1.from_port: "" => "80"
    ingress.1.protocol: "" => "tcp"
    ingress.1.to_port: "" => "80"
    name: "" => "hello-elb-sg"
    owner_id: "" => ""
    aws_security_group.hello_web: Creation complete
    aws_instance.web: Creating...
    ami: "" => "ami-f4b11183"
    availability_zone: "" => ""
    instance_type: "" => "t2.micro"
    key_name: "" => "hellofuture"
    private_dns: "" => ""
    private_ip: "" => ""
    public_dns: "" => ""
    public_ip: "" => ""
    security_groups.#: "" => "1"
    security_groups.0: "" => "hello-elb-sg"
    subnet_id: "" => ""
    aws_instance.web: Provisioning with 'remote-exec'...
    aws_instance.web: Creation complete
    !
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    Terraform applies configuration

    View full-size slide

  19. resource "aws_instance" "web" {
    !
    connection {
    user = "ubuntu"
    key_file = "${var.key_path}"
    }
    !
    instance_type = "t2.micro"
    ami = "${lookup(var.amis, var.region)}"
    !
    key_name = "${var.key_name}"
    !
    security_groups = ["${aws_security_group.hello_web.name}"]
    !
    provisioner "local-exec" {
    command = "knife bootstrap ${aws_instance.example.public_ip}"
    }
    }
    }
    DevOps Consultancy
    Using with Chef

    View full-size slide

  20. Packer
    • Terraform works well with AMIs generated by
    Packer
    • http://www.packer.io/
    DevOps Consultancy

    View full-size slide

  21. Terraform
    • Amazon autoscaling groups, RDS, ELB, EIP, S3, VPC
    • Cloudflare DNS
    • Consul
    • Digital Ocean DNS
    • Google Cloud
    • Herkou
    • Mailgun
    DevOps Consultancy
    What else can you do

    View full-size slide