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

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. Infrastructure as Code
    Sebastian Grodzicki @ DevOpsDay 2019
    @sebgrodzicki

    View Slide

  2. $ whoami
    Sebastian Grodzicki

    • Engineering Manager at
    • ex-CTO at SHOWROOM & GoldenLine
    • #LifeAtElastic
    @sebgrodzicki

    View Slide

  3. module "stack" {

    source = "github.com/segmentio/stack"

    environment = "demo"

    key_name = "sgrodzicki"

    name = "WDI"

    }

    main.tf

    View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. How did we get here?

    View Slide

  9. Data center evolution
    DC

    View Slide

  10. Data center evolution
    DC

    View Slide

  11. Data center evolution
    DC

    View Slide

  12. Data center evolution
    DC
    VM VM
    VM
    VM
    VM VM
    VM
    VM
    VM VM
    VM
    VM

    View Slide

  13. 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

    View Slide

  14. Data center evolution

    DNS

    CDN

    View Slide

  15. Data center evolution
    PaaS
    IaaS SaaS

    View Slide

  16. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    View Slide

  17. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR

    View Slide

  18. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR DC OPS

    View Slide

  19. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR SYSADMIN
    DC OPS

    View Slide

  20. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR DC OPS
    SYSADMIN
    DC OPS

    View Slide

  21. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR DC OPS
    SYSADMIN
    DC OPS
    WEEKS

    View Slide

  22. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR DC OPS
    SYSADMIN
    DC OPS
    WEEKS DAYS

    View Slide

  23. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR DC OPS
    SYSADMIN
    DC OPS
    WEEKS DAYS DAYS

    View Slide

  24. Data center evolution
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    VENDOR DC OPS
    SYSADMIN
    DC OPS
    WEEKS DAYS DAYS DAYS

    View Slide

  25. Cloud computing

    View Slide

  26. Cloud computing
    ACQUIRE










    DESTROY










    PROVISION










    UPDATE










    SECONDS SECONDS SECONDS SECONDS

    View Slide

  27. How do I provision resources?

    View Slide

  28. How do I manage resource
    lifecycles?

    View Slide

  29. How do I balance service providers providing
    core technology for my datacenter?

    View Slide

  30. How do I enforce policy across all
    these resources?

    View Slide

  31. How do I automate and share
    those configurations?

    View Slide

  32. View Slide

  33. TERRAFORM'S GOAL
    Provide a single workflow…

    View Slide

  34. TERRAFORM'S GOAL
    …with a unified view…

    View Slide

  35. TERRAFORM'S GOAL
    …using Infrastructure as Code…

    View Slide

  36. TERRAFORM'S GOAL
    …that can be iterated

    and changed safely…

    View Slide

  37. TERRAFORM'S GOAL
    …capable of complex

    N-tier applications.

    View Slide

  38. 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

    View Slide

  39. $ 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

    View Slide

  40. $ terraform plan


    Terraform will perform the following actions:


    + cloudflare_record.demo

    id: 

    created_on: 

    domain: "grodzicki.pl"

    hostname: 

    metadata.%: 

    modified_on: 

    name: "wdi"

    proxiable: 

    proxied: "false"

    ttl: 

    type: "A"

    value: "${digitalocean_droplet.demo.ipv4_address}"

    zone_id: 


    + digitalocean_droplet.demo

    id: 

    backups: "false"

    disk: 

    image: "ubuntu-18-10-x64"

    ipv4_address: 

    ipv4_address_private: 

    ipv6: "false"

    ipv6_address: 

    ipv6_address_private: 

    locked: 

    memory: 

    monitoring: "false"

    name: "WDI"

    price_hourly: 

    price_monthly: 

    private_networking: "false"

    region: "fra1"

    resize_disk: "true"

    size: "s-1vcpu-1gb"

    status: 

    vcpus: 

    volume_ids.#: 


    Plan: 2 to add, 0 to change, 0 to destroy.
    Terminal

    View Slide

  41. $ terraform apply


    digitalocean_droplet.demo: Creating...

    backups: "" => "false"

    disk: "" => ""

    image: "" => "ubuntu-18-10-x64"

    ipv4_address: "" => ""

    ipv4_address_private: "" => ""

    ipv6: "" => "false"

    ipv6_address: "" => ""

    ipv6_address_private: "" => ""

    locked: "" => ""

    memory: "" => ""

    monitoring: "" => "false"

    name: "" => "WDI"

    price_hourly: "" => ""

    price_monthly: "" => ""

    private_networking: "" => "false"

    region: "" => "fra1"

    resize_disk: "" => "true"

    size: "" => "s-1vcpu-1gb"

    status: "" => ""

    vcpus: "" => ""

    volume_ids.#: "" => ""


    digitalocean_droplet.demo: Creation complete after 36s (ID: 137339900)


    cloudflare_record.demo: Creating...

    created_on: "" => ""

    domain: "" => "grodzicki.pl"

    hostname: "" => ""

    metadata.%: "" => ""

    modified_on: "" => ""

    name: "" => "wdi"

    proxiable: "" => ""

    proxied: "" => "false"

    ttl: "" => ""

    type: "" => "A"

    value: "" => "134.209.240.227"

    zone_id: "" => ""


    cloudflare_record.demo: Creation complete after 2s (ID: 02e2198170dba247e7177e7b59a3aa16)


    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    Terminal

    View Slide

  42. $ 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

    View Slide

  43. 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

    View Slide

  44. $ 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

    View Slide

  45. $ 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

    View Slide

  46. 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

    View Slide

  47. $ 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" => (forces new resource)

    backups: "false" => "false"

    disk: "50" => 

    image: "ubuntu-18-10-x64" => "debian-9-x64" (forces new resource)

    ipv4_address: "134.209.226.251" => 

    ipv4_address_private: "" => 

    ipv6: "false" => "false"

    ipv6_address: "" => 

    ipv6_address_private: "" => 

    locked: "false" => 

    memory: "2048" => 

    monitoring: "false" => "false"

    name: "WDI" => "WDI"

    price_hourly: "0.01488" => 

    price_monthly: "10" => 

    private_networking: "false" => "false"

    region: "fra1" => "fra1"

    resize_disk: "true" => "true"

    size: "s-1vcpu-2gb" => "s-1vcpu-2gb"

    status: "active" => 

    vcpus: "1" => 

    volume_ids.#: "0" => 


    Plan: 1 to add, 1 to change, 1 to destroy.
    Terminal

    View Slide

  48. $ terraform apply


    digitalocean_droplet.demo: Destroying... (ID: 137341968)

    digitalocean_droplet.demo: Destruction complete after 12s

    digitalocean_droplet.demo: Creating...

    backups: "" => "false"

    disk: "" => ""

    image: "" => "debian-9-x64"

    ipv4_address: "" => ""

    ipv4_address_private: "" => ""

    ipv6: "" => "false"

    ipv6_address: "" => ""

    ipv6_address_private: "" => ""

    locked: "" => ""

    memory: "" => ""

    monitoring: "" => "false"

    name: "" => "WDI"

    price_hourly: "" => ""

    price_monthly: "" => ""

    private_networking: "" => "false"

    region: "" => "fra1"

    resize_disk: "" => "true"

    size: "" => "s-1vcpu-2gb"

    status: "" => ""

    vcpus: "" => ""

    volume_ids.#: "" => ""

    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

    View Slide

  49. Human-friendly configuration
    JSON-compatible for non-humans

    View Slide

  50. VCS-friendly format

    View Slide

  51. Entire infrastructure as code

    View Slide

  52. 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

    View Slide

  53. resource "github_team" "wdi" {

    name = "WDI"

    }


    resource "github_team_membership" "sebastian" {

    team_id = "${github_team.wdi.id}"

    username = "sgrodzicki"

    }
    main.tf

    View Slide

  54. $ terraform plan


    Resource actions are indicated with the following symbols:

    + create


    Terraform will perform the following actions:


    + github_team.wdi

    id: 

    etag: 

    name: "WDI"

    privacy: "secret"

    slug: 


    + github_team_membership.sebastian

    id: 

    etag: 

    role: "member"

    team_id: "${github_team.wdi.id}"

    username: "sgrodzicki"


    Plan: 2 to add, 0 to change, 0 to destroy.
    Terminal

    View Slide

  55. $ terraform apply


    github_team.wdi: Creating...

    etag: "" => ""

    name: "" => "WDI"

    privacy: "" => "secret"

    slug: "" => ""

    github_team.wdi: Creation complete after 2s (ID: 3174820)


    github_team_membership.sebastian: Creating...

    etag: "" => ""

    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

    View Slide

  56. resource "github_repository" "wdi" {

    name = "wdi"

    description = "WDI 2019"

    }
    main.tf

    View Slide

  57. $ terraform plan


    Resource actions are indicated with the following symbols:

    + create


    Terraform will perform the following actions:


    + github_repository.wdi

    id: 

    allow_merge_commit: "true"

    allow_rebase_merge: "true"

    allow_squash_merge: "true"

    archived: "false"

    default_branch: 

    description: "WDI 2019"

    etag: 

    full_name: 

    git_clone_url: 

    html_url: 

    http_clone_url: 

    name: "wdi"

    ssh_clone_url: 

    svn_url: 


    Plan: 1 to add, 0 to change, 0 to destroy.
    Terminal

    View Slide

  58. $ terraform apply


    github_repository.wdi: Creating...

    allow_merge_commit: "" => "true"

    allow_rebase_merge: "" => "true"

    allow_squash_merge: "" => "true"

    archived: "" => "false"

    default_branch: "" => ""

    description: "" => "WDI 2019"

    etag: "" => ""

    full_name: "" => ""

    git_clone_url: "" => ""

    html_url: "" => ""

    http_clone_url: "" => ""

    name: "" => "wdi"

    ssh_clone_url: "" => ""

    svn_url: "" => ""


    github_repository.wdi: Creation complete after 3s (ID: wdi)


    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    Terminal

    View Slide

  59. Demo

    View Slide

  60. View Slide

  61. $ terraform console
    Interactive console

    for Terraform interpolations

    View Slide

  62. $ terraform fmt
    Rewrites config files

    to canonical format

    View Slide

  63. $ terraform graph
    Create a visual graph

    of Terraform resources

    View Slide

  64. $ 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

    View Slide

  65. $ terraform import
    Import existing infrastructure

    into Terraform

    View Slide

  66. $ terraform output
    Read an output from a state file

    View Slide

  67. $ 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)

    View Slide

  68. module "stack" {

    source = "github.com/segmentio/stack"

    environment = "demo"

    key_name = "sgrodzicki"

    name = "WDI"

    }

    main.tf

    View Slide

  69. Terraform Website

    View Slide

  70. Terraform Documentation

    View Slide

  71. Terraform Module Registry

    View Slide

  72. THANK YOU!

    View Slide