From ff77fe0c08af072407fc19aa9bbc0434de248934 Mon Sep 17 00:00:00 2001 From: "Sven (AAMOS AI)" Date: Tue, 11 Aug 2026 21:35:31 +0700 Subject: [PATCH] infra: add route53, ses, acm, cloudfront and dns records --- infrastructure/terraform/dns_web.tf | 184 ++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 infrastructure/terraform/dns_web.tf diff --git a/infrastructure/terraform/dns_web.tf b/infrastructure/terraform/dns_web.tf new file mode 100644 index 0000000..5a8fe6e --- /dev/null +++ b/infrastructure/terraform/dns_web.tf @@ -0,0 +1,184 @@ +resource "aws_route53_zone" "main" { + name = "cibello.app" + tags = { + Name = "cibello-app-zone" + } +} + +resource "aws_ses_configuration_set" "main" { + name = "cibello-prod" +} + +resource "aws_ses_domain_identity" "main" { + domain = "mail.cibello.app" +} + +resource "aws_ses_domain_dkim" "main" { + domain = aws_ses_domain_identity.main.domain +} + +resource "aws_route53_record" "ses_verification" { + zone_id = aws_route53_zone.main.zone_id + name = "_amazonses.${aws_ses_domain_identity.main.domain}" + type = "TXT" + ttl = 300 + records = [aws_ses_domain_identity.main.verification_token] +} + +resource "aws_route53_record" "ses_dkim" { + count = 3 + zone_id = aws_route53_zone.main.zone_id + name = "${aws_ses_domain_dkim.main.dkim_tokens[count.index]}._domainkey.${aws_ses_domain_identity.main.domain}" + type = "CNAME" + ttl = 300 + records = ["${aws_ses_domain_dkim.main.dkim_tokens[count.index]}.dkim.amazonses.com"] +} + +resource "aws_acm_certificate" "main" { + provider = aws.us_east_1 + domain_name = "cibello.app" + subject_alternative_names = ["www.cibello.app"] + validation_method = "DNS" + + lifecycle { + create_before_destroy = true + } + + tags = { + Name = "cibello-prod-cert" + } +} + +resource "aws_route53_record" "cert_validation" { + for_each = { + for dvo in aws_acm_certificate.main.domain_validation_options : dvo.domain_name => { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } + + zone_id = aws_route53_zone.main.zone_id + name = each.value.name + type = each.value.type + ttl = 300 + records = [each.value.record] +} + +resource "aws_cloudfront_origin_access_control" "web" { + name = "cibello-prod-oac" + description = "OAC for cibello-web" + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "SigV4" +} + +resource "aws_s3_bucket_policy" "web" { + bucket = aws_s3_bucket.web.id + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "AllowCloudFrontOAC" + Effect = "Allow" + Principal = { + Service = "cloudfront.amazonaws.com" + } + Action = "s3:GetObject" + Resource = "${aws_s3_bucket.web.arn}/*" + Condition = { + StringEquals = { + "AWS:SourceArn" = aws_cloudfront_distribution.main.arn + } + } + } + ] + }) +} + +resource "aws_cloudfront_distribution" "main" { + enabled = true + is_ipv6_enabled = true + default_root_object = "index.html" + aliases = ["cibello.app", "www.cibello.app"] + + origin { + domain_name = aws_s3_bucket.web.bucket_regional_domain_name + origin_id = "cibello-web" + origin_access_control_id = aws_cloudfront_origin_access_control.web.id + } + + default_cache_behavior { + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD"] + target_origin_id = "cibello-web" + viewer_protocol_policy = "redirect-to-https" + forwarded_values { + query_string = false + cookies { + forward = "none" + } + } + min_ttl = 0 + default_ttl = 3600 + max_ttl = 86400 + } + + price_class = "PriceClass_100" + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + viewer_certificate { + acm_certificate_arn = aws_acm_certificate.main.arn + ssl_support_method = "sni-only" + minimum_protocol_version = "TLSv1.2_2021" + } + + tags = { + Name = "cibello-prod-cdn" + } +} + +resource "aws_route53_record" "apex" { + zone_id = aws_route53_zone.main.zone_id + name = "cibello.app" + type = "A" + + alias { + name = aws_cloudfront_distribution.main.domain_name + zone_id = aws_cloudfront_distribution.main.hosted_zone_id + evaluate_target_health = false + } +} + +resource "aws_route53_record" "www" { + zone_id = aws_route53_zone.main.zone_id + name = "www.cibello.app" + type = "A" + + alias { + name = aws_cloudfront_distribution.main.domain_name + zone_id = aws_cloudfront_distribution.main.hosted_zone_id + evaluate_target_health = false + } +} + +resource "aws_route53_record" "api" { + zone_id = aws_route53_zone.main.zone_id + name = "api.cibello.app" + type = "A" + ttl = 300 + records = [aws_eip.app.public_ip] +} + +resource "aws_route53_record" "admin" { + zone_id = aws_route53_zone.main.zone_id + name = "admin.cibello.app" + type = "A" + ttl = 300 + records = [aws_eip.app.public_ip] +}