SlideShare a Scribd company logo
1 of 53
Download to read offline
TERRAFORM
C++ :: 2000
PYTHON :: 2000...
PHP & JS :: 2004...
ACTIONSCRIPT :: 2006-09
GO :: 2016...
Lee Trout
DEVOPS @ YHAT
LEAD ENGINEER @ WRW
COFOUNDER @ EEX
CONSULTANT @ NATGEO
PYTHON @ WAPO
DEGREE IN COMPUTER ANIMATION
NO ONE IS SO TERRIBLY DECEIVED AS HE
WHO DOES NOT HIMSELF SUSPECT IT.
Soren Kierkegaard
I AM A TERRAFORM EXPERT. TRUST ME.
TERRAFORM IS COOL
Me
ACTUALLY I'M JUST A FAN
HELLO TERRAFORM
OVERVIEW
▸ What is Terraform
▸ Code Sample & Compare to Cloud Formation
▸ Create AWS Resources
▸ S3 Bucket
▸ EC2 Instance in VPC
▸ Compose with Digital Ocean Resources
▸ Create Droplet
▸ Grant S3 Access to Droplet
KEEP
CALMAND
AUTOMATE
ALL THE THINGS
HELLO TERRAFORM
DEVOPS @ YHAT
HELLO TERRAFORM
WHAT IS TERRAFORM
▸ Infrastructure as code
▸ A tool to manage virtual server life cycles (AWS, VMWare, etc)
▸ A tool to manage supporting services (DNS, Email)
▸ A tool to manage system servies (MySQL, PostgreSQL)
▸ Configuration files can be HCL or JSON
▸ Created by Hashicorp (Vagrant et al.)
▸ Written in Go
HELLO TERRAFORM
WHAT DOES TERRAFORM LOOK LIKE?
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"
}
HELLO TERRAFORM
TERRAFORM
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"
}
{
"Resources" : {
"my-cool-bucket" : {
"Type" : "AWS::S3::Bucket",
"Properties" : {
"AccessControl" : "PublicRead"
}
}
}
}
CLOUD FORMATION
HELLO TERRAFORM
TERRAFORM
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"
}
{
"Resources" : {
"my-cool-bucket" : {
"Type" : "AWS::S3::Bucket",
"Properties" : {
"AccessControl" : "PublicRead"
}
}
}
}
CLOUD FORMATION
The name to reference
within terraform files
The name of the bucket
Generated name:
stackname-my-cool-bucket-abc123id
LET'S TERRAFORM AN
S3 BUCKET
HELLO TERRAFORM
MAIN.TF
# Configure aws with a default region
provider "aws" {
region = "us-east-1"
}
# Create a demo s3 bucket
resource "aws_s3_bucket" "chadev_tf_demo" {
bucket = "chadev-tf-demo"
tags {
Name = "Terraform demo for ChaDev"
Environment = "Prod"
TF = "yes"
}
}
HELLO TERRAFORM
TERRAFORM PLAN
+ aws_s3_bucket.chadev_tf_demo
acl: "" => "private"
arn: "" => "<computed>"
bucket: "" => "chadev-tf-demo"
force_destroy: "" => "0"
hosted_zone_id: "" => "<computed>"
region: "" => "<computed>"
tags.#: "" => "3"
tags.Environment: "" => "Prod"
tags.Name: "" => "Terraform demo for ChaDev"
tags.TF: "" => "yes"
website_domain: "" => "<computed>"
website_endpoint: "" => "<computed>"
Plan: 1 to add, 0 to change, 0 to destroy.
HELLO TERRAFORM
TERRAFORM APPLY
aws_s3_bucket.chadev_tf_demo: Creating...
acl: "" => "private"
arn: "" => "<computed>"
bucket: "" => "chadev-tf-demo"
force_destroy: "" => "0"
hosted_zone_id: "" => "<computed>"
region: "" => "<computed>"
tags.#: "" => "3"
tags.Environment: "" => "Prod"
tags.Name: "" => "Terraform demo for ChaDev"
tags.TF: "" => "yes"
website_domain: "" => "<computed>"
website_endpoint: "" => "<computed>"
aws_s3_bucket.chadev_tf_demo: Creation complete
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
State path: terraform.tfstate
HELLO TERRAFORM
TERRAFORM STATE
"version": 1,
"serial": 1,
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {
"aws_s3_bucket.chadev_tf_demo": {
"type": "aws_s3_bucket",
"primary": {
"id": "chadev-tf-demo",
"attributes": {
"acl": "private",
"arn": "arn:aws:s3:::chadev-tf-demo",
"bucket": "chadev-tf-demo",
"cors_rule.#": "0",
"force_destroy": "false",
"hosted_zone_id": "Z3AQBSTGFYJSTF",
"id": "chadev-tf-demo",
"policy": "",
"region": "us-east-1",
"tags.#": "3",
"tags.Environment": "Prod",
"tags.Name": "Terraform demo for ChaDev",
"tags.TF": "yes",
"website.#": "0"
HELLO TERRAFORM
TERRAFORM STATE
▸ JSON
▸ Updated when Terraform runs
▸ Refreshed before an operation takes place
▸ Backwards compatible between TF versions
HELLO TERRAFORM
TANGENT: USING REMOTE STATE AS A DEPENDENCY
resource "terraform_remote_state" "core" {
backend = "s3"
config {
bucket = "a-tf-state-bucket"
key = "hosted/core.json"
region = "us-east-1"
}
}
resource "aws_route53_record" "my-awesome-subdomain.yhat.com" {
zone_id = "${terraform_remote_state.core.output.yhat-zone-id}"
name = "my-awesome-subdomain.yhat.com"
type = "A"
ttl = "60"
records = [
"${aws_eip.my-elastic-ip.public_ip}"
]
}
LET'S TERRAFORM A
SERVER
HELLO TERRAFORM
CREATING A SERVER
# Create a key pair for our servers
resource "aws_key_pair" "chadev_demo" {
key_name = "chadev_demo_key"
public_key = "ssh-rsa ..."
}
# Create a demo server
resource "aws_instance" "chadev_demo_server" {
# CentOS 7 (x86_64) with Updates HVM
ami = "ami-6d1c2007"
instance_type = "t2.medium"
key_name = "${aws_key_pair.chadev_demo.key_name}"
tags {
Name = "ChaDev Demo Server"
TF = "yes"
}
}
HELLO TERRAFORM
CREATING A SERVER
# Create a key pair for our servers
resource "aws_key_pair" "chadev_demo" {
key_name = "chadev_demo_key"
public_key = "ssh-rsa ..."
}
# Create a demo server
resource "aws_instance" "chadev_demo_server" {
# CentOS 7 (x86_64) with Updates HVM
ami = "ami-6d1c2007"
instance_type = "t2.medium"
key_name = "${aws_key_pair.chadev_demo.key_name}"
tags {
Name = "ChaDev Demo Server"
TF = "yes"
}
}
Get the name of the key by referencing the
output of the aws_key_pair.
Notice we're using the variable name we define.
HELLO TERRAFORM
TERRAFORM PLAN
+ aws_instance.chadev_demo_server
...
+ aws_key_pair.chadev_demo
...
Plan: 2 to add, 0 to change, 0 to destroy.
HELLO TERRAFORM
CREATING A SERVER
Error applying plan:
1 error(s) occurred:
* aws_instance.chadev_demo_server: Error launching source instance: VPCResourceNotSpecified: The
specified instance type can only be used in a VPC. A subnet ID or network interface ID is required
to carry out the request.
status code: 400, request id:
HELLO TERRAFORM
CREATING A SERVER
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
HELLO TERRAFORM
TERRAFORM PLAN
Plan: 1 to add, 0 to change, 0 to destroy.
LET'S TERRAFORM A
VPC
HELLO TERRAFORM
PARTS OF A VPC
▸ VPC definition (CIDR block)
▸ Subnets
▸ Internet gateway to allow our subnet to route to the internet
▸ Routing table to define how traffic is routed
▸ Main route table association to tell the vpc what route table to use by default
HELLO TERRAFORM
THE VPC
########
# VPC
########
resource "aws_vpc" "chadev_demo" {
cidr_block = "10.20.0.0/16"
enable_dns_hostnames = true
tags {
Name = "ChaDev Demo VPC"
Env = "Prod"
TF = "yes"
}
}
HELLO TERRAFORM
THE SUBNET
# Create a subnet for our instances
resource "aws_subnet" "chadev_demo_1a" {
vpc_id = "${aws_vpc.chadev_demo.id}"
cidr_block = "10.20.0.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags {
Name = "ChaDev Subnet AZ 1a"
Env = "Prod"
TF = "yes"
}
}
HELLO TERRAFORM
THE INTERNET GATEWAY
# Create an internet gateway so we can talk to the world
resource "aws_internet_gateway" "main" {
vpc_id = "${aws_vpc.chadev_demo.id}"
tags {
Name = "ChaDev VPC IGW"
Env = "Prod"
TF = "yes"
}
}
HELLO TERRAFORM
THE ROUTE TABLE
# Replace the default routing table with one explicitly defined here
resource "aws_route_table" "chadev_demo" {
vpc_id = "${aws_vpc.chadev_demo.id}"
# Send all traffic not matched by other routing rules to the internet
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.main.id}"
}
tags {
Name = "ChaDev Main RTB"
Env = "Prod"
TF = "yes"
}
}
HELLO TERRAFORM
THE ROUTE TABLE ASSOCIATION
# Assign our route table as the default route table
resource "aws_main_route_table_association" "main" {
vpc_id = "${aws_vpc.yhat-tf-demo.id}"
route_table_id = "${aws_route_table.yhat-tf-default.id}"
}
HELLO TERRAFORM
MAIN.TF
# Configure aws with a default region
provider "aws" {
region = "us-east-1"
}
# Create a demo s3 bucket
resource "aws_s3_bucket" "chadev_tf_demo" {
bucket = "chadev-tf-demo"
tags {
Name = "Terraform demo for ChaDev"
Environment = "Prod"
TF = "yes"
}
}
# Create a key pair for our servers
resource "aws_key_pair" "chadev_demo" {
key_name = "chadev_demo_key"
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGrwdl2hRk2JvzfoCgZFegX/qlGyaVZRxKJCleGwKRTjG/RPORj6lZnpGPRzKmhwcN78qXDmgGWY7cfaApuLC6lFZNissBeCsjDLFmsnyev+7EwZu3Bt05q7goFKtoaZ2oU2Ijv6TIQ0yj4LKEaBkHAuJgddwvFScoPDt35JB89NXybM9kXMWsiNB3vHLGmYs9qcC/CC7hlY9Y8oHqJRe+1MfbULp6YAgIM4iLD5/rKjUdnyhUSllipuDeECTVuwHK+9LWIAdT8+ZIJe1mVI/ZyDDKk2YDlWPvUrXmVfLMoXeVil7mEe88I9iZtRJMTmzY3oHOHowGkzJ8JRnLmWaF yhat@s-MacBook-Pro.local"
}
# Create a demo server
resource "aws_instance" "chadev_demo_server" {
# CentOS 7 (x86_64) with Updates HVM
ami = "ami-6d1c2007"
instance_type = "t2.micro"
key_name = "${aws_key_pair.chadev_demo.key_name}"
tags {
Name = "ChaDev Demo Server"
TF = "yes"
}
}
########
# VPC
########
resource "aws_vpc" "chadev_demo" {
cidr_block = "10.20.0.0/16"
enable_dns_hostnames = true
tags {
Name = "ChaDev Demo VPC"
Env = "Prod"
TF = "yes"
}
}
# Create a subnet for our instances
resource "aws_subnet" "chadev_demo_1a" {
vpc_id = "${aws_vpc.chadev_demo.id}"
cidr_block = "10.20.0.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags {
Name = "ChaDev Subnet AZ 1a"
Env = "Prod"
TF = "yes"
}
}
# Create an internet gateway so we can talk to the world
resource "aws_internet_gateway" "main" {
vpc_id = "${aws_vpc.chadev_demo.id}"
tags {
Name = "ChaDev VPC IGW"
Env = "Prod"
TF = "yes"
}
}
# Replace the default routing table with one explicitly defined here
resource "aws_route_table" "chadev_demo" {
vpc_id = "${aws_vpc.chadev_demo.id}"
# Send all traffic not matched by other routing rules to the internet
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.main.id}"
}
tags {
Name = "ChaDev Main RTB"
Env = "Prod"
TF = "yes"
}
}
# Assign our route table as the default route table
resource "aws_main_route_table_association" "main" {
vpc_id = "${aws_vpc.yhat-tf-demo.id}"
route_table_id = "${aws_route_table.yhat-tf-default.id}"
}
HELLO TERRAFORM
ORGANIZING TERRAFORM FILES
▸ Terraform looks for all files ending in .tf
▸ I personally prefix the files with the provider where applicable
▸ Let's put the vpc in aws.vpc.tf
▸ Let's put the rest in aws.demo.tf
HELLO TERRAFORM
TERRAFORM APPLY
Error applying plan:
1 error(s) occurred:
* aws_instance.chadev_demo_server: Error launching source instance: VPCResourceNotSpecified: The
specified instance type can only be used in a VPC. A subnet ID or network interface ID is required
to carry out the request.
status code: 400, request id:
HELLO TERRAFORM
SPECIFY SUBNET AND SECURITY GROUPS
vpc_security_group_ids = [
"${aws_security_group.chadev_demo.id}",
]
subnet_id = "${aws_subnet.chadev_demo_1a.id}"
LAUNCH & REVIEW
HELLO TERRAFORM
TERRAFORM WILL GRAPH DEPENDENCIES
▸ terraform graph | dot -Tpng > graph.png
HELLO TERRAFORM
TERRAFORM GRAPH | DOT -TPDF > GRAPH.PDF
aws_instance.chadev_demo_server
aws_key_pair.chadev_demo
aws_security_group.chadev_demo aws_subnet.chadev_demo_1a aws_internet_gateway.main
aws_vpc.chadev_demo
provider.aws
aws_main_route_table_association.main
aws_route_table.chadev_demo
aws_s3_bucket.chadev_tf_demo
COMPOSE
HELLO TERRAFORM
CREATE DIGITAL OCEAN SSH KEY & DROPLET
# Create a new SSH key
resource "digitalocean_ssh_key" "chadev_demo" {
name = "ChaDev Demo"
public_key = "${file("/Users/yhat/.ssh/id_rsa.pub")}"
}
# Create a new Web droplet in the nyc2 region
resource "digitalocean_droplet" "web" {
image = "ubuntu-14-04-x64"
name = "chadev-demo"
region = "nyc2"
size = "512mb"
}
HELLO TERRAFORM
CREATE DIGITAL OCEAN SSH KEY & DROPLET
# Create a new SSH key
resource "digitalocean_ssh_key" "chadev_demo" {
name = "ChaDev Demo"
public_key = "${file("/Users/yhat/.ssh/id_rsa.pub")}"
}
# Create a new Web droplet in the nyc2 region
resource "digitalocean_droplet" "web" {
image = "ubuntu-14-04-x64"
name = "chadev-demo"
region = "nyc2"
size = "512mb"
}
HELLO TERRAFORM
CREATE DIGITAL OCEAN SSH KEY & DROPLET
# Set the variable value in *.tfvars file
# or using -var="do_token=..." CLI option
variable "do_token" {}
# Configure the DigitalOcean Provider
provider "digitalocean" {
token = "${var.do_token}"
}
HELLO TERRAFORM
TERRAFORM.TFVARS
# Set the variable value in *.tfvars file
# or using -var="do_token=..." CLI option
variable "do_token" {}
# Configure the DigitalOcean Provider
provider "digitalocean" {
token = "${var.do_token}"
}
HELLO TERRAFORM
AWS.DEMO.TF
# Upload our html file to our bucket
resource "aws_s3_bucket_object" "object" {
bucket = "${aws_s3_bucket.chadev_tf_demo.id}"
key = "index.html"
source = "./index.html"
}
HELLO TERRAFORM
AWS.DEMO.TF
# Create a demo s3 bucket
resource "aws_s3_bucket" "chadev_tf_demo" {
bucket = "chadev-tf-demo-1"
website {
index_document = "index.html"
}
tags {
Name = "Terraform demo for ChaDev"
Environment = "Prod"
TF = "yes"
}
}
HELLO TERRAFORM
CURL THE ENDPOINT
$ curl chadev-tf-demo-1.s3.amazonaws.com/
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>EC6CC75BE6AA9040</
RequestId><HostId>iIBLHlo4RWzMFE4Sh3AVXv0qD2umr7G7qpI1GaMbCnFmmQv/ZP4KeoeIpWqwC8II</HostId></Error>
HELLO TERRAFORM
ALLOW ACCESS FROM DIGITAL OCEAN
policy = <<EOF
{
"Version": "2008-10-17",
"Id": "S3PolicyId1",
"Statement": [
{
"Sid": "IPAllow",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::chadev-tf-demo-1/*",
"arn:aws:s3:::chadev-tf-demo-1"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "${digitalocean_droplet.chadev_demo.ipv4_address}/32"
}
}
}
]
}
EOF
HELLO TERRAFORM
ALLOW ACCESS FROM DIGITAL OCEAN
"Condition": {
"IpAddress": {
"aws:SourceIp": "${digitalocean_droplet.chadev_demo.ipv4_address}/32"
}
}
HELLO TERRAFORM
aws_instance.chadev_demo_server
aws_key_pair.chadev_demo
aws_security_group.chadev_demo aws_subnet.chadev_demo_1a
provider.aws
aws_internet_gateway.main
aws_vpc.chadev_demo
aws_main_route_table_association.main
aws_route_table.chadev_demo
aws_s3_bucket.chadev_tf_demo
digitalocean_droplet.chadev_demo
aws_s3_bucket_object.object
digitalocean_ssh_key.chadev_demo
provider.digitalocean
HELLO TERRAFORM
aws_ecr_repository.boxr-ops2
provider.aws
aws_ecr_repository.tasty-aptly aws_ecr_repository.tasty-yummy
aws_ecr_repository_policy.boxr-ops2aws_ecr_repository_policy.tasty-aptly aws_ecr_repository_policy.tasty-yummy aws_ecs_cluster.tasty
aws_ecs_task_definition.tasty
aws_ecs_task_definition.tasty-aptly
aws_iam_access_key.tasty-ecs-container
aws_ecs_task_definition.tasty-yummy
aws_eip.metrics-server-eip
aws_instance.metrics-server
aws_iam_user.tasty-ecs-container
aws_iam_instance_profile.metrics-server
aws_iam_role.yhat-build
aws_iam_instance_profile.tasty-ecs-profile
aws_iam_role.tasty-ecs aws_iam_policy.tasty-ecs aws_iam_policy.yhat-build-access
aws_iam_policy_attachment.tasty-ecs-attach aws_iam_policy_attachment.yhat-build-access-attach
aws_iam_role.lambda-tasty
aws_iam_role_policy.tasty-lambdaaws_iam_user_policy.tasty-ecs-user-policy
aws_instance.tasty-container-server
aws_security_group.tasty-container-server aws_subnet.yhat-tf-demo-1a
aws_route53_delegation_set.godaddy
aws_route53_record.20d99ed1-sciencecluster-yhat-com
aws_route53_zone.yhat-com
aws_route53_record.20d99ed1-scienceops-yhat-com aws_route53_record.blog-yhat-com aws_route53_record.c-yhat-com aws_route53_record.conda-yhat-com aws_route53_record.email-yhat-com
aws_route53_record.et-s-yhat-com
aws_route53_record.help-yhat-com aws_route53_record.mx-yhat-com aws_route53_record.rodeo-updates-yhat-com aws_route53_record.rodeo-yhat-com aws_route53_record.slack-yhat-com aws_route53_record.txt2-yhat-com aws_route53_record.www-yhat-com aws_route53_record.yhat-com
aws_s3_bucket.yhat-build aws_s3_bucket.yhat-security-review aws_s3_bucket.yhat-tasty aws_s3_bucket.yhat-tasty-ppa aws_s3_bucket.yhat-tasty-yum
aws_security_group.metrics-server
aws_vpc.yhat-tf-demo
aws_internet_gateway.main
provider.aws
aws_main_route_table_association.main
aws_route_table.yhat-tf-default
provider.aws
THANK YOU
THERE'S SO MUCH MORE BUT WE'RE OUT OF TIME

More Related Content

What's hot

What's hot (20)

Effective terraform
Effective terraformEffective terraform
Effective terraform
 
Terraform on Azure
Terraform on AzureTerraform on Azure
Terraform on Azure
 
Terraform modules restructured
Terraform modules restructuredTerraform modules restructured
Terraform modules restructured
 
Comprehensive Terraform Training
Comprehensive Terraform TrainingComprehensive Terraform Training
Comprehensive Terraform Training
 
An introduction to terraform
An introduction to terraformAn introduction to terraform
An introduction to terraform
 
Terraform introduction
Terraform introductionTerraform introduction
Terraform introduction
 
Terraform
TerraformTerraform
Terraform
 
Terraform Basics
Terraform BasicsTerraform Basics
Terraform Basics
 
Terraform
TerraformTerraform
Terraform
 
Terraform modules and best-practices - September 2018
Terraform modules and best-practices - September 2018Terraform modules and best-practices - September 2018
Terraform modules and best-practices - September 2018
 
Infrastructure-as-Code (IaC) using Terraform
Infrastructure-as-Code (IaC) using TerraformInfrastructure-as-Code (IaC) using Terraform
Infrastructure-as-Code (IaC) using Terraform
 
Introduction To Terraform
Introduction To TerraformIntroduction To Terraform
Introduction To Terraform
 
Final terraform
Final terraformFinal terraform
Final terraform
 
Microsoft Azure IaaS and Terraform
Microsoft Azure IaaS and TerraformMicrosoft Azure IaaS and Terraform
Microsoft Azure IaaS and Terraform
 
infrastructure as code
infrastructure as codeinfrastructure as code
infrastructure as code
 
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
Infrastructure-as-Code (IaC) Using Terraform (Advanced Edition)
 
Configuration management II - Terraform
Configuration management II - TerraformConfiguration management II - Terraform
Configuration management II - Terraform
 
Terraform
TerraformTerraform
Terraform
 
Terraform
TerraformTerraform
Terraform
 
Terraform Introduction
Terraform IntroductionTerraform Introduction
Terraform Introduction
 

Similar to Terraform: An Overview & Introduction

Puppetpreso
PuppetpresoPuppetpreso
Puppetpreso
ke4qqq
 

Similar to Terraform: An Overview & Introduction (20)

OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...
OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...
OSDC 2015: Mitchell Hashimoto | Automating the Modern Datacenter, Development...
 
Fullstack conf 2017 - Basic dev pipeline end-to-end
Fullstack conf 2017 - Basic dev pipeline end-to-endFullstack conf 2017 - Basic dev pipeline end-to-end
Fullstack conf 2017 - Basic dev pipeline end-to-end
 
Przemysław Iwanek - ABC AWS, budowanie infrastruktury przy pomocy Terraform
Przemysław Iwanek - ABC AWS, budowanie infrastruktury przy pomocy TerraformPrzemysław Iwanek - ABC AWS, budowanie infrastruktury przy pomocy Terraform
Przemysław Iwanek - ABC AWS, budowanie infrastruktury przy pomocy Terraform
 
TIAD : Automating the modern datacenter
TIAD : Automating the modern datacenterTIAD : Automating the modern datacenter
TIAD : Automating the modern datacenter
 
Meetup bangalore aug31st2019
Meetup bangalore aug31st2019Meetup bangalore aug31st2019
Meetup bangalore aug31st2019
 
London HUG 12/4
London HUG 12/4London HUG 12/4
London HUG 12/4
 
Atmosphere Conference 2015: Taming the Modern Datacenter
Atmosphere Conference 2015: Taming the Modern DatacenterAtmosphere Conference 2015: Taming the Modern Datacenter
Atmosphere Conference 2015: Taming the Modern Datacenter
 
Amazon Web Services for PHP Developers
Amazon Web Services for PHP DevelopersAmazon Web Services for PHP Developers
Amazon Web Services for PHP Developers
 
Aprovisionamiento multi-proveedor con Terraform - Plain Concepts DevOps day
Aprovisionamiento multi-proveedor con Terraform  - Plain Concepts DevOps dayAprovisionamiento multi-proveedor con Terraform  - Plain Concepts DevOps day
Aprovisionamiento multi-proveedor con Terraform - Plain Concepts DevOps day
 
Terraform at Scale
Terraform at ScaleTerraform at Scale
Terraform at Scale
 
Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
 Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data... Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
Big Data Web applications for Interactive Hadoop by ENRICO BERTI at Big Data...
 
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
How we used ruby to build locaweb's cloud (http://presentations.pothix.com/ru...
 
An intro to Docker, Terraform, and Amazon ECS
An intro to Docker, Terraform, and Amazon ECSAn intro to Docker, Terraform, and Amazon ECS
An intro to Docker, Terraform, and Amazon ECS
 
Micro app-framework - NodeLive Boston
Micro app-framework - NodeLive BostonMicro app-framework - NodeLive Boston
Micro app-framework - NodeLive Boston
 
Micro app-framework
Micro app-frameworkMicro app-framework
Micro app-framework
 
Infrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and OpsInfrastructure-as-code: bridging the gap between Devs and Ops
Infrastructure-as-code: bridging the gap between Devs and Ops
 
Refactoring terraform
Refactoring terraformRefactoring terraform
Refactoring terraform
 
Puppetpreso
PuppetpresoPuppetpreso
Puppetpreso
 
Reusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modulesReusable, composable, battle-tested Terraform modules
Reusable, composable, battle-tested Terraform modules
 
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiMonitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
 

Recently uploaded

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Recently uploaded (20)

Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 

Terraform: An Overview & Introduction

  • 2. C++ :: 2000 PYTHON :: 2000... PHP & JS :: 2004... ACTIONSCRIPT :: 2006-09 GO :: 2016... Lee Trout DEVOPS @ YHAT LEAD ENGINEER @ WRW COFOUNDER @ EEX CONSULTANT @ NATGEO PYTHON @ WAPO DEGREE IN COMPUTER ANIMATION
  • 3. NO ONE IS SO TERRIBLY DECEIVED AS HE WHO DOES NOT HIMSELF SUSPECT IT. Soren Kierkegaard I AM A TERRAFORM EXPERT. TRUST ME.
  • 5. HELLO TERRAFORM OVERVIEW ▸ What is Terraform ▸ Code Sample & Compare to Cloud Formation ▸ Create AWS Resources ▸ S3 Bucket ▸ EC2 Instance in VPC ▸ Compose with Digital Ocean Resources ▸ Create Droplet ▸ Grant S3 Access to Droplet KEEP CALMAND AUTOMATE ALL THE THINGS
  • 6.
  • 8. HELLO TERRAFORM WHAT IS TERRAFORM ▸ Infrastructure as code ▸ A tool to manage virtual server life cycles (AWS, VMWare, etc) ▸ A tool to manage supporting services (DNS, Email) ▸ A tool to manage system servies (MySQL, PostgreSQL) ▸ Configuration files can be HCL or JSON ▸ Created by Hashicorp (Vagrant et al.) ▸ Written in Go
  • 9. HELLO TERRAFORM WHAT DOES TERRAFORM LOOK LIKE? 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" }
  • 10. HELLO TERRAFORM TERRAFORM 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" } { "Resources" : { "my-cool-bucket" : { "Type" : "AWS::S3::Bucket", "Properties" : { "AccessControl" : "PublicRead" } } } } CLOUD FORMATION
  • 11. HELLO TERRAFORM TERRAFORM 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" } { "Resources" : { "my-cool-bucket" : { "Type" : "AWS::S3::Bucket", "Properties" : { "AccessControl" : "PublicRead" } } } } CLOUD FORMATION The name to reference within terraform files The name of the bucket Generated name: stackname-my-cool-bucket-abc123id
  • 13. HELLO TERRAFORM MAIN.TF # Configure aws with a default region provider "aws" { region = "us-east-1" } # Create a demo s3 bucket resource "aws_s3_bucket" "chadev_tf_demo" { bucket = "chadev-tf-demo" tags { Name = "Terraform demo for ChaDev" Environment = "Prod" TF = "yes" } }
  • 14. HELLO TERRAFORM TERRAFORM PLAN + aws_s3_bucket.chadev_tf_demo acl: "" => "private" arn: "" => "<computed>" bucket: "" => "chadev-tf-demo" force_destroy: "" => "0" hosted_zone_id: "" => "<computed>" region: "" => "<computed>" tags.#: "" => "3" tags.Environment: "" => "Prod" tags.Name: "" => "Terraform demo for ChaDev" tags.TF: "" => "yes" website_domain: "" => "<computed>" website_endpoint: "" => "<computed>" Plan: 1 to add, 0 to change, 0 to destroy.
  • 15. HELLO TERRAFORM TERRAFORM APPLY aws_s3_bucket.chadev_tf_demo: Creating... acl: "" => "private" arn: "" => "<computed>" bucket: "" => "chadev-tf-demo" force_destroy: "" => "0" hosted_zone_id: "" => "<computed>" region: "" => "<computed>" tags.#: "" => "3" tags.Environment: "" => "Prod" tags.Name: "" => "Terraform demo for ChaDev" tags.TF: "" => "yes" website_domain: "" => "<computed>" website_endpoint: "" => "<computed>" aws_s3_bucket.chadev_tf_demo: Creation complete Apply complete! Resources: 1 added, 0 changed, 0 destroyed. State path: terraform.tfstate
  • 16. HELLO TERRAFORM TERRAFORM STATE "version": 1, "serial": 1, "modules": [ { "path": [ "root" ], "outputs": {}, "resources": { "aws_s3_bucket.chadev_tf_demo": { "type": "aws_s3_bucket", "primary": { "id": "chadev-tf-demo", "attributes": { "acl": "private", "arn": "arn:aws:s3:::chadev-tf-demo", "bucket": "chadev-tf-demo", "cors_rule.#": "0", "force_destroy": "false", "hosted_zone_id": "Z3AQBSTGFYJSTF", "id": "chadev-tf-demo", "policy": "", "region": "us-east-1", "tags.#": "3", "tags.Environment": "Prod", "tags.Name": "Terraform demo for ChaDev", "tags.TF": "yes", "website.#": "0"
  • 17. HELLO TERRAFORM TERRAFORM STATE ▸ JSON ▸ Updated when Terraform runs ▸ Refreshed before an operation takes place ▸ Backwards compatible between TF versions
  • 18. HELLO TERRAFORM TANGENT: USING REMOTE STATE AS A DEPENDENCY resource "terraform_remote_state" "core" { backend = "s3" config { bucket = "a-tf-state-bucket" key = "hosted/core.json" region = "us-east-1" } } resource "aws_route53_record" "my-awesome-subdomain.yhat.com" { zone_id = "${terraform_remote_state.core.output.yhat-zone-id}" name = "my-awesome-subdomain.yhat.com" type = "A" ttl = "60" records = [ "${aws_eip.my-elastic-ip.public_ip}" ] }
  • 20. HELLO TERRAFORM CREATING A SERVER # Create a key pair for our servers resource "aws_key_pair" "chadev_demo" { key_name = "chadev_demo_key" public_key = "ssh-rsa ..." } # Create a demo server resource "aws_instance" "chadev_demo_server" { # CentOS 7 (x86_64) with Updates HVM ami = "ami-6d1c2007" instance_type = "t2.medium" key_name = "${aws_key_pair.chadev_demo.key_name}" tags { Name = "ChaDev Demo Server" TF = "yes" } }
  • 21. HELLO TERRAFORM CREATING A SERVER # Create a key pair for our servers resource "aws_key_pair" "chadev_demo" { key_name = "chadev_demo_key" public_key = "ssh-rsa ..." } # Create a demo server resource "aws_instance" "chadev_demo_server" { # CentOS 7 (x86_64) with Updates HVM ami = "ami-6d1c2007" instance_type = "t2.medium" key_name = "${aws_key_pair.chadev_demo.key_name}" tags { Name = "ChaDev Demo Server" TF = "yes" } } Get the name of the key by referencing the output of the aws_key_pair. Notice we're using the variable name we define.
  • 22. HELLO TERRAFORM TERRAFORM PLAN + aws_instance.chadev_demo_server ... + aws_key_pair.chadev_demo ... Plan: 2 to add, 0 to change, 0 to destroy.
  • 23. HELLO TERRAFORM CREATING A SERVER Error applying plan: 1 error(s) occurred: * aws_instance.chadev_demo_server: Error launching source instance: VPCResourceNotSpecified: The specified instance type can only be used in a VPC. A subnet ID or network interface ID is required to carry out the request. status code: 400, request id:
  • 24. HELLO TERRAFORM CREATING A SERVER Terraform does not automatically rollback in the face of errors. Instead, your Terraform state file has been partially updated with any resources that successfully completed. Please address the error above and apply again to incrementally change your infrastructure.
  • 25. HELLO TERRAFORM TERRAFORM PLAN Plan: 1 to add, 0 to change, 0 to destroy.
  • 27. HELLO TERRAFORM PARTS OF A VPC ▸ VPC definition (CIDR block) ▸ Subnets ▸ Internet gateway to allow our subnet to route to the internet ▸ Routing table to define how traffic is routed ▸ Main route table association to tell the vpc what route table to use by default
  • 28. HELLO TERRAFORM THE VPC ######## # VPC ######## resource "aws_vpc" "chadev_demo" { cidr_block = "10.20.0.0/16" enable_dns_hostnames = true tags { Name = "ChaDev Demo VPC" Env = "Prod" TF = "yes" } }
  • 29. HELLO TERRAFORM THE SUBNET # Create a subnet for our instances resource "aws_subnet" "chadev_demo_1a" { vpc_id = "${aws_vpc.chadev_demo.id}" cidr_block = "10.20.0.0/24" availability_zone = "us-east-1a" map_public_ip_on_launch = true tags { Name = "ChaDev Subnet AZ 1a" Env = "Prod" TF = "yes" } }
  • 30. HELLO TERRAFORM THE INTERNET GATEWAY # Create an internet gateway so we can talk to the world resource "aws_internet_gateway" "main" { vpc_id = "${aws_vpc.chadev_demo.id}" tags { Name = "ChaDev VPC IGW" Env = "Prod" TF = "yes" } }
  • 31. HELLO TERRAFORM THE ROUTE TABLE # Replace the default routing table with one explicitly defined here resource "aws_route_table" "chadev_demo" { vpc_id = "${aws_vpc.chadev_demo.id}" # Send all traffic not matched by other routing rules to the internet route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.main.id}" } tags { Name = "ChaDev Main RTB" Env = "Prod" TF = "yes" } }
  • 32. HELLO TERRAFORM THE ROUTE TABLE ASSOCIATION # Assign our route table as the default route table resource "aws_main_route_table_association" "main" { vpc_id = "${aws_vpc.yhat-tf-demo.id}" route_table_id = "${aws_route_table.yhat-tf-default.id}" }
  • 33. HELLO TERRAFORM MAIN.TF # Configure aws with a default region provider "aws" { region = "us-east-1" } # Create a demo s3 bucket resource "aws_s3_bucket" "chadev_tf_demo" { bucket = "chadev-tf-demo" tags { Name = "Terraform demo for ChaDev" Environment = "Prod" TF = "yes" } } # Create a key pair for our servers resource "aws_key_pair" "chadev_demo" { key_name = "chadev_demo_key" public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGrwdl2hRk2JvzfoCgZFegX/qlGyaVZRxKJCleGwKRTjG/RPORj6lZnpGPRzKmhwcN78qXDmgGWY7cfaApuLC6lFZNissBeCsjDLFmsnyev+7EwZu3Bt05q7goFKtoaZ2oU2Ijv6TIQ0yj4LKEaBkHAuJgddwvFScoPDt35JB89NXybM9kXMWsiNB3vHLGmYs9qcC/CC7hlY9Y8oHqJRe+1MfbULp6YAgIM4iLD5/rKjUdnyhUSllipuDeECTVuwHK+9LWIAdT8+ZIJe1mVI/ZyDDKk2YDlWPvUrXmVfLMoXeVil7mEe88I9iZtRJMTmzY3oHOHowGkzJ8JRnLmWaF yhat@s-MacBook-Pro.local" } # Create a demo server resource "aws_instance" "chadev_demo_server" { # CentOS 7 (x86_64) with Updates HVM ami = "ami-6d1c2007" instance_type = "t2.micro" key_name = "${aws_key_pair.chadev_demo.key_name}" tags { Name = "ChaDev Demo Server" TF = "yes" } } ######## # VPC ######## resource "aws_vpc" "chadev_demo" { cidr_block = "10.20.0.0/16" enable_dns_hostnames = true tags { Name = "ChaDev Demo VPC" Env = "Prod" TF = "yes" } } # Create a subnet for our instances resource "aws_subnet" "chadev_demo_1a" { vpc_id = "${aws_vpc.chadev_demo.id}" cidr_block = "10.20.0.0/24" availability_zone = "us-east-1a" map_public_ip_on_launch = true tags { Name = "ChaDev Subnet AZ 1a" Env = "Prod" TF = "yes" } } # Create an internet gateway so we can talk to the world resource "aws_internet_gateway" "main" { vpc_id = "${aws_vpc.chadev_demo.id}" tags { Name = "ChaDev VPC IGW" Env = "Prod" TF = "yes" } } # Replace the default routing table with one explicitly defined here resource "aws_route_table" "chadev_demo" { vpc_id = "${aws_vpc.chadev_demo.id}" # Send all traffic not matched by other routing rules to the internet route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.main.id}" } tags { Name = "ChaDev Main RTB" Env = "Prod" TF = "yes" } } # Assign our route table as the default route table resource "aws_main_route_table_association" "main" { vpc_id = "${aws_vpc.yhat-tf-demo.id}" route_table_id = "${aws_route_table.yhat-tf-default.id}" }
  • 34. HELLO TERRAFORM ORGANIZING TERRAFORM FILES ▸ Terraform looks for all files ending in .tf ▸ I personally prefix the files with the provider where applicable ▸ Let's put the vpc in aws.vpc.tf ▸ Let's put the rest in aws.demo.tf
  • 35. HELLO TERRAFORM TERRAFORM APPLY Error applying plan: 1 error(s) occurred: * aws_instance.chadev_demo_server: Error launching source instance: VPCResourceNotSpecified: The specified instance type can only be used in a VPC. A subnet ID or network interface ID is required to carry out the request. status code: 400, request id:
  • 36. HELLO TERRAFORM SPECIFY SUBNET AND SECURITY GROUPS vpc_security_group_ids = [ "${aws_security_group.chadev_demo.id}", ] subnet_id = "${aws_subnet.chadev_demo_1a.id}"
  • 38. HELLO TERRAFORM TERRAFORM WILL GRAPH DEPENDENCIES ▸ terraform graph | dot -Tpng > graph.png
  • 39. HELLO TERRAFORM TERRAFORM GRAPH | DOT -TPDF > GRAPH.PDF aws_instance.chadev_demo_server aws_key_pair.chadev_demo aws_security_group.chadev_demo aws_subnet.chadev_demo_1a aws_internet_gateway.main aws_vpc.chadev_demo provider.aws aws_main_route_table_association.main aws_route_table.chadev_demo aws_s3_bucket.chadev_tf_demo
  • 41.
  • 42. HELLO TERRAFORM CREATE DIGITAL OCEAN SSH KEY & DROPLET # Create a new SSH key resource "digitalocean_ssh_key" "chadev_demo" { name = "ChaDev Demo" public_key = "${file("/Users/yhat/.ssh/id_rsa.pub")}" } # Create a new Web droplet in the nyc2 region resource "digitalocean_droplet" "web" { image = "ubuntu-14-04-x64" name = "chadev-demo" region = "nyc2" size = "512mb" }
  • 43. HELLO TERRAFORM CREATE DIGITAL OCEAN SSH KEY & DROPLET # Create a new SSH key resource "digitalocean_ssh_key" "chadev_demo" { name = "ChaDev Demo" public_key = "${file("/Users/yhat/.ssh/id_rsa.pub")}" } # Create a new Web droplet in the nyc2 region resource "digitalocean_droplet" "web" { image = "ubuntu-14-04-x64" name = "chadev-demo" region = "nyc2" size = "512mb" }
  • 44. HELLO TERRAFORM CREATE DIGITAL OCEAN SSH KEY & DROPLET # Set the variable value in *.tfvars file # or using -var="do_token=..." CLI option variable "do_token" {} # Configure the DigitalOcean Provider provider "digitalocean" { token = "${var.do_token}" }
  • 45. HELLO TERRAFORM TERRAFORM.TFVARS # Set the variable value in *.tfvars file # or using -var="do_token=..." CLI option variable "do_token" {} # Configure the DigitalOcean Provider provider "digitalocean" { token = "${var.do_token}" }
  • 46. HELLO TERRAFORM AWS.DEMO.TF # Upload our html file to our bucket resource "aws_s3_bucket_object" "object" { bucket = "${aws_s3_bucket.chadev_tf_demo.id}" key = "index.html" source = "./index.html" }
  • 47. HELLO TERRAFORM AWS.DEMO.TF # Create a demo s3 bucket resource "aws_s3_bucket" "chadev_tf_demo" { bucket = "chadev-tf-demo-1" website { index_document = "index.html" } tags { Name = "Terraform demo for ChaDev" Environment = "Prod" TF = "yes" } }
  • 48. HELLO TERRAFORM CURL THE ENDPOINT $ curl chadev-tf-demo-1.s3.amazonaws.com/ <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>EC6CC75BE6AA9040</ RequestId><HostId>iIBLHlo4RWzMFE4Sh3AVXv0qD2umr7G7qpI1GaMbCnFmmQv/ZP4KeoeIpWqwC8II</HostId></Error>
  • 49. HELLO TERRAFORM ALLOW ACCESS FROM DIGITAL OCEAN policy = <<EOF { "Version": "2008-10-17", "Id": "S3PolicyId1", "Statement": [ { "Sid": "IPAllow", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::chadev-tf-demo-1/*", "arn:aws:s3:::chadev-tf-demo-1" ], "Condition": { "IpAddress": { "aws:SourceIp": "${digitalocean_droplet.chadev_demo.ipv4_address}/32" } } } ] } EOF
  • 50. HELLO TERRAFORM ALLOW ACCESS FROM DIGITAL OCEAN "Condition": { "IpAddress": { "aws:SourceIp": "${digitalocean_droplet.chadev_demo.ipv4_address}/32" } }
  • 52. HELLO TERRAFORM aws_ecr_repository.boxr-ops2 provider.aws aws_ecr_repository.tasty-aptly aws_ecr_repository.tasty-yummy aws_ecr_repository_policy.boxr-ops2aws_ecr_repository_policy.tasty-aptly aws_ecr_repository_policy.tasty-yummy aws_ecs_cluster.tasty aws_ecs_task_definition.tasty aws_ecs_task_definition.tasty-aptly aws_iam_access_key.tasty-ecs-container aws_ecs_task_definition.tasty-yummy aws_eip.metrics-server-eip aws_instance.metrics-server aws_iam_user.tasty-ecs-container aws_iam_instance_profile.metrics-server aws_iam_role.yhat-build aws_iam_instance_profile.tasty-ecs-profile aws_iam_role.tasty-ecs aws_iam_policy.tasty-ecs aws_iam_policy.yhat-build-access aws_iam_policy_attachment.tasty-ecs-attach aws_iam_policy_attachment.yhat-build-access-attach aws_iam_role.lambda-tasty aws_iam_role_policy.tasty-lambdaaws_iam_user_policy.tasty-ecs-user-policy aws_instance.tasty-container-server aws_security_group.tasty-container-server aws_subnet.yhat-tf-demo-1a aws_route53_delegation_set.godaddy aws_route53_record.20d99ed1-sciencecluster-yhat-com aws_route53_zone.yhat-com aws_route53_record.20d99ed1-scienceops-yhat-com aws_route53_record.blog-yhat-com aws_route53_record.c-yhat-com aws_route53_record.conda-yhat-com aws_route53_record.email-yhat-com aws_route53_record.et-s-yhat-com aws_route53_record.help-yhat-com aws_route53_record.mx-yhat-com aws_route53_record.rodeo-updates-yhat-com aws_route53_record.rodeo-yhat-com aws_route53_record.slack-yhat-com aws_route53_record.txt2-yhat-com aws_route53_record.www-yhat-com aws_route53_record.yhat-com aws_s3_bucket.yhat-build aws_s3_bucket.yhat-security-review aws_s3_bucket.yhat-tasty aws_s3_bucket.yhat-tasty-ppa aws_s3_bucket.yhat-tasty-yum aws_security_group.metrics-server aws_vpc.yhat-tf-demo aws_internet_gateway.main provider.aws aws_main_route_table_association.main aws_route_table.yhat-tf-default provider.aws
  • 53. THANK YOU THERE'S SO MUCH MORE BUT WE'RE OUT OF TIME