Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Infrastructure as Code @ DevOpsDay Warsaw 2019

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
Tweet

More Decks by Sebastian Grodzicki

Other Decks in Technology

Transcript

  1. $ whoami Sebastian Grodzicki
 • Engineering Manager at • ex-CTO

    at SHOWROOM & GoldenLine • #LifeAtElastic @sebgrodzicki
  2. 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
  3. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 

  4. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR
  5. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR DC OPS
  6. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR SYSADMIN DC OPS
  7. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR DC OPS SYSADMIN DC OPS
  8. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR DC OPS SYSADMIN DC OPS WEEKS
  9. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR DC OPS SYSADMIN DC OPS WEEKS DAYS
  10. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR DC OPS SYSADMIN DC OPS WEEKS DAYS DAYS
  11. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR DC OPS SYSADMIN DC OPS WEEKS DAYS DAYS DAYS
  12. Cloud computing ACQUIRE
 
 
 
 
 
 
 


    
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 SECONDS SECONDS SECONDS SECONDS
  13. 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
  14. $ 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
  15. $ 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
  16. $ 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
  17. $ 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
  18. 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
  19. $ 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
  20. $ 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
  21. 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
  22. $ 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
  23. $ 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
  24. 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
  25. resource "github_team" "wdi" {
 name = "WDI"
 }
 
 resource

    "github_team_membership" "sebastian" {
 team_id = "${github_team.wdi.id}"
 username = "sgrodzicki"
 } main.tf
  26. $ 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
  27. $ 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
  28. $ 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
  29. $ 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
  30. $ 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
  31. $ 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)