Slide 1

Slide 1 text

Terraform Andy Gale DevOps Consultancy

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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.

Slide 10

Slide 10 text

# 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

Slide 11

Slide 11 text

$ 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

Slide 12

Slide 12 text

$ 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

Slide 13

Slide 13 text

Adding an instance DevOps Consultancy

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

# 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

Slide 18

Slide 18 text

$ 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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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