无法使用 Terraform 在自定义 VPC 中创建 Elastic Beanstalk 应用程序
Cannot create an Elastic Beanstalk application in a custom VPC using Terraform
我正在尝试使用 Terraform 在自定义 VPC 的私有子网中创建 Elastic Beanstalk 应用程序。我遇到的问题是创建超时。
Error:
Error waiting for Elastic Beanstalk Environment (e-xxxxxxxxx) to become ready: 2 errors occurred:
- 2021-01-22 16:37:56.664 +0000 UTC (e-xxxxxxxxx) : Stack named 'awseb-e-xxxxxxxxx-stack' aborted operation. Current state: 'CREATE_FAILED' Reason: The following resource(s) failed to create: [AWSEBInstanceLaunchWaitCondition].
- 2021-01-22 16:37:56.791 +0000 UTC (e-xxxxxxxxx) : The EC2 instances failed to communicate with AWS Elastic Beanstalk, either because of configuration problems with the VPC or a failed EC2 instance. Check your VPC configuration and try launching the environment again.
我想我缺少从 VPC 到外部的连接,但我不确定是什么。
我尝试添加一些 aws_vpc_endpoint
资源:
resource "aws_vpc" "main" {
cidr_block = "10.16.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_security_group" "elasticbeanstalk_vpc_endpoint" {
name = "elasticbeanstalk-vpc-endpoint"
vpc_id = aws_vpc.main.id
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
}
resource "aws_vpc_endpoint" "elasticbeanstalk" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.elasticbeanstalk"
security_group_ids = [
aws_security_group.elasticbeanstalk_vpc_endpoint.id,
]
vpc_endpoint_type = "Interface"
}
resource "aws_security_group" "ec2_vpc_endpoint" {
name = "ec2-vpc-endpoint"
vpc_id = aws_vpc.main.id
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
}
resource "aws_vpc_endpoint" "ec2" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.ec2"
security_group_ids = [
aws_security_group.ec2_vpc_endpoint.id,
]
vpc_endpoint_type = "Interface"
}
EB 实例:
resource "aws_elastic_beanstalk_environment" "endpoint" {
name = "foo-env"
setting {
namespace = "aws:ec2:vpc"
name = "VPCId"
value = aws_vpc.main.vpc_id
resource = ""
}
setting {
namespace = "aws:ec2:vpc"
name = "Subnets"
value = join(",", [ aws_subnet.private_a.id, aws_subnet.private_b.id ])
resource = ""
}
setting {
namespace = "aws:ec2:vpc"
name = "ELBScheme"
value = "internal"
resource = ""
}
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "EnvironmentType"
value = "LoadBalanced"
resource = ""
}
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "LoadBalancerType"
value = "application"
resource = ""
}
setting {
namespace = "aws:elasticbeanstalk:application:environment"
name = "AWS_REGION"
value = var.aws_region
resource = ""
}
# ...
depends_on = [
aws_vpc_endpoint.ec2,
aws_vpc_endpoint.elasticbeanstalk,
]
}
这样创建的子网:
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.16.0.0/24"
availability_zone = "${var.aws_region}c"
map_public_ip_on_launch = true
}
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.16.192.0/24"
availability_zone = "${var.aws_region}a"
}
resource "aws_subnet" "private_b" {
vpc_id = aws_vpc.main.id
cidr_block = "10.16.224.0/24"
availability_zone = "${var.aws_region}b"
}
路由表:
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table_association" "private_a" {
route_table_id = aws_route_table.private.id
subnet_id = aws_subnet.private_a.id
}
resource "aws_route_table_association" "private_b" {
route_table_id = aws_route_table.private.id
subnet_id = aws_subnet.private_b.id
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table_association" "public" {
route_table_id = aws_route_table.public.id
subnet_id = aws_subnet.public.id
}
resource "aws_internet_gateway" "public" {
vpc_id = aws_vpc.main.id
}
resource "aws_route" "public_internet" {
route_table_id = aws_route_table.public.id
gateway_id = aws_internet_gateway.public.id
destination_cidr_block = "0.0.0.0/0"
}
下面列出了一些可能有助于解决您的问题的观察结果。在私有 VPC 中设置 EB 的一般指南在 aws docs.
中
观察:
aws_vpc.main.vpc_id
应该是 aws_vpc.main.id
.
默认情况下,在所有端点 private_dns_enabled
中是 false
。它应该是 true
端点才能无缝工作。您可以将以下内容添加到端点:
private_dns_enabled = true
- 您的端点未与任何子网相关联。要关联它们,您可以使用:
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
cloudformation
没有接口端点:
resource "aws_vpc_endpoint" "cloudformation" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.cloudformation"
security_group_ids = [
aws_security_group.elasticbeanstalk_vpc_endpoint.id,
]
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
private_dns_enabled = true
vpc_endpoint_type = "Interface"
}
- EB 从 S3 获取应用程序
zip
,但没有 S3 端点。对于 S3,您可以使用:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [ aws_route_table.private.id ]
}
elasticbeanstalk-healthd
没有 vpc 端点。可以使用:
resource "aws_vpc_endpoint" "elasticbeanstalk-hc" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.elasticbeanstalk-health"
security_group_ids = [
aws_security_group.elasticbeanstalk_vpc_endpoint.id,
]
private_dns_enabled = true
vpc_endpoint_type = "Interface"
}
- 如果您添加新端点,则需要在
aws_elastic_beanstalk_environment
中更新您的 depends_on
我正在尝试使用 Terraform 在自定义 VPC 的私有子网中创建 Elastic Beanstalk 应用程序。我遇到的问题是创建超时。
Error:
Error waiting for Elastic Beanstalk Environment (e-xxxxxxxxx) to become ready: 2 errors occurred:
- 2021-01-22 16:37:56.664 +0000 UTC (e-xxxxxxxxx) : Stack named 'awseb-e-xxxxxxxxx-stack' aborted operation. Current state: 'CREATE_FAILED' Reason: The following resource(s) failed to create: [AWSEBInstanceLaunchWaitCondition].
- 2021-01-22 16:37:56.791 +0000 UTC (e-xxxxxxxxx) : The EC2 instances failed to communicate with AWS Elastic Beanstalk, either because of configuration problems with the VPC or a failed EC2 instance. Check your VPC configuration and try launching the environment again.
我想我缺少从 VPC 到外部的连接,但我不确定是什么。
我尝试添加一些 aws_vpc_endpoint
资源:
resource "aws_vpc" "main" {
cidr_block = "10.16.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_security_group" "elasticbeanstalk_vpc_endpoint" {
name = "elasticbeanstalk-vpc-endpoint"
vpc_id = aws_vpc.main.id
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
}
resource "aws_vpc_endpoint" "elasticbeanstalk" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.elasticbeanstalk"
security_group_ids = [
aws_security_group.elasticbeanstalk_vpc_endpoint.id,
]
vpc_endpoint_type = "Interface"
}
resource "aws_security_group" "ec2_vpc_endpoint" {
name = "ec2-vpc-endpoint"
vpc_id = aws_vpc.main.id
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
}
resource "aws_vpc_endpoint" "ec2" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.ec2"
security_group_ids = [
aws_security_group.ec2_vpc_endpoint.id,
]
vpc_endpoint_type = "Interface"
}
EB 实例:
resource "aws_elastic_beanstalk_environment" "endpoint" {
name = "foo-env"
setting {
namespace = "aws:ec2:vpc"
name = "VPCId"
value = aws_vpc.main.vpc_id
resource = ""
}
setting {
namespace = "aws:ec2:vpc"
name = "Subnets"
value = join(",", [ aws_subnet.private_a.id, aws_subnet.private_b.id ])
resource = ""
}
setting {
namespace = "aws:ec2:vpc"
name = "ELBScheme"
value = "internal"
resource = ""
}
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "EnvironmentType"
value = "LoadBalanced"
resource = ""
}
setting {
namespace = "aws:elasticbeanstalk:environment"
name = "LoadBalancerType"
value = "application"
resource = ""
}
setting {
namespace = "aws:elasticbeanstalk:application:environment"
name = "AWS_REGION"
value = var.aws_region
resource = ""
}
# ...
depends_on = [
aws_vpc_endpoint.ec2,
aws_vpc_endpoint.elasticbeanstalk,
]
}
这样创建的子网:
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.16.0.0/24"
availability_zone = "${var.aws_region}c"
map_public_ip_on_launch = true
}
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.16.192.0/24"
availability_zone = "${var.aws_region}a"
}
resource "aws_subnet" "private_b" {
vpc_id = aws_vpc.main.id
cidr_block = "10.16.224.0/24"
availability_zone = "${var.aws_region}b"
}
路由表:
resource "aws_route_table" "private" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table_association" "private_a" {
route_table_id = aws_route_table.private.id
subnet_id = aws_subnet.private_a.id
}
resource "aws_route_table_association" "private_b" {
route_table_id = aws_route_table.private.id
subnet_id = aws_subnet.private_b.id
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table_association" "public" {
route_table_id = aws_route_table.public.id
subnet_id = aws_subnet.public.id
}
resource "aws_internet_gateway" "public" {
vpc_id = aws_vpc.main.id
}
resource "aws_route" "public_internet" {
route_table_id = aws_route_table.public.id
gateway_id = aws_internet_gateway.public.id
destination_cidr_block = "0.0.0.0/0"
}
下面列出了一些可能有助于解决您的问题的观察结果。在私有 VPC 中设置 EB 的一般指南在 aws docs.
中观察:
aws_vpc.main.vpc_id
应该是aws_vpc.main.id
.
默认情况下,在所有端点
private_dns_enabled
中是false
。它应该是true
端点才能无缝工作。您可以将以下内容添加到端点:
private_dns_enabled = true
- 您的端点未与任何子网相关联。要关联它们,您可以使用:
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
cloudformation
没有接口端点:
resource "aws_vpc_endpoint" "cloudformation" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.cloudformation"
security_group_ids = [
aws_security_group.elasticbeanstalk_vpc_endpoint.id,
]
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
private_dns_enabled = true
vpc_endpoint_type = "Interface"
}
- EB 从 S3 获取应用程序
zip
,但没有 S3 端点。对于 S3,您可以使用:
resource "aws_vpc_endpoint" "s3" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.s3"
vpc_endpoint_type = "Gateway"
route_table_ids = [ aws_route_table.private.id ]
}
elasticbeanstalk-healthd
没有 vpc 端点。可以使用:
resource "aws_vpc_endpoint" "elasticbeanstalk-hc" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.${var.aws_region}.elasticbeanstalk-health"
security_group_ids = [
aws_security_group.elasticbeanstalk_vpc_endpoint.id,
]
private_dns_enabled = true
vpc_endpoint_type = "Interface"
}
- 如果您添加新端点,则需要在
aws_elastic_beanstalk_environment
中更新您的
depends_on