Share
Embed
Infrastructure as Code @ DevOpsDay Warsaw 2019
Terraform enables you to safely and predictably create, change, and improve production infrastructure. It is an open source tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned. Terraform has emerged as a key player in the DevOps world for defining, launching, and managing infrastructure as code (IAC) across a variety of cloud and virtualization platforms, including AWS, Google Cloud, and Azure. In this talk I'll show you how to get up and running with Terraform using IaaS (e.g. AWS, DigitalOcean) or SaaS providers (e.g. CloudFlare, GitHub).
Sebastian Grodzicki
November 25, 2019
Transcript
72 slides
-
$ whoami Sebastian Grodzicki • Engineering Manager at • ex-CTO
at SHOWROOM & GoldenLine • #LifeAtElastic @sebgrodzicki -
module "stack" { source = "github.com/segmentio/stack" environment = "demo" key_name
= "sgrodzicki" name = "WDI" } main.tf -
Data center evolution DC VM VM VM VM VM VM
VM VM VM VM VM VM -
Data center evolution DC VM C C C C C
C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C VM C C C C C C -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR DC OPS -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR SYSADMIN DC OPS -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR DC OPS SYSADMIN DC OPS -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR DC OPS SYSADMIN DC OPS WEEKS -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR DC OPS SYSADMIN DC OPS WEEKS DAYS -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR DC OPS SYSADMIN DC OPS WEEKS DAYS DAYS -
Data center evolution ACQUIRE
DESTROY PROVISION UPDATE VENDOR DC OPS SYSADMIN DC OPS WEEKS DAYS DAYS DAYS -
Cloud computing ACQUIRE
DESTROY PROVISION UPDATE SECONDS SECONDS SECONDS SECONDS -
resource "digitalocean_droplet" "demo" { image = "ubuntu-18-10-x64" name = "WDI"
region = "fra1" size = "s-1vcpu-1gb" } resource "cloudflare_record" "demo" { domain = "grodzicki.pl" name = "wdi" type = "A" value = "${digitalocean_droplet.demo.ipv4_address}" } main.tf -
$ terraform init Initializing provider plugins... - Checking for
available provider plugins on https:// releases.hashicorp.com... - Downloading plugin for provider "cloudflare" (1.12.0)... - Downloading plugin for provider "digitalocean" (1.1.0)... Terraform has been successfully initialized! Terminal -
$ terraform plan Terraform will perform the following actions:
+ cloudflare_record.demo id: <computed> created_on: <computed> domain: "grodzicki.pl" hostname: <computed> metadata.%: <computed> modified_on: <computed> name: "wdi" proxiable: <computed> proxied: "false" ttl: <computed> type: "A" value: "${digitalocean_droplet.demo.ipv4_address}" zone_id: <computed> + digitalocean_droplet.demo id: <computed> backups: "false" disk: <computed> image: "ubuntu-18-10-x64" ipv4_address: <computed> ipv4_address_private: <computed> ipv6: "false" ipv6_address: <computed> ipv6_address_private: <computed> locked: <computed> memory: <computed> monitoring: "false" name: "WDI" price_hourly: <computed> price_monthly: <computed> private_networking: "false" region: "fra1" resize_disk: "true" size: "s-1vcpu-1gb" status: <computed> vcpus: <computed> volume_ids.#: <computed> Plan: 2 to add, 0 to change, 0 to destroy. Terminal -
$ terraform apply digitalocean_droplet.demo: Creating... backups: "" => "false"
disk: "" => "<computed>" image: "" => "ubuntu-18-10-x64" ipv4_address: "" => "<computed>" ipv4_address_private: "" => "<computed>" ipv6: "" => "false" ipv6_address: "" => "<computed>" ipv6_address_private: "" => "<computed>" locked: "" => "<computed>" memory: "" => "<computed>" monitoring: "" => "false" name: "" => "WDI" price_hourly: "" => "<computed>" price_monthly: "" => "<computed>" private_networking: "" => "false" region: "" => "fra1" resize_disk: "" => "true" size: "" => "s-1vcpu-1gb" status: "" => "<computed>" vcpus: "" => "<computed>" volume_ids.#: "" => "<computed>" digitalocean_droplet.demo: Creation complete after 36s (ID: 137339900) cloudflare_record.demo: Creating... created_on: "" => "<computed>" domain: "" => "grodzicki.pl" hostname: "" => "<computed>" metadata.%: "" => "<computed>" modified_on: "" => "<computed>" name: "" => "wdi" proxiable: "" => "<computed>" proxied: "" => "false" ttl: "" => "<computed>" type: "" => "A" value: "" => "134.209.240.227" zone_id: "" => "<computed>" cloudflare_record.demo: Creation complete after 2s (ID: 02e2198170dba247e7177e7b59a3aa16) Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Terminal -
$ terraform destroy digitalocean_droplet.demo: Refreshing state... (ID: 137339900) cloudflare_record.demo:
Refreshing state... (ID: 02e2198170dba247e7177e7b59a3aa16) cloudflare_record.demo: Destroying... (ID: 02e2198170dba247e7177e7b59a3aa16) cloudflare_record.demo: Destruction complete after 1s digitalocean_droplet.demo: Destroying... (ID: 137339900) digitalocean_droplet.demo: Still destroying... (ID: 137339900, 10s elapsed) digitalocean_droplet.demo: Destruction complete after 12s Destroy complete! Resources: 2 destroyed. Terminal -
resource "digitalocean_droplet" "demo" { image = "ubuntu-18-10-x64" name = "WDI"
region = "fra1" - size = "s-1vcpu-1gb" + size = "s-1vcpu-2gb" } resource "cloudflare_record" "demo" { domain = "grodzicki.pl" name = "wdi" type = "A" value = "${digitalocean_droplet.demo.ipv4_address}" } main.tf -
$ terraform plan Resource actions are indicated with the
following symbols: ~ update in-place Terraform will perform the following actions: ~ digitalocean_droplet.demo size: "s-1vcpu-1gb" => "s-1vcpu-2gb" Plan: 0 to add, 1 to change, 0 to destroy. Terminal -
$ terraform apply digitalocean_droplet.demo: Refreshing state... (ID: 137341062) cloudflare_record.demo:
Refreshing state... (ID: d1ad18b09494e7c865620379ba84fb11) digitalocean_droplet.demo: Modifying... (ID: 137341062) size: "s-1vcpu-1gb" => "s-1vcpu-2gb" digitalocean_droplet.demo: Modifications complete after 1m9s (ID: 137341062) Apply complete! Resources: 0 added, 1 changed, 0 destroyed. Terminal -
resource "digitalocean_droplet" "demo" { - image = "ubuntu-18-10-x64" + image
= "debian-9-x64" name = "WDI" region = "fra1" size = "s-1vcpu-2gb" } resource "cloudflare_record" "demo" { domain = "grodzicki.pl" name = "wdi" type = "A" value = "${digitalocean_droplet.demo.ipv4_address}" } main.tf -
$ terraform plan Resource actions are indicated with the
following symbols: ~ update in-place -/+ destroy and then create replacement Terraform will perform the following actions: ~ cloudflare_record.demo value: "134.209.226.251" => "${digitalocean_droplet.demo.ipv4_address}" -/+ digitalocean_droplet.demo (new resource required) id: "137341968" => <computed> (forces new resource) backups: "false" => "false" disk: "50" => <computed> image: "ubuntu-18-10-x64" => "debian-9-x64" (forces new resource) ipv4_address: "134.209.226.251" => <computed> ipv4_address_private: "" => <computed> ipv6: "false" => "false" ipv6_address: "" => <computed> ipv6_address_private: "" => <computed> locked: "false" => <computed> memory: "2048" => <computed> monitoring: "false" => "false" name: "WDI" => "WDI" price_hourly: "0.01488" => <computed> price_monthly: "10" => <computed> private_networking: "false" => "false" region: "fra1" => "fra1" resize_disk: "true" => "true" size: "s-1vcpu-2gb" => "s-1vcpu-2gb" status: "active" => <computed> vcpus: "1" => <computed> volume_ids.#: "0" => <computed> Plan: 1 to add, 1 to change, 1 to destroy. Terminal -
$ terraform apply digitalocean_droplet.demo: Destroying... (ID: 137341968) digitalocean_droplet.demo: Destruction
complete after 12s digitalocean_droplet.demo: Creating... backups: "" => "false" disk: "" => "<computed>" image: "" => "debian-9-x64" ipv4_address: "" => "<computed>" ipv4_address_private: "" => "<computed>" ipv6: "" => "false" ipv6_address: "" => "<computed>" ipv6_address_private: "" => "<computed>" locked: "" => "<computed>" memory: "" => "<computed>" monitoring: "" => "false" name: "" => "WDI" price_hourly: "" => "<computed>" price_monthly: "" => "<computed>" private_networking: "" => "false" region: "" => "fra1" resize_disk: "" => "true" size: "" => "s-1vcpu-2gb" status: "" => "<computed>" vcpus: "" => "<computed>" volume_ids.#: "" => "<computed>" digitalocean_droplet.demo: Creation complete after 35s (ID: 137342688) cloudflare_record.demo: Modifying... (ID: b99a42e66c68a8a5a0a19f1a27821a80) value: "134.209.226.251" => "46.101.143.241" cloudflare_record.demo: Modifications complete after 1s (ID: b99a42e66c68a8a5a0a19f1a27821a80) Apply complete! Resources: 1 added, 1 changed, 1 destroyed. Terminal -
100+ providers AWS Bitbucket Chef Cloudflare Consul Datadog DigitalOcean DNSimple
Docker Dyn Fastly GitHub Google Cloud Grafana Heroku Kubernetes Logentries MySQL New Relic Nomad NS1 OpenStack OVH Rancher Scaleway SoftLayer VMware -
resource "github_team" "wdi" { name = "WDI" } resource
"github_team_membership" "sebastian" { team_id = "${github_team.wdi.id}" username = "sgrodzicki" } main.tf -
$ terraform plan Resource actions are indicated with the
following symbols: + create Terraform will perform the following actions: + github_team.wdi id: <computed> etag: <computed> name: "WDI" privacy: "secret" slug: <computed> + github_team_membership.sebastian id: <computed> etag: <computed> role: "member" team_id: "${github_team.wdi.id}" username: "sgrodzicki" Plan: 2 to add, 0 to change, 0 to destroy. Terminal -
$ terraform apply github_team.wdi: Creating... etag: "" => "<computed>"
name: "" => "WDI" privacy: "" => "secret" slug: "" => "<computed>" github_team.wdi: Creation complete after 2s (ID: 3174820) github_team_membership.sebastian: Creating... etag: "" => "<computed>" role: "" => "member" team_id: "" => "3174820" username: "" => "sgrodzicki" github_team_membership.sebastian: Creation complete after 2s (ID: 3174820:sgrodzicki) Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Terminal -
$ terraform plan Resource actions are indicated with the
following symbols: + create Terraform will perform the following actions: + github_repository.wdi id: <computed> allow_merge_commit: "true" allow_rebase_merge: "true" allow_squash_merge: "true" archived: "false" default_branch: <computed> description: "WDI 2019" etag: <computed> full_name: <computed> git_clone_url: <computed> html_url: <computed> http_clone_url: <computed> name: "wdi" ssh_clone_url: <computed> svn_url: <computed> Plan: 1 to add, 0 to change, 0 to destroy. Terminal -
$ terraform apply github_repository.wdi: Creating... allow_merge_commit: "" => "true"
allow_rebase_merge: "" => "true" allow_squash_merge: "" => "true" archived: "" => "false" default_branch: "" => "<computed>" description: "" => "WDI 2019" etag: "" => "<computed>" full_name: "" => "<computed>" git_clone_url: "" => "<computed>" html_url: "" => "<computed>" http_clone_url: "" => "<computed>" name: "" => "wdi" ssh_clone_url: "" => "<computed>" svn_url: "" => "<computed>" github_repository.wdi: Creation complete after 3s (ID: wdi) Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Terminal -
$ terraform graph cloudflare_record.demo digitalocean_droplet.demo provider.cloudflare provider.digitalocean [root] meta.count-boundary (count
boundary fixup) [root] provider.cloudflare (close) [root] provider.digitalocean (close) [root] root -
$ terraform state list (List resources in the state) mv
(Move an item in the state) pull (Pull current state and output to stdout) push (Update remote state from a local state file) rm (Remove an item from the state) show (Show a resource in the state) -
module "stack" { source = "github.com/segmentio/stack" environment = "demo" key_name
= "sgrodzicki" name = "WDI" } main.tf