Conditionally create a resource based on terraform_remote_state

Hi,

I have two resources, and one is dependent of the other.

resource "aws_vpc_peering_connection" "test_to_prod" {
  count       = terraform.workspace == "test" ? 1 : 0
  peer_vpc_id = data.terraform_remote_state.network_prod.outputs.vpc_id
  vpc_id      = module.vpc.vpc_id
  auto_accept = false

  requester {
    allow_remote_vpc_dns_resolution = true
  }
}

# Accepter's side of the connection.
resource "aws_vpc_peering_connection_accepter" "test_to_prod" {
  count                     = terraform.workspace == "prod" ? 1 : 0
  vpc_peering_connection_id = data.terraform_remote_state.network_test.outputs.vpc_peering_request_id

  accepter {
    allow_remote_vpc_dns_resolution = true
  }
}

However, terraform plan will fail for the prod workspace, because data.terraform_remote_state.network_test.outputs.vpc_peering_request_id doesn’t exist in test yet:

│ Error: Unsupported attribute
│
│   on peering.tf line 72, in resource "aws_vpc_peering_connection_accepter" "test_to_prod":
│   72:   count                     = terraform.workspace == "prod" ? 1 : 0
│     ├────────────────
│     │ data.terraform_remote_state.network_test.outputs is object with 7 attributes
│
│ This object does not have an attribute named "vpc_peering_request_id".

Is there a way of not creating aws_vpc_peering_connection_accepter.test_to_prod if data.terraform_remote_state.network_test.outputs.vpc_peering_request_id doesn’t exist?

Edit:

Looks like TF is accepting this condition:

data "aws_vpc_peering_connection" "test" {
  depends_on = [
    aws_vpc_peering_connection.test_to_prod
  ]
  count                     = terraform.workspace == "test" ? 1 : 0
  vpc_id          = module.vpc.vpc_id
  peer_vpc_id     = data.terraform_remote_state.network_prod.outputs.vpc_id

  filter {
    name   = "tag:Name"
    values = ["peering-from-test-to-prod"]
  }

  filter {
    name   = "tag:Side"
    values = ["Requester"]
  }
}

resource "aws_vpc_peering_connection" "test_to_prod" {
  count       = terraform.workspace == "test" ? 1 : 0
  peer_vpc_id = data.terraform_remote_state.network_prod.outputs.vpc_id
  vpc_id      = module.vpc.vpc_id
  auto_accept = false

  requester {
    allow_remote_vpc_dns_resolution = true
  }
}

# Accepter's side of the connection.
resource "aws_vpc_peering_connection_accepter" "test_to_prod" {
  terraform.workspace == "prod" && data.aws_vpc_peering_connection.test[0].id != "null" ? 1 : 0
  vpc_peering_connection_id = data.terraform_remote_state.network_test.outputs.vpc_peering_request_id

  accepter {
    allow_remote_vpc_dns_resolution = true
  }
}

However, data.aws_vpc_peering_connection.test[0].id doesn’t exist yet in the test workspace, so TF is complaining:

│ Error: no matching EC2 VPC Peering Connection found
│
│   with data.aws_vpc_peering_connection.test[0],
│   on peering.tf line 31, in data "aws_vpc_peering_connection" "test":
│   31: data "aws_vpc_peering_connection" "test" {
│
╵
Releasing state lock. This may take a few moments...
make: *** [plan] Error 1

Hmm, looks like it’s working now. But please, let me know if there is any other (better) way to achieve this.

resource "aws_vpc_peering_connection" "test_to_prod" {
  count         = terraform.workspace == "test" ? 1 : 0
  peer_owner_id = local.env.prod.aws_account_number
  peer_vpc_id   = data.terraform_remote_state.network_prod.outputs.vpc_id
  vpc_id        = module.vpc.vpc_id
  auto_accept   = false

  tags = merge({
    Name        = "peering-from-${terraform.workspace}-to-prod"
    Side        = "Requester"
    Environment = terraform.workspace
  }, var.tags)
}

# Accepter's side of the connection.
resource "aws_vpc_peering_connection_accepter" "test_to_prod" {
  depends_on                = [aws_vpc_peering_connection.test_to_prod]
  count                     = terraform.workspace == "prod" && data.terraform_remote_state.network_test.outputs.vpc_peering_request_id != "" ? 1 : 0
  vpc_peering_connection_id = data.terraform_remote_state.network_test.outputs.vpc_peering_request_id
  auto_accept               = true

  accepter {
    allow_remote_vpc_dns_resolution = true
  }

  tags = merge({
    Side        = "Accepter"
    Environment = terraform.workspace
  }, var.tags)
}

resource "aws_route" "vpc_peering_test_to_prod" {
  depends_on                = [aws_vpc_peering_connection.test_to_prod]
  count                     = terraform.workspace == "test" ? length(data.aws_route_tables.rts_private.ids) : 0
  route_table_id            = data.aws_route_tables.rts_private.ids[count.index]
  destination_cidr_block    = data.terraform_remote_state.network_prod.outputs.database_subnets_cidr_blocks[count.index]
  vpc_peering_connection_id = one(aws_vpc_peering_connection.test_to_prod[*].id)
}

resource "aws_route" "vpc_peering_prod_to_test" {
  depends_on                = [aws_vpc_peering_connection_accepter.test_to_prod]
  count                     = terraform.workspace == "prod" && data.terraform_remote_state.network_test.outputs.vpc_peering_request_id != "" ? length(data.aws_route_tables.rts_private.ids) : 0
  route_table_id            = data.aws_route_tables.rts_private.ids[count.index]
  destination_cidr_block    = data.terraform_remote_state.network_test.outputs.private_subnets_cidr_blocks[count.index]
  vpc_peering_connection_id = data.terraform_remote_state.network_test.outputs.vpc_peering_request_id
}