AWS Cloud Blog & News | StratusGrid

How to Use AWS Terraform Defaults Function

Written by Chris Hurst | Aug 3, 2022 4:00:00 AM

Official documentation: defaults - Functions - Configuration Language | Terraform by HashiCorp

At the time of this writing, this is currently an experimental function. For this reason, we are only allowing its use in our parent repos for things like the variables on root repos; we are not allowing the use of the defaults() function until it is released as GA instead of experimental.

Example: Using defaults() to Set the Default Values of Object Attributes Inside of a Map of Objects

This example shows how to have an input variable that accepts a map of objects but allows the objects to only require some values vs. all because there are sane defaults. You can replicate this by copying the content of the two code blocks (test.tf and test.tfvars) into files in an empty folder and running terraform apply (because no resources are being created, you won’t need any credentials or state).

test.tfvars

1ecs_service_variables = {
2
3 test = {
4
5 security_groups = ["string1","string2"]
6 subnets = ["string1","string2"]
7 log_group_path = "/"
8
9 # Task Size
10 taskdef_cpu = 256
11 taskdef_memory = 1024
12
13 }
14
15 test2 = {
16 security_groups = ["string3","string4"]
17 subnets = ["string3","string4"]
18 log_group_path = "/"
19 assign_public_ip = true
20
21 # Task Size
22 taskdef_cpu = 512
23 taskdef_memory = 1024
24 }
25
26}

test.tf

1terraform {
2 # Optional attributes and the defaults function are
3 # both are experimental, so we must opt into the experiment.
4 experiments = [module_variable_optional_attrs]
5}
6
7variable "ecs_service_variables" {
8 description = "A map of the standard values that need to be fed in as variables/adjusted per environment. These should be named to match the names in the map of ecs services"
9 type = map(object(
10 {
11
12 security_groups = list(string)
13 subnets = list(string)
14 assign_public_ip = optional(bool)
15 propagate_tags = optional(string)
16 log_group_path = string
17 enable_execute_command = optional(bool)
18
19 codedeploy_termination_wait_time = optional(number)
20 codedeploy_auto_rollback_enabled = optional(bool)
21
22 # Task Size
23 taskdef_cpu = number
24 taskdef_memory = number
25
26 # Service Scale
27 desired_count = optional(number)
28 min_capacity = optional(number)
29 max_capacity = optional(number)
30 scale_in_cooldown = optional(number)
31 scale_out_cooldown = optional(number)
32
33 }
34 ))
35}
36
37locals {
38 ecs_service_variables = defaults(var.ecs_service_variables, {
39 assign_public_ip = false
40 enable_execute_command = true
41 propagate_tags = "TASK_DEFINITION"
42
43 codedeploy_termination_wait_time = 300
44 codedeploy_auto_rollback_enabled = true
45
46 desired_count = 2
47 min_capacity = 2
48 max_capacity = 3
49 scale_in_cooldown = 300
50 scale_out_cooldown = 600
51 })
52}
53
54output "ecs_service_variables" {
55 value = local.ecs_service_variables
56}

Notice that we are referencing the local, not the variable. If you run terraform apply -var-file ./test.tfvars, you should see this:

1Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
2
3Outputs:
4
5ecs_service_variables = tomap({
6 "test" = {
7 "assign_public_ip" = false
8 "codedeploy_auto_rollback_enabled" = true
9 "codedeploy_termination_wait_time" = 300
10 "desired_count" = 2
11 "enable_execute_command" = true
12 "log_group_path" = "/"
13 "max_capacity" = 3
14 "min_capacity" = 2
15 "propagate_tags" = "TASK_DEFINITION"
16 "scale_in_cooldown" = 300
17 "scale_out_cooldown" = 600
18 "security_groups" = tolist([
19 "string1",
20 "string2",
21 ])
22 "subnets" = tolist([
23 "string1",
24 "string2",
25 ])
26 "taskdef_cpu" = 256
27 "taskdef_memory" = 1024
28 }
29 "test2" = {
30 "assign_public_ip" = true
31 "codedeploy_auto_rollback_enabled" = true
32 "codedeploy_termination_wait_time" = 300
33 "desired_count" = 2
34 "enable_execute_command" = true
35 "log_group_path" = "/"
36 "max_capacity" = 3
37 "min_capacity" = 2
38 "propagate_tags" = "TASK_DEFINITION"
39 "scale_in_cooldown" = 300
40 "scale_out_cooldown" = 600
41 "security_groups" = tolist([
42 "string3",
43 "string4",
44 ])
45 "subnets" = tolist([
46 "string3",
47 "string4",
48 ])
49 "taskdef_cpu" = 512
50 "taskdef_memory" = 1024
51 }
52})

If you want to get this in a format that can be machine interpreted (to import with jsondecode() for instance), you can get that like so with terraform output -json | jq .ecs_service_variables.value which should return:

1{
2 "test": {
3 "assign_public_ip": false,
4 "codedeploy_auto_rollback_enabled": true,
5 "codedeploy_termination_wait_time": 300,
6 "desired_count": 2,
7 "enable_execute_command": true,
8 "log_group_path": "/",
9 "max_capacity": 3,
10 "min_capacity": 2,
11 "propagate_tags": "TASK_DEFINITION",
12 "scale_in_cooldown": 300,
13 "scale_out_cooldown": 600,
14 "security_groups": [
15 "string1",
16 "string2"
17 ],
18 "subnets": [
19 "string1",
20 "string2"
21 ],
22 "taskdef_cpu": 256,
23 "taskdef_memory": 1024
24 },
25 "test2": {
26 "assign_public_ip": true,
27 "codedeploy_auto_rollback_enabled": true,
28 "codedeploy_termination_wait_time": 300,
29 "desired_count": 2,
30 "enable_execute_command": true,
31 "log_group_path": "/",
32 "max_capacity": 3,
33 "min_capacity": 2,
34 "propagate_tags": "TASK_DEFINITION",
35 "scale_in_cooldown": 300,
36 "scale_out_cooldown": 600,
37 "security_groups": [
38 "string3",
39 "string4"
40 ],
41 "subnets": [
42 "string3",
43 "string4"
44 ],
45 "taskdef_cpu": 512,
46 "taskdef_memory": 1024
47 }
48}

Master Cloud Management with StratusGrid's Terraform Defaults Function Expertise

Embrace the full potential of Terraform to streamline your AWS cloud management with StratusGrid's guidance on the Defaults Function. Whether you're new to Terraform or looking to refine your skills, StratusGrid is here to illuminate the path toward more robust and simplified cloud infrastructure management.

Contact us today to explore how our expertise can elevate your Terraform projects and unlock new levels of efficiency and control in your AWS environment.

BONUS: Find Out if Your Organization is Ready for The Cloud ⤵️