Slide 1

Slide 1 text

TERRAFORM JOSH MICHIELSEN 1 Josh Michielsen | jaymickey | jmickey_ | jmichielsen | @ [email protected]

Slide 2

Slide 2 text

TERRAFORM IS A TOOL FOR BUILDING, CHANGING, AND VERSIONING INFRASTRUCTURE SAFELY AND EFFICIENTLY. TERRAFORM CAN MANAGE EXISTING AND POPULAR SERVICE PROVIDERS AS WELL AS CUSTOM IN-HOUSE SOLUTIONS terraform.io/intro WHAT IS TERRAFORM? 2 Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 3

Slide 3 text

WHAT IS TERRAFORM QUICK OVERVIEW ▸ Developed by HashiCorp. ▸ Open Source, written in Go. ▸ Command line tool. ▸ Declarative programming. ▸ HashiCorp Configuration Language (HCL). ▸ Domain Specific Language (DSL). Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected] 3

Slide 4

Slide 4 text

IMPERATIVE VS. DECLARATIVE PROGRAMMING IMPERATIVE ▸ “A programming paradigm that describes computation in terms of statements that change a program state.” - Wikipedia1 ▸ Less wanky: Set of instructions that describe how to get to a certain state. 4 def makeCoffee(sugars=0, milk=False): cup = Cup() cup.add_grounds() cup.add_water(hot=True) if sugars: cup.add_sugar(sugars) if milk: cup.add_milk() return cup Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 5

Slide 5 text

IMPERATIVE VS. DECLARATIVE PROGRAMMING DECLARATIVE ‣ “A programming paradigm, a style of building the structure and elements of computer programs, that expresses the logic of a computation without describing its control flow.” - Wikipedia1 ‣ Less wanky: Declaring what state you want the system to be in, without the details of how to get there. ‣ Much of the logic is abstracted. Often this is presented to the user as a Domain Specific Language (DSL). 5 coffee = { 'hot': True, 'milk': True, 'sugars': 1 } Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 6

Slide 6 text

