Menu
blog.headdesk.me
blog.headdesk.me

Terraform resource config – inline or standalone

Posted on 2024/12/052024/12/05

Settings for some resources can be defined inline or as standalone resources. In this article, we will see how they behave differently.

For settings like routes for route table or security group rules for security group, you have options to config them inline or as standalone resources. Let’s use routes for demonstration. In the following code, I have 2 route tables, each with several routes. rt1 is managed with inline routes, while rt2’s routes are set with standalone aws_route resources.

locals {
route-dest = toset([
"192.168.10.1/32",
"192.168.10.2/32",
"192.168.10.3/32"
])
}

resource "aws_route_table" "rt1" {
vpc_id = "vpc-01234567890123456"
dynamic "route" {
for_each = local.route-dest
content {
cidr_block = route.value
gateway_id = "igw-01234567890123456"
}
}
}

resource "aws_route_table" "rt2" {
vpc_id = "vpc-01234567890123456"
}

resource "aws_route" "rt2-routes" {
for_each = local.route-dest
route_table_id = aws_route_table.rt2.id
destination_cidr_block = each.value
gateway_id = "igw-01234567890123456"
}

Both of them works and there is little difference for the initial resource creation. But the challenge comes when you need to modify the routes later on. Suppose I now want to add one more route, say adding 192.168.20.1/32. I do that by adding the cidr block to local.route-dest. When I run terraform plan, I see that for rt1, terraform removes all existing routes and then add them back. For rt2, a new aws_route resource is created for the new address and existing routes are left alone.

The way terraform handles rt1 can be a bit of an issue. If the routes are essential to production traffic, you don’t want them removed even for less than a second. Especially when the removal is technically unnecessary. If you have numerous routes and the new route exceeds the service quota, terraform apply will fail. You now need to come up with a fix, fast. We don’t want to be in that situation.

Inline settings are convenient and the code is lean. But if you are managing your resources with terraform continuously, use standalone resources.

Below is the terraform plan for adding 1 additional route for 192.168.20.1/32.

Terraform will perform the following actions:

# aws_route.rt2-routes["192.168.20.1/32"] will be created
+ resource "aws_route" "rt2-routes" {
+ destination_cidr_block = "192.168.20.1/32"
+ gateway_id = "igw-01234567890123456"
+ id = (known after apply)
+ instance_id = (known after apply)
+ instance_owner_id = (known after apply)
+ network_interface_id = (known after apply)
+ origin = (known after apply)
+ route_table_id = "rtb-05e8665817bf302ac"
+ state = (known after apply)
}

# aws_route_table.rt1 will be updated in-place
~ resource "aws_route_table" "rt1" {
id = "rtb-0ad32e3201e3f123f"
~ route = [
- {
- carrier_gateway_id = ""
- cidr_block = "192.168.10.1/32"
- core_network_arn = ""
- destination_prefix_list_id = ""
- egress_only_gateway_id = ""
- gateway_id = "igw-01234567890123456"
- ipv6_cidr_block = ""
- local_gateway_id = ""
- nat_gateway_id = ""
- network_interface_id = ""
- transit_gateway_id = ""
- vpc_endpoint_id = ""
- vpc_peering_connection_id = ""
},
- {
- carrier_gateway_id = ""
- cidr_block = "192.168.10.2/32"
- core_network_arn = ""
- destination_prefix_list_id = ""
- egress_only_gateway_id = ""
- gateway_id = "igw-01234567890123456"
- ipv6_cidr_block = ""
- local_gateway_id = ""
- nat_gateway_id = ""
- network_interface_id = ""
- transit_gateway_id = ""
- vpc_endpoint_id = ""
- vpc_peering_connection_id = ""
},
- {
- carrier_gateway_id = ""
- cidr_block = "192.168.10.3/32"
- core_network_arn = ""
- destination_prefix_list_id = ""
- egress_only_gateway_id = ""
- gateway_id = "igw-01234567890123456"
- ipv6_cidr_block = ""
- local_gateway_id = ""
- nat_gateway_id = ""
- network_interface_id = ""
- transit_gateway_id = ""
- vpc_endpoint_id = ""
- vpc_peering_connection_id = ""
},
+ {
+ carrier_gateway_id = ""
+ cidr_block = "192.168.20.1/32"
+ core_network_arn = ""
+ destination_prefix_list_id = ""
+ egress_only_gateway_id = ""
+ gateway_id = "igw-01234567890123456"
+ ipv6_cidr_block = ""
+ local_gateway_id = ""
+ nat_gateway_id = ""
+ network_interface_id = ""
+ transit_gateway_id = ""
+ vpc_endpoint_id = ""
+ vpc_peering_connection_id = ""
},
+ {
+ carrier_gateway_id = null
+ cidr_block = "192.168.10.1/32"
+ core_network_arn = null
+ destination_prefix_list_id = null
+ egress_only_gateway_id = null
+ gateway_id = "igw-01234567890123456"
+ ipv6_cidr_block = null
+ local_gateway_id = null
+ nat_gateway_id = null
+ network_interface_id = null
+ transit_gateway_id = null
+ vpc_endpoint_id = null
+ vpc_peering_connection_id = null
},
+ {
+ carrier_gateway_id = null
+ cidr_block = "192.168.10.2/32"
+ core_network_arn = null
+ destination_prefix_list_id = null
+ egress_only_gateway_id = null
+ gateway_id = "igw-01234567890123456"
+ ipv6_cidr_block = null
+ local_gateway_id = null
+ nat_gateway_id = null
+ network_interface_id = null
+ transit_gateway_id = null
+ vpc_endpoint_id = null
+ vpc_peering_connection_id = null
},
+ {
+ carrier_gateway_id = null
+ cidr_block = "192.168.10.3/32"
+ core_network_arn = null
+ destination_prefix_list_id = null
+ egress_only_gateway_id = null
+ gateway_id = "igw-01234567890123456"
+ ipv6_cidr_block = null
+ local_gateway_id = null
+ nat_gateway_id = null
+ network_interface_id = null
+ transit_gateway_id = null
+ vpc_endpoint_id = null
+ vpc_peering_connection_id = null
},
]
tags = {}
# (5 unchanged attributes hidden)
}

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


Loading

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Full text search

Recent Posts

  • Generate secure password
  • AWS Compute Savings Plans
  • AWS Zonal Shift
  • Coffee break…
  • Prevent private key from being committed to git
  • aws (14)
  • coffee (2)
  • headfi (1)
  • linux (9)
  • others (61)
  • security (2)
  • tech (41)
  • terraform (3)
  • wordpress (2)

Loading

apache aws awscli azure backup boot cloud coffee docker ec2 EL8 ElasticBeanstalk espresso featured git kernel lelit linux lvm meltdown MFA nat gateway php power proliant python rdp Redhat RHEL rpm Ryzen scp security smartarray smart switch snapshot spectre tech terraform ubuntu ubuntu upgrade vpn windows wordpress workspace

©2026 blog.headdesk.me | Powered by SuperbThemes