Managing Applications and Infrastructure with Terraform-Deploying Infrastructure with Terraform-(1)Terraform Basics and a Docker Deployment-(12)Maps and Lookups

2018年10月04日


Managing Applications and Infrastructure with Terraform-Deploying Infrastructure with Terraform
1. Terraform Basics and a Docker Deployment
12. Maps and Lookups

~/docker# vim variables.tf

variable "env" {
  description = "env: dev or prod"
}
variable "image" {
  description = "image for container"
  type = map
  default = {
    dev = "ghost:latest"
    prod = "ghost:alpine"
  }
}
variable "container_name" {
  description = "Name of Container"
  default = "blog"
}
variable "int_port" {
  description = "Internal port for container"
  default = "2368"
}
variable "ext_port" {
  description = "External port for container"
  default = "80"
Add and update these blocks.
variable "env" {
  description = "env: dev or prod"
}

variable "image" {
  description = "image for container"
  type = map
  default = {
    dev = "ghost:latest"
    prod = "ghost:alpine"
  }
}

~/docker# vim main.tf
# Download the latest Ghost image
module "image" {
  source = "./image"
  image = lookup(var.image, var.env)
}

# Start the Container
module "container" {
  source = "./container"
  image = module.image.image_out
  name = var.container_name
  int_port = var.int_port
  ext_port = var.ext_port
}
Update this block.
# Download the latest Ghost image
module "image" {
  source = "./image"
  image = lookup(var.image, var.env)
}

~/docker# terraform plan
var.env
  env: dev or prod

  Enter a value: prod

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + module.container.docker_container.container_id
      id:                       <computed>
      bridge:                   <computed>
      gateway:                  <computed>
      image:                    "${var.image}"
      ip_address:               <computed>
      ip_prefix_length:         <computed>
      log_driver:               "json-file"
      must_run:                 "true"
      name:                     "blog"
      ports.#:                  "1"
      ports.580670141.external: "80"
      ports.580670141.internal: "2368"
      ports.580670141.ip:       ""
      ports.580670141.protocol: "tcp"
      restart:                  "no"

  + module.image.docker_image.image_id
      id:                       <computed>
      latest:                   <computed>
      name:                     "ghost:alpine"


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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

~/docker# vim variables.tf
variable "env" {
  description = "env: dev or prod"
}
variable "image" {
  description = "image for container"
  type = map
  default = {
    dev = "ghost:latest"
    prod = "ghost:alpine"
  }
}
variable "container_name" {
  description = "Name of Container"
  type = map
  default = {
    dev = "dev_blog"
    prod = "prod_blog"
  }
}
variable "int_port" {
  description = "Internal port for container"
  type = map
  default = {
    dev = "2368"
    prod = "2368"
  }
}
variable "ext_port" {
  description = "External port for container"
  type = map
  default = {
    dev = "8080"
    prod = "80"
  }
}

~/docker# vim main.tf
# Download the latest Ghost image
module "image" {
  source = "./image"
  image = lookup(var.image, var.env)
}

# Start the Container
module "container" {
  source = "./container"
  image = module.image.image_out
  name = lookup(var.container_name, var.env)
  int_port = lookup(var.int_port, var.env)
  ext_port = lookup(var.ext_port, var.env)
}

~/docker# terraform plan
var.env
  env: dev or prod

  Enter a value: prod

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.container.docker_container.container_id will be created
  + resource "docker_container" "container_id" {
      + attach           = false
      + bridge           = (known after apply)
      + command          = (known after apply)
      + container_logs   = (known after apply)
      + dns              = (known after apply)
      + dns_opts         = (known after apply)
      + entrypoint       = (known after apply)
      + exit_code        = (known after apply)
      + gateway          = (known after apply)
      + hostname         = (known after apply)
      + id               = (known after apply)
      + image            = (known after apply)
      + ip_address       = (known after apply)
      + ip_prefix_length = (known after apply)
      + ipc_mode         = (known after apply)
      + log_driver       = (known after apply)
      + log_opts         = (known after apply)
      + logs             = false
      + must_run         = true
      + name             = "blog"
      + network_data     = (known after apply)
      + read_only        = false
      + restart          = "no"
      + rm               = false
      + shm_size         = (known after apply)
      + start            = true
      + user             = (known after apply)
      + working_dir      = (known after apply)

      + ports {
          + external = 80
          + internal = 2368
          + ip       = "0.0.0.0"
          + protocol = "tcp"
        }
    }

  # module.image.docker_image.image_id will be created
  + resource "docker_image" "image_id" {
      + id     = (known after apply)
      + latest = (known after apply)
      + name   = "ghost:alpine"
    }

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

Changes to Outputs:
  + IP_Address     = (known after apply)
  + container_name = "blog"

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

~/docker# terraform apply
var.env
  env: dev or prod

  Enter a value: dev

module.image.docker_image.image_id: Refreshing state... [id=sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5ghost:latest]
module.container.docker_container.container_id: Refreshing state... [id=9ff202fb1aa86e686b3b912150d0639db5862989b384241e6aa33fe8ff18fdaf]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # module.container.docker_container.container_id must be replaced
-/+ resource "docker_container" "container_id" {
        attach            = false
      + bridge            = (known after apply)
      ~ command           = [
          - "node",
          - "current/index.js",
        ] -> (known after apply)
      + container_logs    = (known after apply)
      - cpu_shares        = 0 -> null
      ~ dns               = [] -> (known after apply)
      ~ dns_opts          = [] -> (known after apply)
      - dns_search        = [] -> null
      ~ entrypoint        = [
          - "docker-entrypoint.sh",
        ] -> (known after apply)
      + exit_code         = (known after apply)
      ~ gateway           = "172.17.0.1" -> (known after apply)
      - group_add         = [] -> null
      ~ hostname          = "9ff202fb1aa8" -> (known after apply)
      ~ id                = "9ff202fb1aa86e686b3b912150d0639db5862989b384241e6aa33fe8ff18fdaf" -> (known after apply)
        image             = "sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5"
      ~ ip_address        = "172.17.0.2" -> (known after apply)
      ~ ip_prefix_length  = 16 -> (known after apply)
      ~ ipc_mode          = "private" -> (known after apply)
      - links             = [] -> null
      ~ log_driver        = "json-file" -> (known after apply)
      ~ log_opts          = {} -> (known after apply)
        logs              = false
      - max_retry_count   = 0 -> null
      - memory            = 0 -> null
      - memory_swap       = 0 -> null
        must_run          = true
      ~ name              = "blog" -> "dev_blog" # forces replacement
      ~ network_data      = [
          - {
              - gateway          = "172.17.0.1"
              - ip_address       = "172.17.0.2"
              - ip_prefix_length = 16
              - network_name     = "bridge"
            },
        ] -> (known after apply)
      - network_mode      = "default" -> null
      - privileged        = false -> null
      - publish_all_ports = false -> null
        read_only         = false
        restart           = "no"
        rm                = false
      ~ shm_size          = 64 -> (known after apply)
        start             = true
      - sysctls           = {} -> null
      - tmpfs             = {} -> null
      + user              = (known after apply)
      ~ working_dir       = "/var/lib/ghost" -> (known after apply)

      ~ ports {
          ~ external = 80 -> 8080 # forces replacement
            internal = 2368
            ip       = "0.0.0.0"
            protocol = "tcp"
        }
    }

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

Changes to Outputs:
  ~ IP_Address     = "172.17.0.2" -> (known after apply)
  ~ container_name = "blog" -> "dev_blog"

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.container.docker_container.container_id: Destroying... [id=9ff202fb1aa86e686b3b912150d0639db5862989b384241e6aa33fe8ff18fdaf]
module.container.docker_container.container_id: Destruction complete after 1s
module.container.docker_container.container_id: Creating...
module.container.docker_container.container_id: Creation complete after 1s [id=63315e22f59df1e270fa50c19f80e58e5d2639cfcbcc834ae6884c5aeb4b8e55]

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

Outputs:

IP_Address = 172.17.0.2
container_name = dev_blog

The variable can be set via an environment variable.
~/docker# export TF_VAR_env=prod

~/docker# terraform console
> lookup(var.ext_port, var.env)
80
> lookup(var.container_name, var.env)
prod_blog
> ^C

Ctrl + C

~/docker# unset TF_VAR_env

~/docker# export TF_VAR_env=dev

~/docker# terraform destroy
module.image.docker_image.image_id: Refreshing state... [id=sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5ghost:latest]
module.container.docker_container.container_id: Refreshing state... [id=63315e22f59df1e270fa50c19f80e58e5d2639cfcbcc834ae6884c5aeb4b8e55]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # module.container.docker_container.container_id will be destroyed
  - resource "docker_container" "container_id" {
      - attach            = false -> null
      - command           = [
          - "node",
          - "current/index.js",
        ] -> null
      - cpu_shares        = 0 -> null
      - dns               = [] -> null
      - dns_opts          = [] -> null
      - dns_search        = [] -> null
      - entrypoint        = [
          - "docker-entrypoint.sh",
        ] -> null
      - gateway           = "172.17.0.1" -> null
      - group_add         = [] -> null
      - hostname          = "63315e22f59d" -> null
      - id                = "63315e22f59df1e270fa50c19f80e58e5d2639cfcbcc834ae6884c5aeb4b8e55" -> null
      - image             = "sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5" -> null
      - ip_address        = "172.17.0.2" -> null
      - ip_prefix_length  = 16 -> null
      - ipc_mode          = "private" -> null
      - links             = [] -> null
      - log_driver        = "json-file" -> null
      - log_opts          = {} -> null
      - logs              = false -> null
      - max_retry_count   = 0 -> null
      - memory            = 0 -> null
      - memory_swap       = 0 -> null
      - must_run          = true -> null
      - name              = "dev_blog" -> null
      - network_data      = [
          - {
              - gateway          = "172.17.0.1"
              - ip_address       = "172.17.0.2"
              - ip_prefix_length = 16
              - network_name     = "bridge"
            },
        ] -> null
      - network_mode      = "default" -> null
      - privileged        = false -> null
      - publish_all_ports = false -> null
      - read_only         = false -> null
      - restart           = "no" -> null
      - rm                = false -> null
      - shm_size          = 64 -> null
      - start             = true -> null
      - sysctls           = {} -> null
      - tmpfs             = {} -> null
      - working_dir       = "/var/lib/ghost" -> null

      - ports {
          - external = 8080 -> null
          - internal = 2368 -> null
          - ip       = "0.0.0.0" -> null
          - protocol = "tcp" -> null
        }
    }

  # module.image.docker_image.image_id will be destroyed
  - resource "docker_image" "image_id" {
      - id     = "sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5ghost:latest" -> null
      - latest = "sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5" -> null
      - name   = "ghost:latest" -> null
    }

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

Changes to Outputs:
  - IP_Address     = "172.17.0.2" -> null
  - container_name = "dev_blog" -> null

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

module.container.docker_container.container_id: Destroying... [id=63315e22f59df1e270fa50c19f80e58e5d2639cfcbcc834ae6884c5aeb4b8e55]
module.container.docker_container.container_id: Destruction complete after 1s
module.image.docker_image.image_id: Destroying... [id=sha256:98c65d66926b2da9fbb696d43aadfaf3fee847b7185e132e199532bc549aeba5ghost:latest]
module.image.docker_image.image_id: Destruction complete after 8s

Destroy complete! Resources: 2 destroyed.

~/docker# unset TF_VAR_env

In this post, we have gone through the Terraform Environment Variable configuration.


References

Environment Variables

Category: orchestration Tags: public

Upvote


Downvote