使用Terraform部署AWS负载均衡与SSL证书时验证超时求助
AWS ACM证书验证超时并出现连接重置错误的解决方法
问题描述
使用Terraform在AWS上配置负载均衡器和SSL证书时,证书验证耗时超20分钟,最终出现连接重置错误。相关日志、配置文件及错误信息如下:
验证日志片段
module.lb.aws_acm_certificate_validation.cert-validation: Still creating... [11m20s elapsed] module.lb.aws_acm_certificate_validation.cert-validation: Still creating... [11m30s elapsed] ... module.lb.aws_acm_certificate_validation.cert-validation: Still creating... [14m40s elapsed]
main.tf 文件内容
provider "aws" { profile = "myprofile" region = var.region } module "vpc" { source = "./modules/vpc" } module "sg" { source = "./modules/sg" vpc_id = module.vpc.vpc_id } resource "aws_instance" "public_server" { ami = lookup(var.ami, var.region) security_groups = [module.sg.SG_id] subnet_id = module.vpc.public_subnet_ids[count.index] instance_type = var.instance_type associate_public_ip_address = true provisioner "local-exec" { command = "echo 'instance_${count.index + 1}_IP = ${self.public_ip}' > ansible-folder/host-inventory" } tags = { Name : "public_server_${count.index + 1}" } key_name = aws_key_pair.key-pair.id count = 3 } resource "tls_private_key" "pk" { algorithm = "RSA" rsa_bits = 4096 } resource "aws_key_pair" "key-pair" { key_name = "myKey" public_key = tls_private_key.pk.public_key_openssh provisioner "local-exec" { command = "echo '${tls_private_key.pk.private_key_pem}' > .aws-key/myKey.pem" } } module "lb" { source = "./modules/lb" vpc_id = module.vpc.vpc_id SG_id = module.sg.SG_id subnets = [for subnet in module.vpc.public_subnet_ids : subnet] instance_id_1 = aws_instance.public_server[0].id instance_id_2 = aws_instance.public_server[1].id instance_id_3 = aws_instance.public_server[2].id }
负载均衡模块代码(含Route53与证书配置)
resource "aws_lb_target_group" "target-group" { name = "altschool-lb-target-group" port = 80 protocol = "HTTP" target_type = "instance" vpc_id = var.vpc_id health_check { enabled = true path = "/" protocol = "HTTP" matcher = "200" healthy_threshold = 3 unhealthy_threshold = 2 timeout = 3 interval = 10 } } resource "aws_lb_target_group_attachment" "public-target-attachment1" { target_group_arn = aws_lb_target_group.target-group.arn target_id = var.instance_id_1 port = 80 } resource "aws_lb_target_group_attachment" "public-target-attachment2" { target_group_arn = aws_lb_target_group.target-group.arn target_id = var.instance_id_2 port = 80 } resource "aws_lb_target_group_attachment" "public-target-attachment3" { target_group_arn = aws_lb_target_group.target-group.arn target_id = var.instance_id_3 port = 80 } resource "aws_lb" "altschool-lb" { name = "altschool-lb" internal = false load_balancer_type = "application" security_groups = [var.SG_id] subnets = var.subnets tags = { Environment = "altschool-lb" } } resource "aws_lb_listener" "alb-http-listener" { load_balancer_arn = aws_lb.altschool-lb.arn port = 80 protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.target-group.arn } } resource "aws_route53_zone" "hosted-zone" { name = "altschoolminiproject.software" tags = { Environment = "terraform-test" } } resource "aws_route53_record" "terraform-test" { zone_id = aws_route53_zone.hosted-zone.zone_id name = "terraform-test.altschoolminiproject.software" type = "A" alias { name = aws_lb.altschool-lb.dns_name zone_id = aws_lb.altschool-lb.zone_id evaluate_target_health = true } } resource "aws_acm_certificate" "alt-cert" { domain_name = "altschoolminiproject.software" subject_alternative_names = ["terraform-test.altschoolminiproject.software"] validation_method = "DNS" lifecycle { create_before_destroy = true } tags = { Environment = "altschool-certificate" } } resource "aws_route53_record" "cert-record" { for_each = { for dvo in aws_acm_certificate.alt-cert.domain_validation_options : dvo.domain_name => { name = dvo.resource_record_name record = dvo.resource_record_value type = dvo.resource_record_type } } allow_overwrite = true name = each.value.name records = [each.value.record] ttl = 60 type = each.value.type zone_id = aws_route53_zone.hosted-zone.zone_id } resource "aws_acm_certificate_validation" "cert-validation" { certificate_arn = aws_acm_certificate.alt-cert.arn validation_record_fqdns = [for record in aws_route53_record.cert-record : record.fqdn] } resource "aws_alb_listener" "alb-listener-https" { depends_on = [ aws_acm_certificate.alt-cert, aws_route53_record.cert-record, aws_acm_certificate_validation.cert-validation ] load_balancer_arn = aws_lb.altschool-lb.arn port = 443 protocol = "HTTPS" certificate_arn = aws_acm_certificate.alt-cert.arn ssl_policy = "ELBSecurityPolicy-2016-08" default_action { target_group_arn = aws_lb_target_group.target-group.arn type = "forward" } } resource "aws_lb_listener" "alb-listener-http" { load_balancer_arn = aws_lb.altschool-lb.arn port = "80" protocol = "HTTP" default_action { type = "redirect" redirect { port = "443" protocol = "HTTPS" status_code = "HTTP_301" } } }
最终错误信息
| module.lb.aws_acm_certificate_validation.cert-validation: Still creating... [30m15s elapsed] │ Error: waiting for ACM Certificate (arn:aws:acm:us-east-1:732887255406:certificate/17f19b6e-3dd2-4234-aea8-56742d1a92da) to be issued: RequestError: send request failed │ caused by: Post "acm.us-east-1.amazonaws.com": read tcp 192.168.123.111:57898->54.239.25.80:443: read: connection reset by peer │ │ with module.lb.aws_acm_certificate_validation.cert-validation
域名已在Route53中配置,需确保AWS证书能成功完成验证。
解决方案
1. 排查网络连接问题
连接重置错误多由本地到AWS ACM服务的网络限制导致:
- 检查本地防火墙、代理规则,确保允许访问
acm.us-east-1.amazonaws.com的443端口 - 切换网络环境(如从公司内网换至家用网络),排除特定网络的访问限制
- 执行
nslookup acm.us-east-1.amazonaws.com验证DNS解析是否正常
2. 延长Terraform验证超时时间
默认验证超时可能无法覆盖网络延迟场景,修改aws_acm_certificate_validation资源添加超时配置:
resource "aws_acm_certificate_validation" "cert-validation" { certificate_arn = aws_acm_certificate.alt-cert.arn validation_record_fqdns = [for record in aws_route53_record.cert-record : record.fqdn] timeouts { create = "60m" # 延长至60分钟 } }
3. 确认DNS验证记录正确性
- 登录AWS控制台进入Route53托管区域,检查是否存在ACM生成的CNAME验证记录
- 对比Terraform输出的
aws_route53_record.cert-record参数与ACM控制台显示的验证记录是否完全一致 - 执行
dig <验证记录名称> CNAME确认记录已完成DNS传播(通常需1-5分钟)
4. 简化资源依赖配置
当前aws_alb_listener.alb-listener-https的depends_on包含冗余资源,简化后:
resource "aws_alb_listener" "alb-listener-https" { depends_on = [aws_acm_certificate_validation.cert-validation] load_balancer_arn = aws_lb.altschool-lb.arn port = 443 protocol = "HTTPS" certificate_arn = aws_acm_certificate.alt-cert.arn ssl_policy = "ELBSecurityPolicy-2016-08" default_action { target_group_arn = aws_lb_target_group.target-group.arn type = "forward" } }
Terraform会自动处理证书和DNS记录的依赖关系,无需手动添加。
5. 手动触发验证或重建证书
- 若DNS记录已正确配置但验证超时,可在AWS ACM控制台手动重新触发验证流程
- 销毁现有证书资源后重新执行部署:
terraform destroy -target=module.lb.aws_acm_certificate.alt-cert terraform apply
6. 检查区域一致性
确保ACM证书所在区域与负载均衡器区域一致(日志显示当前区域为us-east-1),若负载均衡器在其他区域,需在对应区域创建ACM证书(CloudFront需在us-east-1创建证书)
内容的提问来源于stack exchange,提问作者user11631346
相关产品推荐
相关产品推荐

