I have 4-6 or may be n number of projects in aws environment that share the base domain. I am trying to create separate cloudfront distribution, api gateway and cognito user pool each for each project.
For api gateway I already had a module that was creating gateway for one project earlier in the environment now I have put a loop in the calling module of modules/api to create api gateway for each project in this list
var.projects= [{"project": "project1", "version": "v1"}, {"project": "project2", "version": "v1"}, {"project": "project3", "version": "v2"}, {"project": "project4", "version": "v3"}]
For first time apply terraform configurations work fine but when I add a new projects (example project5 and project6) to the above var.project list it fails with this error for all projects 1 to 4
Error: creating Route 53 Record: InvalidChangeBatch: [Tried to create resource record set [name='xyz-api.project4.domain.com', type='A'] but it already exists] status code: 400, request id: b59a889a-c920-4fec-a709-e8b489b57613
with module.api["project4"].aws_route53_record.exampleon modules/api/route53.tf line 16, in resource "aws_route53_record" "example":
resource "aws_route53_record" "example" {
Issue is why Terraform tries to apply api module for existing project1 to project4 when they are already there and fails.
Is it the for_each statement that tries to recreate the resource instance with every apply when the list var.projects is updated, even if it is already created earlier by Terraform?
Code for resource aws_route53_record code under modules/api/route53.tf
resource "aws_api_gateway_domain_name" "this" {
domain_name = "${var.dns_name}.${var.domain}"
regional_certificate_arn = var.certificate_validation
endpoint_configuration {
types = ["REGIONAL"]
}
}
resource "aws_route53_record" "example" {
name = aws_api_gateway_domain_name.this.domain_name
type = "A"
zone_id = data.aws_route53_zone.public.id
alias {
evaluate_target_health = true
name = aws_api_gateway_domain_name.this.regional_domain_name
zone_id = aws_api_gateway_domain_name.this.regional_zone_id
}
}
Calling module
locals {
projectList = {
for pv in var.project_version : pv.project => {
project_name = "${pv.project}"
}
}
}
module "api" {
source = "./modules/api"
for_each = local.projectList
env = var.env
balancer_uri = "${var.dns_name}.${var.domain}"
domain = "${var.domain}"
dns_name = "xyz-api-${each.value.project_name}"
sm_api_host = "sm-portal-api.${var.domain}"
app = each.value.project_name
subnets = [module.vpc.private_subnets[0], module.vpc.private_subnets[1], module.vpc.private_subnets[2]]
vpc_id = module.vpc.vpc_id
internal_alb_arn = aws_lb.alb_internal.id
certificate_validation = aws_acm_certificate_validation.example.certificate_arn
user_identifier_lambda_arn = aws_lambda_function.User_Identifier.invoke_arn
lambdas = {
post_confirm = module.lambda.identity_lambda
}
cognito = {
create_auth_challenge = aws_lambda_function.Cognito_Create_Auth.arn
define_auth_challenge = aws_lambda_function.Cognito_Define_Auth.arn
pre_sign_up = aws_lambda_function.Cognito_Pre_Sign_Up.arn
verify_auth_challenge_response = aws_lambda_function.Cognito_Verify_Auth.arn
pre_authentication = aws_lambda_function.Cognito_Pre_Auth.arn
post_authentication = aws_lambda_function.Cognito_Post_Auth.arn
}
depends_on = [
aws_lb.alb_internal,
aws_lb_target_group.alb-tg,
aws_alb_listener.internal_http_listener,
aws_lambda_function.Cognito_Create_Auth,
aws_lambda_function.Cognito_Define_Auth,
aws_lambda_function.Cognito_Pre_Sign_Up,
aws_lambda_function.Cognito_Verify_Auth,
module.vpc
]
}