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

Infrastructure as Code @ phpCE 2017

Infrastructure as Code @ phpCE 2017

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

9a328142924c93e5e148c75356ba6d42?s=128

Sebastian Grodzicki

November 02, 2017
Tweet

More Decks by Sebastian Grodzicki

Other Decks in Programming

Transcript

  1. Infrastructure as Code Sebastian Grodzicki @ phpCE 2017 !@sebgrodzicki

  2. $ whoami Sebastian Grodzicki
 • CTO at SHOWROOM • PHP

    developer for 15+ years • DevOps enthusiast !@sebgrodzicki
  3. module "stack" {
 source = "github.com/segmentio/stack"
 environment = "demo"
 key_name

    = "sgrodzicki"
 name = "phpCE"
 } main.tf
  4. None
  5. None
  6. None
  7. None
  8. How did we get here?

  9. Data center evolution DC

  10. Data center evolution DC

  11. Data center evolution DC

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

    VM VM VM VM VM VM
  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
  14. Data center evolution 
 DNS 
 CDN

  15. Data center evolution PaaS IaaS SaaS

  16. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 

  17. Data center evolution ACQUIRE
 
 
 
 
 
 


    
 
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 VENDOR
  18. Data center evolution ACQUIRE
 
 
 
 
 
 


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


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


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


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


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


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


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

  26. Cloud computing ACQUIRE
 
 
 
 
 
 
 


    
 
 DESTROY
 
 
 
 
 
 
 
 
 
 PROVISION
 
 
 
 
 
 
 
 
 
 UPDATE
 
 
 
 
 
 
 
 
 
 SECONDS SECONDS SECONDS SECONDS
  27. How do I provision resources?

  28. How do I manage resource lifecycles?

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

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

  31. How do I automate and share those configurations?

  32. None
  33. TERRAFORM'S GOAL Provide a single workflow…

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

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

  36. TERRAFORM'S GOAL …that can be iterated
 and changed safely…

  37. TERRAFORM'S GOAL …capable of complex
 N-tier applications.

  38. resource "digitalocean_droplet" "demo" {
 image = "ubuntu-17-10-x64"
 name = "phpCE"


    region = "fra1"
 size = "512mb"
 }
 
 resource "cloudflare_record" "demo" {
 domain = "grodzicki.pl"
 name = "phpce"
 type = "A"
 value = "${digitalocean_droplet.demo.ipv4_address}"
 }
 main.tf
  39. $ terraform init
 
 Initializing provider plugins...
 - Downloading plugin

    for provider "digitalocean" (0.1.2)...
 - Downloading plugin for provider "cloudflare" (0.1.0)...
 
 Terraform has been successfully initialized! Terminal
  40. $ terraform plan
 
 Terraform will perform the following actions:


    
 + cloudflare_record.demo
 id: <computed>
 domain: "grodzicki.pl"
 hostname: <computed>
 name: "phpce"
 proxied: "false"
 ttl: <computed>
 type: "A"
 value: "${digitalocean_droplet.demo.ipv4_address}"
 zone_id: <computed>
 
 + digitalocean_droplet.demo
 id: <computed>
 disk: <computed>
 image: "ubuntu-17-10-x64"
 ipv4_address: <computed>
 ipv4_address_private: <computed>
 ipv6_address: <computed>
 ipv6_address_private: <computed>
 locked: <computed>
 name: "phpCE"
 price_hourly: <computed>
 price_monthly: <computed>
 region: "fra1"
 resize_disk: "true"
 size: "512mb"
 status: <computed>
 vcpus: <computed>
 
 Plan: 2 to add, 0 to change, 0 to destroy. Terminal
  41. $ terraform apply
 
 digitalocean_droplet.demo: Creating...
 disk: "" => "<computed>"


    image: "" => "ubuntu-17-10-x64"
 ipv4_address: "" => "<computed>"
 ipv4_address_private: "" => "<computed>"
 ipv6_address: "" => "<computed>"
 ipv6_address_private: "" => "<computed>"
 locked: "" => "<computed>"
 name: "" => "phpCE"
 price_hourly: "" => "<computed>"
 price_monthly: "" => "<computed>"
 region: "" => "fra1"
 resize_disk: "" => "true"
 size: "" => "512mb"
 status: "" => "<computed>"
 vcpus: "" => "<computed>"
 digitalocean_droplet.demo: Creation complete after 26s (ID: 69048017)
 cloudflare_record.demo: Creating...
 domain: "" => "grodzicki.pl"
 hostname: "" => "<computed>"
 name: "" => "phpce"
 proxied: "" => "false"
 ttl: "" => "<computed>"
 type: "" => "A"
 value: "" => "207.154.225.151"
 zone_id: "" => "<computed>"
 cloudflare_record.demo: Creation complete after 1s (ID: 4a59cffb21560ea257b2567d362fec2b)
 
 Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Terminal
  42. $ terraform destroy
 
 digitalocean_droplet.demo: Refreshing state... (ID: 69048513)
 cloudflare_record.demo:

    Refreshing state... (ID: c30fe74f5279d0def)
 cloudflare_record.demo: Destroying... (ID: c30fe74f5279d0def)
 cloudflare_record.demo: Destruction complete after 2s
 digitalocean_droplet.demo: Destroying... (ID: 69048513)
 digitalocean_droplet.demo: Destruction complete after 14s
 
 Destroy complete! Resources: 2 destroyed. Terminal
  43. resource "digitalocean_droplet" "demo" {
 image = "ubuntu-17-10-x64"
 name = "phpCE"


    region = "fra1"
 - size = "512mb"
 + size = "1gb"
 }
 
 resource "cloudflare_record" "demo" {
 domain = "grodzicki.pl"
 name = "phpce"
 type = "A"
 value = "${digitalocean_droplet.demo.ipv4_address}"
 }
 main.tf
  44. $ terraform plan
 
 Resource actions are indicated with the

    following symbols:
 ~ update in-place
 
 Terraform will perform the following actions:
 
 ~ digitalocean_droplet.demo
 size: "512mb" => "1gb"
 
 Plan: 0 to add, 1 to change, 0 to destroy. Terminal
  45. $ terraform apply
 
 digitalocean_droplet.demo: Modifying... (ID: 69048968)
 size: "512mb"

    => "1gb"
 digitalocean_droplet.demo: Modifications complete after 53s (ID: 69048968)
 
 Apply complete! Resources: 0 added, 1 changed, 0 destroyed. Terminal
  46. resource "digitalocean_droplet" "demo" {
 - image = "ubuntu-17-10-x64"
 + image

    = "debian-9-x64"
 name = "phpCE"
 region = "fra1"
 size = "1gb"
 }
 
 resource "cloudflare_record" "demo" {
 domain = "grodzicki.pl"
 name = "phpce"
 type = "A"
 value = "${digitalocean_droplet.demo.ipv4_address}"
 }
 main.tf
  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: "46.101.143.229" => "${digitalocean_droplet.demo.ipv4_address}"
 
 -/+ digitalocean_droplet.demo (new resource required)
 id: "69048968" => <computed> (forces new resource)
 disk: "30" => <computed>
 image: "ubuntu-17-10-x64" => "debian-9-x64" (forces new resource)
 ipv4_address: "46.101.143.229" => <computed>
 ipv4_address_private: "" => <computed>
 ipv6_address: "" => <computed>
 ipv6_address_private: "" => <computed>
 locked: "false" => <computed>
 name: "phpCE" => "phpCE"
 price_hourly: "0.01488" => <computed>
 price_monthly: "10" => <computed>
 region: "fra1" => "fra1"
 resize_disk: "true" => "true"
 size: "1gb" => "1gb"
 status: "active" => <computed>
 vcpus: "1" => <computed>
 
 Plan: 1 to add, 1 to change, 1 to destroy. Terminal
  48. $ terraform apply
 
 digitalocean_droplet.demo: Destroying... (ID: 69056095)
 digitalocean_droplet.demo: Destruction

    complete after 12s
 digitalocean_droplet.demo: Creating...
 disk: "" => "<computed>"
 image: "" => "debian-9-x64"
 ipv4_address: "" => "<computed>"
 ipv4_address_private: "" => "<computed>"
 ipv6_address: "" => "<computed>"
 ipv6_address_private: "" => "<computed>"
 locked: "" => "<computed>"
 name: "" => "phpCE"
 price_hourly: "" => "<computed>"
 price_monthly: "" => "<computed>"
 region: "" => "fra1"
 resize_disk: "" => "true"
 size: "" => "1gb"
 status: "" => "<computed>"
 vcpus: "" => "<computed>"
 digitalocean_droplet.demo: Creation complete after 47s (ID: 69056200)
 
 cloudflare_record.demo: Modifying... (ID: 7a5ad9e5a510eb3a87606bbacf2ccbec)
 value: "207.154.230.75" => "165.227.146.145"
 cloudflare_record.demo: Modifications complete after 3s (ID: 7a5ad9e5a510eb3a87606bbacf2ccbec)
 
 Apply complete! Resources: 1 added, 1 changed, 1 destroyed. Terminal
  49. Human-friendly configuration JSON-compatible for non-humans

  50. VCS-friendly format

  51. Entire infrastructure as code

  52. 70+ 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
  53. resource "github_team" "backend" {
 name = "backend"
 }
 
 resource

    "github_team_membership" "sebastian" {
 team_id = "${github_team.backend.id}"
 username = "sgrodzicki"
 } main.tf
  54. $ terraform plan
 
 Resource actions are indicated with the

    following symbols:
 + create
 
 Terraform will perform the following actions:
 
 + github_team.backend
 id: <computed>
 name: "backend"
 privacy: "secret"
 
 + github_team_membership.sebastian
 id: <computed>
 role: "member"
 team_id: "${github_team.backend.id}"
 username: "sgrodzicki"
 
 Plan: 2 to add, 0 to change, 0 to destroy. Terminal
  55. $ terraform apply
 
 github_team.backend: Creating...
 name: "" => "backend"


    privacy: "" => "secret"
 github_team.backend: Creation complete after 1s (ID: 2541906)
 
 github_team_membership.sebastian: Creating...
 role: "" => "member"
 team_id: "" => "2541906"
 username: "" => "sgrodzicki"
 github_team_membership.sebastian: Creation complete after 1s (ID: 2541906:sgrodzicki)
 
 Apply complete! Resources: 2 added, 0 changed, 0 destroyed. Terminal
  56. resource "github_repository" "phpce" {
 name = "phpce"
 description = "phpCE

    2017"
 } main.tf
  57. $ terraform plan
 
 Resource actions are indicated with the

    following symbols:
 + create
 
 Terraform will perform the following actions:
 
 + github_repository.phpce
 id: <computed>
 allow_merge_commit: "true"
 allow_rebase_merge: "true"
 allow_squash_merge: "true"
 default_branch: <computed>
 description: "phpCE 2017"
 full_name: <computed>
 git_clone_url: <computed>
 http_clone_url: <computed>
 name: "phpce"
 ssh_clone_url: <computed>
 svn_url: <computed>
 
 Plan: 1 to add, 0 to change, 0 to destroy. Terminal
  58. $ terraform apply
 
 github_repository.phpce: Creating...
 allow_merge_commit: "" => "true"


    allow_rebase_merge: "" => "true"
 allow_squash_merge: "" => "true"
 default_branch: "" => "<computed>"
 description: "" => "phpCE 2017"
 full_name: "" => "<computed>"
 git_clone_url: "" => "<computed>"
 http_clone_url: "" => "<computed>"
 name: "" => "phpce"
 ssh_clone_url: "" => "<computed>"
 svn_url: "" => "<computed>"
 
 github_repository.phpce: Creation complete after 1s (ID: phpce)
 
 Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Terminal
  59. Demo

  60. $ terraform console Interactive console
 for Terraform interpolations

  61. $ terraform fmt Rewrites config files
 to canonical format

  62. $ terraform graph Create a visual graph
 of Terraform resources

  63. $ 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
  64. $ terraform import Import existing infrastructure
 into Terraform

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

  66. $ 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)
  67. module "stack" {
 source = "github.com/segmentio/stack"
 environment = "demo"
 key_name

    = "sgrodzicki"
 name = "phpCE"
 } main.tf
  68. Terraform Website

  69. Terraform Documentation

  70. Terraform Module Registry

  71. Questions? joind.in/talk/49431

  72. THANK YOU! joind.in/talk/49431