简体   繁体   中英

How to use nested count in terraform for creating VPN endpoint routes?

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 & su.net_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 su.nets. But my current code is only associating 1 su.net 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]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM