Slide 1

Slide 1 text

Terraform All The Things! 1 — St. Louis DevOps Meetup

Slide 2

Slide 2 text

Hello I'm Brian Hicks I do cloud stuff [email protected] // @brianhicks 2 — St. Louis DevOps Meetup

Slide 3

Slide 3 text

3 — St. Louis DevOps Meetup

Slide 4

Slide 4 text

4 — St. Louis DevOps Meetup

Slide 5

Slide 5 text

5 — St. Louis DevOps Meetup

Slide 6

Slide 6 text

TODO → VMs → Load Balancer → DNS 6 — St. Louis DevOps Meetup

Slide 7

Slide 7 text

7 — St. Louis DevOps Meetup

Slide 8

Slide 8 text

8 — St. Louis DevOps Meetup

Slide 9

Slide 9 text

9 — St. Louis DevOps Meetup

Slide 10

Slide 10 text

10 — St. Louis DevOps Meetup

Slide 11

Slide 11 text

11 — St. Louis DevOps Meetup

Slide 12

Slide 12 text

12 — St. Louis DevOps Meetup

Slide 13

Slide 13 text

13 — St. Louis DevOps Meetup

Slide 14

Slide 14 text

Provider: AWS provider "aws" { access_key = "AKIAMICJAGGER" secret_key = "gotthemoves/likejagger/scary" region = "us-east-1" } 14 — St. Louis DevOps Meetup

Slide 15

Slide 15 text

Resource: AWS Key Pair resource "aws_key_pair" "brian" { key_name = "brian-hicks-is-the-coolest" public_key = "${file("~/.ssh/id_rsa.pub")}" } 15 — St. Louis DevOps Meetup

Slide 16

Slide 16 text

Resource: AWS Instance resource "aws_instance" "web" { ami = "${data.aws_ami.ubuntu.id}" instance_type = "t2.micro" key_name = "${aws_key_pair.brian.key_name}" tags { Name = "web" } count = 3 } 16 — St. Louis DevOps Meetup

Slide 17

Slide 17 text

Data: AMI ID data "aws_ami" "ubuntu" { most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"] } filter { name = "virtualization-type" values = ["hvm"] } owners = ["099720109477"] # Canonical } 17 — St. Louis DevOps Meetup

Slide 18

Slide 18 text

Resource: AWS ELB resource "aws_elb" "web" { name = "web" instances = ["${aws_instance.web.*.id}"] availability_zones = ["us-east-1b", "us-east-1c", "us-east-1d"] listener { instance_port = 80 instance_protocol = "http" lb_port = 80 lb_protocol = "http" } } 18 — St. Louis DevOps Meetup

Slide 19

Slide 19 text

Terraform Plan (Before) + aws_key_pair.brian fingerprint: "" key_name: "brian-hicks-is-the-coolest" public_key: "ssh-rsa {snip}" 19 — St. Louis DevOps Meetup

Slide 20

Slide 20 text

Terraform Plan (Before) + aws_instance.web.0 ami: "ami-1081b807" associate_public_ip_address: "" availability_zone: "" instance_state: "" instance_type: "t2.micro" key_name: "brian-hicks-is-the-coolest" network_interface_id: "" placement_group: "" private_dns: "" private_ip: "" public_dns: "" public_ip: "" source_dest_check: "true" tags.%: "1" tags.Name: "web" 20 — St. Louis DevOps Meetup

Slide 21

Slide 21 text

Terraform Plan (Before) + aws_elb.web availability_zones.#: "3" availability_zones.1305112097: "us-east-1b" availability_zones.2762590996: "us-east-1d" availability_zones.986537655: "us-east-1c" cross_zone_load_balancing: "true" dns_name: "" health_check.#: "" idle_timeout: "60" listener.#: "1" listener.3057123346.instance_port: "80" listener.3057123346.instance_protocol: "http" listener.3057123346.lb_port: "80" listener.3057123346.lb_protocol: "http" listener.3057123346.ssl_certificate_id: "" name: "web" 21 — St. Louis DevOps Meetup

Slide 22

Slide 22 text

Terraform Apply (the highlights) aws_instance.web.2: Still creating... (10s elapsed) aws_instance.web.1: Still creating... (10s elapsed) aws_instance.web.0: Still creating... (10s elapsed) aws_instance.web.0: Still creating... (20s elapsed) aws_instance.web.2: Still creating... (20s elapsed) aws_instance.web.1: Still creating... (20s elapsed) aws_instance.web.0: Still creating... (30s elapsed) aws_instance.web.2: Still creating... (30s elapsed) aws_instance.web.1: Still creating... (30s elapsed) aws_instance.web.1: Creation complete aws_instance.web.2: Creation complete aws_instance.web.0: Creation complete 22 — St. Louis DevOps Meetup

Slide 23

Slide 23 text

Terraform Plan (After) Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. aws_key_pair.brian: Refreshing state... (ID: brian-hicks-is-the-coolest) data.aws_ami.ubuntu: Refreshing state... aws_instance.web.0: Refreshing state... (ID: i-8e08c999) aws_instance.web.1: Refreshing state... (ID: i-8d08c99a) aws_instance.web.2: Refreshing state... (ID: i-f908c9ee) aws_elb.web: Refreshing state... (ID: web) No changes. Infrastructure is up-to-date. This means that Terraform could not detect any differences between your configuration and the real physical resources that exist. As a result, Terraform doesn't need to do anything. 23 — St. Louis DevOps Meetup

Slide 24

Slide 24 text

Terraform Plan (After) ~ aws_instance.web.2 tags.Name: "web-i-changed" => "web" 24 — St. Louis DevOps Meetup

Slide 25

Slide 25 text

CloudFlare resource "cloudflare_record" "cats" { domain = "brianthicks.com" name = "cats" type = "CNAME" value = "${aws_elb.web.dns_name}" } 25 — St. Louis DevOps Meetup

Slide 26

Slide 26 text

CloudFlare (plan) + cloudflare_record.cats domain: "brianthicks.com" hostname: "" name: "cats" proxied: "false" ttl: "" type: "CNAME" value: "web-336570990.us-east-1.elb.amazonaws.com" zone_id: "" 26 — St. Louis DevOps Meetup

Slide 27

Slide 27 text

Visualization terraform graph | dot -Tpng -ograph.png 27 — St. Louis DevOps Meetup

Slide 28

Slide 28 text

Demo Time! 28 — St. Louis DevOps Meetup

Slide 29

Slide 29 text

Problems, and Their Solutions → State files -> Back up terraform.tfstate → Adding independent resources -> terraform import → Organization -> modules 29 — St. Louis DevOps Meetup

Slide 30

Slide 30 text

Questions? 30 — St. Louis DevOps Meetup

Slide 31

Slide 31 text

Thank You! @brianhicks // [email protected] terraform.io speakerdeck.com/brianhicks/terraform-all-the- things 31 — St. Louis DevOps Meetup