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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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.
1
2
3
4
5
6
7
8
9
10
11
12
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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.
1
2
3
4
5
# Download the latest Ghost image
module "image" {
  source = "./image"
  image = lookup(var.image, var.env)
}

~/docker# terraform plan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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