TERRAFORM BASICS WS credentials should ion = "${var.region}" trieves latest Amazon Linux AMI. "aws_ami" "aws_linux_ami" { st_recent = true lter { name = "name" values = ["amzn-ami-hvm-*-x86_64-gp2"] ilter { name = "virtualization-type" values = ["hvm"] } dule "web_ec2" { source = " ../modules/ec2" env = "${var.env}" ami_id = "${data.aws_ami.aws_linux_ami.id}" count = "${var.count}" subnet_id = "${var.subnet_id}" module "web_elb" { source = " ../modules/elb" env = "${var.env}" var.instance_port}" " 6

Slide 7

Slide 7 text

TERRAFORM BASICS PROVIDERS Providers are the abstraction layer between you and the service you’re attempting to automate. These services include IaaS (e.g. OpenStack, Digital Ocean), PaaS (e.g. Heroku), SaaS (e.g. CloudFlare, GitHub), and full service cloud (e.g. AWS, Azure). # Provider declaration provider "aws" { # AWS credentials should be declared as environment variables. region = “ap-southeast-2“ } 7 main.tf Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 8

Slide 8 text

TERRAFORM BASICS DATA Data allows you to query the provider API for information that you can then use to configure Terraform resources. Examples of data includes: AWS AMI, Azure DNS zone, GitHub user. # Retrieves latest Amazon Linux AMI. data "aws_ami" "aws_linux_ami" { most_recent = true filter { name = "name" values = ["amzn-ami-hvm-*-x86_64-gp2"] } filter { name = "virtualization-type" values = ["hvm"] } } 8 main.tf Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 9

Slide 9 text

TERRAFORM BASICS RESOURCES Resources are the most important things you’ll configure in Terraform. When you declare a resource, you are declaring a tangible component of your infrastructure. Some examples of resources: EC2 instance, GitHub repo, CloudFlare DNS record. resource "aws_instance" "an_ec2_instance" { count = "1" ami = "${data.aws_ami.aws_linux_ami.id}" instance_type = "t2.micro" subnet_id = "subnet-11223344" tags = { Name = "Some instance" Product = "Some product" Environment = "Prod" Terraform = "true" } } 9 main.tf Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 10

Slide 10 text

TERRAFORM BASICS VARIABLES Variables allow you to parameterise your Terraform configurations. Allowing you to re-use the same code across multiple environments, with values passed to the config at runtime. Variable declarations can be declared with default values, making them optional. Terraform will automatically detect the terraform.tfvars file if it exists, or you can pass another .tfvars file at runtime (e.g. qa.tfvars). # Required variables variable "env" {} variable "count" {} # Variables with defaults variable "instance_type" { default = "t2.micro" } resource "aws_instance" "an_ec2_instance" { count = "${var.count}" ami = "${data.aws_ami.aws_linux_ami.id}" instance_type = "${var.instance_type}" } 10 main.tf env = "qa" count = “2" qa.tfvars Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 11

Slide 11 text

TERRAFORM BASICS OUTPUT When you use Terraform to create infrastructure, it knows everything about those resources. Outputs allow you to tell Terraform which information is important to you. Terraform will output this information after a configuration has been applied, or you can query it on-demand using the terraform output command. resource "aws_instance" "an_ec2_instance" { count = "1" ami = "${data.aws_ami.aws_linux_ami.id}" instance_type = "t2.micro" } output "instance_ids" { value = "${aws_instance.ec2.id}" } 11 main.tf Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 12

Slide 12 text

TERRAFORM BASICS TFSTATE Terraform stores the state of all the resources it manages within a text file named terraform.tfstate. This file stores all the configuration state and metadata of each resources being managed within an applied configuration. Terraform uses this state file to create plans and make changes, and will refresh the state with the live infrastructure when calling any operation. Terraform also supports storing of this state file in remote backends such as Amazon S3. 12 Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 13

Slide 13 text

TERRAFORM STRUCTURE WS credentials should ion = "${var.region}" trieves latest Amazon Linux AMI. "aws_ami" "aws_linux_ami" { st_recent = true lter { name = "name" values = ["amzn-ami-hvm-*-x86_64-gp2"] ilter { name = "virtualization-type" values = ["hvm"] } dule "web_ec2" { source = " ../modules/ec2" env = "${var.env}" ami_id = "${data.aws_ami.aws_linux_ami.id}" count = "${var.count}" subnet_id = "${var.subnet_id}" module "web_elb" { source = " ../modules/elb" env = "${var.env}" var.instance_port}" " 13

Slide 14

Slide 14 text

TERRAFORM STRUCTURE THE TERRALITH ▸ “Monolithic” implementation of Terraform configuration. ▸ All config in a single file. ▸ Limited or no use of variables. terraform/ ├── main.tf ├── terraform.tfvars 14 Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 15

Slide 15 text

TERRAFORM STRUCTURE GETTING BETTER terraform/ ├── base/ │ ├── vpc.tf │ ├── network.tf │ ├── variables.tf │ ├── terraform.tfvars ├── qa/ │ ├── ec2.tf │ ├── cloudwatch.tf │ ├── route53.tf │ ├── variables.tf │ ├── terraform.tfvars └── prod/ │ ├── ec2.tf │ ├── cloudwatch.tf │ ├── route53.tf │ ├── variables.tf │ ├── terraform.tfvars 15 ▸ Environments separated into own their own configs. ▸ Parameterisation and code reuse. ▸ However, hard to manage and lots of duplication. Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 16

Slide 16 text

A BETTER WAY? ider decl er "aws" { S credentials should be declared as environment variabl on = "${var.region}" rieves latest Amazon Linux AMI. "aws_ami" "aws_linux_ami" { t_recent = true lter { name = "name" values = ["amzn-ami-hvm-*-x86_64-gp2"] lter { name = "virtualization-type" values = ["hvm"] ule "web_ec2" { source = " ../modules/ec2" env = "${var.env}" ami_id = "${data.aws_ami.aws_linux_ami.id}" count = "${var.count}" subnet_id = "${var.subnet_id}" odule "web_elb" { = " ../modules/elb"

Slide 17

Slide 17 text

TERRAFORM STRUCTURE INTRODUCING MODULES terraform/ ├── base/ │ ├── main.tf │ ├── variables.tf │ ├── terraform.tfvars ├── qa/ │ ├── main.tf │ ├── variables.tf │ ├── terraform.tfvars ├── prod/ │ ├── main.tf │ ├── variables.tf │ ├── terraform.tfvars ├── modules/ │ ├── ec2/ │ │ ├── main.tf │ │ ├── variables.tf │ │ ├── output.tf │ └── elb/ │ ├── main.tf │ ├── variables.tf | ├── output.tf 17 ▸ Reusable blocks of code. ▸ Highly parameterised. ▸ Modelled on your architecture. Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 18

Slide 18 text

TERRAFORM SOME COMMENTS ▸ Your Terraform structure should model your service structure. ▸ Should I make X a variable: Yes. ▸ Segregate, segregate, segregate. ▸ Protect your .tfstate file with your life. ▸ Use a remote backend, with versioning. ▸ Don’t use Terraform for state (DynamoDB, RDS, etc). 18 Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 19

Slide 19 text

DEMO Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]

Slide 20

Slide 20 text

THANKS! ‣ Official Terraform Docs: https://www.terraform.io/intro/index.html ‣ Charity Majors blog posts: ‣ https://charity.wtf/2016/03/30/terraform-vpc-and-why-you-want-a-tfstate-file-per-env/ ‣ https://charity.wtf/2016/04/14/scrapbag-of-useful-terraform-tips/ ‣ Terraform Module Registry: https://registry.terraform.io/ RESOURCES 20 Josh Michielsen | jmickey | jmickey_ | jmichielsen | @ [email protected]