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

Terraform: An Overview & Introduction

David Chou
January 29, 2019

Terraform: An Overview & Introduction

David Chou

January 29, 2019
Tweet

More Decks by David Chou

Other Decks in Research

Transcript

  1. Infrastructure as Code (IaC) The Process of Managing and Provisioning

    Computer Data Centers Through Machine-Readable Definition Files
  2. HCL A structured configuration language that is both human and

    machine friendly, and specifically targeted towards DevOps tools, etc. #An AMI variable "ami" { description = "the AMI to use" } /* A multi line comment. */ resource "aws_instance" "web" { ami = "${var.ami}" count = 2 source_dest_check = false connection { user = "root" } }
  3. Terraform Cloudformation provider "aws" { #Set AWS_ACCESS_KEY_ID #AWS_SECRET_ACCESS_KEY env vars

    region = "us-west-2" } resource "aws_s3_bucket" "my-cool-bucket" { bucket = "my-cool-bucket" acl = "public-read" } 1 2 3 4 5 6 7 8 9 10 { "Resources" : { "my-cool-bucket" : { "Type" : "AWS::S3::Bucket", "Properties" : { "AccessControl" : "PublicRead } } } } 1 2 3 4 5 6 7 8 9 10
  4. Terraform flow $ terraform init To initialize a working directory

    containing Terraform configuration files $ terraform plan Terraform performs a refresh, then determines what actions are necessary to achieve the desired state specified in the configuration files. $ terraform apply Apply the changes required to reach the desired state of the configuration
  5. main.tf #Configure aws with a default region provider "aws" {

    region = "us-east-1" } /*Create a demo s3 bucket*/ resource "aws_s3_bucket" "umbocv-demo-bucket" { bucket = "umbocv-demo-bucket" tags { Name = "umbocv-demo-bucket" Environment = "internal" Purpose = "demo" } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 provider "aws" { region = "us-east-1" } #Configure aws with a default region 1 2 3 4 5 /*Create a demo s3 bucket*/ 6 resource "aws_s3_bucket" "umbocv-demo-bucket" { 7 bucket = "umbocv-demo-bucket" 8 9 tags { 10 Name = "umbocv-demo-bucket" 11 Environment = "internal" 12 Purpose = "demo" 13 } 14 } 15 resource "aws_s3_bucket" "umbocv-demo-bucket" { #Configure aws with a default region 1 provider "aws" { 2 region = "us-east-1" 3 } 4 5 /*Create a demo s3 bucket*/ 6 7 bucket = "umbocv-demo-bucket" 8 9 tags { 10 Name = "umbocv-demo-bucket" 11 Environment = "internal" 12 Purpose = "demo" 13 } 14 } 15 bucket = "umbocv-demo-bucket" tags { Name = "umbocv-demo-bucket" Environment = "internal" Purpose = "demo" } #Configure aws with a default region 1 provider "aws" { 2 region = "us-east-1" 3 } 4 5 /*Create a demo s3 bucket*/ 6 resource "aws_s3_bucket" "umbocv-demo-bucket" { 7 8 9 10 11 12 13 14 } 15
  6. variables.tf main.tf provider "aws" { region = "${var.region}" } resource

    "aws_instance" "helloworld ami = "${lookup(var.ami instance_type = "t2.micro" } resource "aws_eip" "ip" { instance = "${aws_instance.hellow } 1 2 3 4 5 6 7 8 9 10 11 12 resource "aws_instance" "helloworld instance = "${aws_instance.hellow provider "aws" { 1 region = "${var.region}" 2 } 3 4 5 ami = "${lookup(var.ami 6 instance_type = "t2.micro" 7 } 8 9 resource "aws_eip" "ip" { 10 11 } 12 region = "${var.region}" provider "aws" { 1 2 } 3 4 resource "aws_instance" "helloworld 5 ami = "${lookup(var.ami 6 instance_type = "t2.micro" 7 } 8 9 resource "aws_eip" "ip" { 10 instance = "${aws_instance.hellow 11 } 12 ami = "${lookup(var.ami provider "aws" { 1 region = "${var.region}" 2 } 3 4 resource "aws_instance" "helloworld 5 6 instance_type = "t2.micro" 7 } 8 9 resource "aws_eip" "ip" { 10 instance = "${aws_instance.hellow 11 } 12 variable "region" { default = "ap-northeast-1" } variable "ami" { type = "map" default = { "ap-northeast-1" = "ami-044c1940d8 "us-east-1" = "ami-015a7a34db } } 1 2 3 4 5 6 7 8 9 10 11 12 } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 variable "ami" { 5 type = "map" 6 7 default = { 8 "ap-northeast-1" = "ami-044c1940d8 9 "us-east-1" = "ami-015a7a34db 10 } 11 12 variable "region" { default = "ap-northeast-1" } 1 2 3 4 variable "ami" { 5 type = "map" 6 7 default = { 8 "ap-northeast-1" = "ami-044c1940d8 9 "us-east-1" = "ami-015a7a34db 10 } 11 } 12 variable "ami" { type = "map" default = { "ap-northeast-1" = "ami-044c1940d8 "us-east-1" = "ami-015a7a34db } } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 5 6 7 8 9 10 11 12
  7. Terraform plan + aws_eip.ip id: <computed> instance: "${aws_instance.helloworld.id}" network_interface: <computed>

    vpc: <computed> + aws_instance.helloworld id: <computed> ami: "ami-044c1940d801a38d6" arn:
  8. variables.tf apne1.tfvars usea1.tfvars variable "region" { default = "ap-northeast-1" }

    variable "name" { default = "" } variable "tags" { type = "map" default = {} } variable "cidr" { default = "0.0.0.0/0" } variable "azs" { type = "list" default = [] } variable "public_subnets" { type = "list" default = [] } variable "private_subnets" { type = "list" default = [] } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 variable "region" { default = "ap-northeast-1" } 1 2 3 4 variable "name" { 5 default = "" 6 } 7 8 variable "tags" { 9 type = "map" 10 default = {} 11 } 12 13 variable "cidr" { 14 default = "0.0.0.0/0" 15 } 16 17 variable "azs" { 18 type = "list" 19 default = [] 20 } 21 22 variable "public_subnets" { 23 type = "list" 24 default = [] 25 } 26 27 variable "private_subnets" { 28 type = "list" 29 default = [] 30 } 31 variable "name" { default = "" } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 5 6 7 8 variable "tags" { 9 type = "map" 10 default = {} 11 } 12 13 variable "cidr" { 14 default = "0.0.0.0/0" 15 } 16 17 variable "azs" { 18 type = "list" 19 default = [] 20 } 21 22 variable "public_subnets" { 23 type = "list" 24 default = [] 25 } 26 27 variable "private_subnets" { 28 type = "list" 29 default = [] 30 } 31 variable "tags" { type = "map" default = {} variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 variable "name" { 5 default = "" 6 } 7 8 9 10 11 } 12 13 variable "cidr" { 14 default = "0.0.0.0/0" 15 } 16 17 variable "azs" { 18 type = "list" 19 default = [] 20 } 21 22 variable "public_subnets" { 23 type = "list" 24 default = [] 25 } 26 27 variable "private_subnets" { 28 type = "list" 29 default = [] 30 } 31 variable "cidr" { default = "0.0.0.0/0" } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 variable "name" { 5 default = "" 6 } 7 8 variable "tags" { 9 type = "map" 10 default = {} 11 } 12 13 14 15 16 17 variable "azs" { 18 type = "list" 19 default = [] 20 } 21 22 variable "public_subnets" { 23 type = "list" 24 default = [] 25 } 26 27 variable "private_subnets" { 28 type = "list" 29 default = [] 30 } 31 variable "azs" { type = "list" default = [] } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 variable "name" { 5 default = "" 6 } 7 8 variable "tags" { 9 type = "map" 10 default = {} 11 } 12 13 variable "cidr" { 14 default = "0.0.0.0/0" 15 } 16 17 18 19 20 21 22 variable "public_subnets" { 23 type = "list" 24 default = [] 25 } 26 27 variable "private_subnets" { 28 type = "list" 29 default = [] 30 } 31 variable "public_subnets" { type = "list" default = [] } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 variable "name" { 5 default = "" 6 } 7 8 variable "tags" { 9 type = "map" 10 default = {} 11 } 12 13 variable "cidr" { 14 default = "0.0.0.0/0" 15 } 16 17 variable "azs" { 18 type = "list" 19 default = [] 20 } 21 22 23 24 25 26 27 variable "private_subnets" { 28 type = "list" 29 default = [] 30 } 31 variable "private_subnets" { type = "list" default = [] } variable "region" { 1 default = "ap-northeast-1" 2 } 3 4 variable "name" { 5 default = "" 6 } 7 8 variable "tags" { 9 type = "map" 10 default = {} 11 } 12 13 variable "cidr" { 14 default = "0.0.0.0/0" 15 } 16 17 variable "azs" { 18 type = "list" 19 default = [] 20 } 21 22 variable "public_subnets" { 23 type = "list" 24 default = [] 25 } 26 27 28 29 30 31 region = "ap-northeast-1" name = "david74-vpc" tags = { "Environment" = "internal" "Purpose" = "test" } cidr = "10.0.0.0/16" azs = ["ap-northeast-1a", "ap-northeast-1c" public_subnets = ["10.0.0.0/24", "10.0.1.0/ private_subnets = ["10.0.10.0/24", "10.0.11 1 2 3 4 5 6 7 8 9 10 region = "ap-northeast-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.0.0.0/16" 7 azs = ["ap-northeast-1a", "ap-northeast-1c" 8 public_subnets = ["10.0.0.0/24", "10.0.1.0/ 9 private_subnets = ["10.0.10.0/24", "10.0.11 10 name = "david74-vpc" region = "ap-northeast-1" 1 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.0.0.0/16" 7 azs = ["ap-northeast-1a", "ap-northeast-1c" 8 public_subnets = ["10.0.0.0/24", "10.0.1.0/ 9 private_subnets = ["10.0.10.0/24", "10.0.11 10 tags = { "Environment" = "internal" "Purpose" = "test" } region = "ap-northeast-1" 1 name = "david74-vpc" 2 3 4 5 6 cidr = "10.0.0.0/16" 7 azs = ["ap-northeast-1a", "ap-northeast-1c" 8 public_subnets = ["10.0.0.0/24", "10.0.1.0/ 9 private_subnets = ["10.0.10.0/24", "10.0.11 10 cidr = "10.0.0.0/16" region = "ap-northeast-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 7 azs = ["ap-northeast-1a", "ap-northeast-1c" 8 public_subnets = ["10.0.0.0/24", "10.0.1.0/ 9 private_subnets = ["10.0.10.0/24", "10.0.11 10 azs = ["ap-northeast-1a", "ap-northeast-1c" region = "ap-northeast-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.0.0.0/16" 7 8 public_subnets = ["10.0.0.0/24", "10.0.1.0/ 9 private_subnets = ["10.0.10.0/24", "10.0.11 10 public_subnets = ["10.0.0.0/24", "10.0.1.0/ region = "ap-northeast-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.0.0.0/16" 7 azs = ["ap-northeast-1a", "ap-northeast-1c" 8 9 private_subnets = ["10.0.10.0/24", "10.0.11 10 private_subnets = ["10.0.10.0/24", "10.0.11 region = "ap-northeast-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.0.0.0/16" 7 azs = ["ap-northeast-1a", "ap-northeast-1c" 8 public_subnets = ["10.0.0.0/24", "10.0.1.0/ 9 10 region = "us-east-1" name = "david74-vpc" tags = { "Environment" = "internal" "Purpose" = "test" } cidr = "10.1.0.0/16" azs = ["us-east-1a", "us-east-1b"] public_subnets = ["10.1.0.0/24", "10.1.1.0/ private_subnets = ["10.1.10.0/24", "10.1.11 1 2 3 4 5 6 7 8 9 10 region = "us-east-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.1.0.0/16" 7 azs = ["us-east-1a", "us-east-1b"] 8 public_subnets = ["10.1.0.0/24", "10.1.1.0/ 9 private_subnets = ["10.1.10.0/24", "10.1.11 10 name = "david74-vpc" region = "us-east-1" 1 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.1.0.0/16" 7 azs = ["us-east-1a", "us-east-1b"] 8 public_subnets = ["10.1.0.0/24", "10.1.1.0/ 9 private_subnets = ["10.1.10.0/24", "10.1.11 10 tags = { "Environment" = "internal" "Purpose" = "test" } region = "us-east-1" 1 name = "david74-vpc" 2 3 4 5 6 cidr = "10.1.0.0/16" 7 azs = ["us-east-1a", "us-east-1b"] 8 public_subnets = ["10.1.0.0/24", "10.1.1.0/ 9 private_subnets = ["10.1.10.0/24", "10.1.11 10 cidr = "10.1.0.0/16" region = "us-east-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 7 azs = ["us-east-1a", "us-east-1b"] 8 public_subnets = ["10.1.0.0/24", "10.1.1.0/ 9 private_subnets = ["10.1.10.0/24", "10.1.11 10 azs = ["us-east-1a", "us-east-1b"] region = "us-east-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.1.0.0/16" 7 8 public_subnets = ["10.1.0.0/24", "10.1.1.0/ 9 private_subnets = ["10.1.10.0/24", "10.1.11 10 public_subnets = ["10.1.0.0/24", "10.1.1.0/ region = "us-east-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.1.0.0/16" 7 azs = ["us-east-1a", "us-east-1b"] 8 9 private_subnets = ["10.1.10.0/24", "10.1.11 10 private_subnets = ["10.1.10.0/24", "10.1.11 region = "us-east-1" 1 name = "david74-vpc" 2 tags = { 3 "Environment" = "internal" 4 "Purpose" = "test" 5 } 6 cidr = "10.1.0.0/16" 7 azs = ["us-east-1a", "us-east-1b"] 8 public_subnets = ["10.1.0.0/24", "10.1.1.0/ 9 10
  9. #VPC resource "aws_vpc" "main" { cidr_block = "${var.cidr}" enable_dns_support =

    true enable_dns_hostnames = true tags = "${merge(map("Name", format("%s", var.name)), va } /* tags = { "Name" = "david74-vpc" "Environment" = "internal" "Purpose" = "test" } */ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 resource "aws_vpc" "main" { cidr_block = "${var.cidr}" #VPC 1 2 3 enable_dns_support = true 4 enable_dns_hostnames = true 5 6 tags = "${merge(map("Name", format("%s", var.name)), va 7 } 8 9 /* 10 tags = { 11 "Name" = "david74-vpc" 12 "Environment" = "internal" 13 "Purpose" = "test" 14 } 15 */ 16 tags = "${merge(map("Name", format("%s", var.name)), va tags = { "Name" = "david74-vpc" "Environment" = "internal" "Purpose" = "test" } #VPC 1 resource "aws_vpc" "main" { 2 cidr_block = "${var.cidr}" 3 enable_dns_support = true 4 enable_dns_hostnames = true 5 6 7 } 8 9 /* 10 11 12 13 14 15 */ 16 #VPC resource "aws_vpc" "main" { cidr_block = "${var.cidr}" enable_dns_support = true enable_dns_hostnames = true tags = "${merge(map("Name", format("%s", var.name)), va } /* tags = { "Name" = "david74-vpc" "Environment" = "internal" "Purpose" = "test" } */ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #Internet gateway resource "aws_internet_gateway" "igw" { vpc_id = "${aws_vpc.main.id}" tags = "${merge(map("Name", format("%s", var.name)), var } 1 2 3 4 5 6 vpc_id = "${aws_vpc.main.id}" #Internet gateway 1 resource "aws_internet_gateway" "igw" { 2 3 4 tags = "${merge(map("Name", format("%s", var.name)), var 5 } 6 Create VPC Create Internet Gateway
  10. #NAT gateway resource "aws_eip" "nat" { vpc = true depends_on

    = ["aws_internet_gateway.igw"] tags = "${merge(map("Name", format("%s-nat", var.name)), var.tags)}" } resource "aws_nat_gateway" "ngw" { allocation_id = "${aws_eip.nat.id}" subnet_id = "${aws_subnet.public.0.id}" tags = "${merge(map("Name", format("%s", var.name)), var.tags)}" } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 resource "aws_eip" "nat" { vpc = true depends_on = ["aws_internet_gateway.igw"] tags = "${merge(map("Name", format("%s-nat", var.name)), var.tags)}" } #NAT gateway 1 2 3 4 5 6 7 8 resource "aws_nat_gateway" "ngw" { 9 allocation_id = "${aws_eip.nat.id}" 10 subnet_id = "${aws_subnet.public.0.id}" 11 12 tags = "${merge(map("Name", format("%s", var.name)), var.tags)}" 13 } 14 depends_on = ["aws_internet_gateway.igw"] #NAT gateway 1 resource "aws_eip" "nat" { 2 vpc = true 3 4 5 tags = "${merge(map("Name", format("%s-nat", var.name)), var.tags)}" 6 } 7 8 resource "aws_nat_gateway" "ngw" { 9 allocation_id = "${aws_eip.nat.id}" 10 subnet_id = "${aws_subnet.public.0.id}" 11 12 tags = "${merge(map("Name", format("%s", var.name)), var.tags)}" 13 } 14 allocation_id = "${aws_eip.nat.id}" #NAT gateway 1 resource "aws_eip" "nat" { 2 vpc = true 3 depends_on = ["aws_internet_gateway.igw"] 4 5 tags = "${merge(map("Name", format("%s-nat", var.name)), var.tags)}" 6 } 7 8 resource "aws_nat_gateway" "ngw" { 9 10 subnet_id = "${aws_subnet.public.0.id}" 11 12 tags = "${merge(map("Name", format("%s", var.name)), var.tags)}" 13 } 14 Create NAT Gateway
  11. /* Private subnet */ resource "aws_subnet" "private" { count =

    "${length(var.azs)}" vpc_id = "${aws_vpc.main.id}" availability_zone = "${element(var.azs, count.index)}" cidr_block = "${element(var.private_subnets, count.index)}" map_public_ip_on_launch = false tags = "${merge(map("Name", format("%s-private-%s", var.name, element(var.azs, count.index))), var.tags)}" } /* Public subnet */ resource "aws_subnet" "public" { count = "${length(var.azs)}" vpc_id = "${aws_vpc.main.id}" availability_zone = "${element(var.azs, count.index)}" cidr_block = "${element(var.public_subnets, count.index)}" map_public_ip_on_launch = true tags = "${merge(map("Name", format("%s-public-%s", var.name, element(var.azs, count.index))), var.tags)}" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 count = "${length(var.azs)}" availability_zone = "${element(var.azs, count.index)}" cidr_block = "${element(var.private_subnets, count.index)}" /* Private subnet */ 1 resource "aws_subnet" "private" { 2 3 4 vpc_id = "${aws_vpc.main.id}" 5 6 7 map_public_ip_on_launch = false 8 9 tags = "${merge(map("Name", format("%s-private-%s", var.name, element(var.azs, count.index))), var.tags)}" 10 } 11 12 /* Public subnet */ 13 resource "aws_subnet" "public" { 14 count = "${length(var.azs)}" 15 16 vpc_id = "${aws_vpc.main.id}" 17 availability_zone = "${element(var.azs, count.index)}" 18 cidr_block = "${element(var.public_subnets, count.index)}" 19 map_public_ip_on_launch = true 20 21 tags = "${merge(map("Name", format("%s-public-%s", var.name, element(var.azs, count.index))), var.tags)}" 22 azs = ["ap-northeast-1a", "ap-northeast-1c" public_subnets = ["10.0.0.0/24", "10.0.1.0/2 private_subnets = ["10.0.10.0/24", "10.0.11 1 2 3 Create Subnets
  12. #Public route tables resource "aws_route_table" "public" { vpc_id = "${aws_vpc.main.id}"

    route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.igw.id}" } tags = "${merge(map("Name", format("%s-public", var.name)), va } resource "aws_route_table_association" "public" { count = "${length(var.azs)}" subnet_id = "${element(aws_subnet.public.*.id, count.inde route_table_id = "${aws_route_table.public.id}" } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 subnet_id = "${element(aws_subnet.public.*.id, count.inde #Public route tables 1 resource "aws_route_table" "public" { 2 vpc_id = "${aws_vpc.main.id}" 3 4 route { 5 cidr_block = "0.0.0.0/0" 6 gateway_id = "${aws_internet_gateway.igw.id}" 7 } 8 9 tags = "${merge(map("Name", format("%s-public", var.name)), va 10 } 11 12 resource "aws_route_table_association" "public" { 13 count = "${length(var.azs)}" 14 15 16 route_table_id = "${aws_route_table.public.id}" 17 } 18 Create Route Tables
  13. $ terraform workspace new apne1 $ terraform apply -var-file=apne1.tfvars $

    terraform workspace new uses1 $ terraform apply -var-file=uses1.tfvars
  14. Terraform Remote Backend By default, .tfstate file stores on local

    disk Save .tfstate file to a remote backend Easier for state sharing and team work CI/CD
  15. S3 Remote Backend terraform { backend "s3" { region =

    "us-west-2" bucket = "david74-terraform-remote-state-s key = "terraform.tfstate" dynamodb_table = "terraform-state-lock-dynamo" encrypt = true workspace_key_prefix = "david74-demo" } } 1 2 3 4 5 6 7 8 9 10 region = "us-west-2" bucket = "david74-terraform-remote-state-s key = "terraform.tfstate" terraform { 1 backend "s3" { 2 3 4 5 dynamodb_table = "terraform-state-lock-dynamo" 6 encrypt = true 7 workspace_key_prefix = "david74-demo" 8 } 9 } 10 dynamodb_table = "terraform-state-lock-dynamo" terraform { 1 backend "s3" { 2 region = "us-west-2" 3 bucket = "david74-terraform-remote-state-s 4 key = "terraform.tfstate" 5 6 encrypt = true 7 workspace_key_prefix = "david74-demo" 8 } 9 } 10
  16. provider "aws" { region = "${var.requester_region}" profile = "${var.requester_aws_profile}" }

    module "vpc_peering" { source = "./vpc-peering" allow_remote_vpc_dns_resolution = "${var.allow_remote_vpc_dns_resolution}" # Requester Data requester_vpc_id = "${var.requester_vpc_id}" # Accepter Data accepter_aws_profile = "${var.accepter_aws_profile}" accepter_region = "${var.accepter_region}" accepter_vpc_id = "${var.accepter_vpc_id}" }
  17. resource "aws_instance" "temp" { /* ... */ } 1 2

    3 $ terraform import aws_instance.temp i-abcd1234
  18. Everything as Code, but how to test? Terratest is a

    Go library that makes it easier to write automated tests for your infrastructure code. gruntwork-io/terratest