I want to create VPN client endpoint in AWS using terraform.
My current block of code is:
resource "aws_ec2_client_vpn_route" "vpn_route" {
depends_on = [
aws_ec2_client_vpn_network_association.vpn_subnets
]
count = length(var.rule)
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.vpn.id
destination_cidr_block = element(var.rule, count.index)
target_vpc_subnet_id = element(var.subnets_id, count.index)
}
Here rule & subnet_id variables are as below:
rule = ["172.16.0.0/16", "172.18.0.0/16", "172.19.0.0/16"]
subnets_id = ["subnet-123", "subnet-456"]
I want to associate each rule CIDR with both subnets. But my current code is only associating 1 subnet with 1 CIDR. I am not able to figure out how to solve it.
Update:
I modified code according to @Ervin's answer but getting following error.
Error: error creating client VPN route "cvpn-endpoint-0e72bbde5,subnet-0fefd,172.19.0.0/16": ConcurrentMutationLimitExceeded: Cannot initiate another change for this endpoint at this time. Please try again later.
│ status code: 400, request id: 2663f630-54a1-4a22-a093-d04425204cf5
│
│ with module.VPN-Endpoint.aws_ec2_client_vpn_route.vpn_route["5"],
│ on modules\VPN-Endpoint\rule_route.tf line 14, in resource "aws_ec2_client_vpn_route" "vpn_route":
│ 14: resource "aws_ec2_client_vpn_route" "vpn_route" {
I guess it is because each route should be created one by one. So I modified my code as below by adding time sleep:
resource "time_sleep" "wait_30_seconds" {
create_duration = "30s"
}
resource "aws_ec2_client_vpn_route" "vpn_route" {
depends_on = [
aws_ec2_client_vpn_network_association.vpn_subnets,
time_sleep.wait_30_seconds
]
for_each = { for index, pair in setproduct(var.rule, var.subnets_id) : index => pair }
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.vpn.id
destination_cidr_block = each.value[0]
target_vpc_subnet_id = each.value[1]
}
But it is still not working. Is there any workaround for this?
You can accomplish this by using setproduct
. This function computes the Cartesian-product for the elements of the two lists.
resource "aws_ec2_client_vpn_route" "vpn_route" {
depends_on = [
aws_ec2_client_vpn_network_association.vpn_subnets
]
for_each = { for index, pair in setproduct(var.rule, var.subnets_id) : index => pair }
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.vpn.id
destination_cidr_block = each.value[0]
target_vpc_subnet_id = each.value[1]
}