将 ECS 服务转换为 cloudformation
Translate ECS service to cloudformation
我正在尝试将手动创建的服务转换为 cloudformation 模板,但我不断收到错误。
已经使用 UI 创建了任务定义,因为它需要一些特定角色
这个模板给我:Classic Load Balancers are not supported with Fargate
ServicesSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for cluster services
VpcId: !Ref 'VPC'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId: !Ref "PublicLoadBalancerSG"
ServiceStaging:
Type: AWS::ECS::Service
Properties:
ServiceName: pouch-svc-staging
TaskDefinition: pouch-td-staging:4
Cluster: !Ref 'ClusterECS'
DesiredCount: 2
SchedulingStrategy: REPLICA
LaunchType: FARGATE
EnableECSManagedTags: true
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups:
- !Ref ServicesSG
LoadBalancers:
- ContainerName: pouch-image-staging
LoadBalancerName: !Ref 'LoadBalancerName'
ContainerPort: 3100
更新:这是修改后的完整 cloudformation 模板,没有一些评论明确指出的负载均衡器名称
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC, subnets and external, public facing load balancer, for forwarding public traffic to containers
Parameters:
LoadBalancerName:
Type: String
Default: pouch-api-elb
ClusterName:
Type: String
Default: pouch-api-cluster
Mappings:
SubnetConfig:
VPC:
CIDR: '172.16.0.0/16'
PublicOne:
CIDR: '172.16.0.0/24'
PublicTwo:
CIDR: '172.16.1.0/24'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
PublicSubnetOne:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
MapPublicIpOnLaunch: true
PublicSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
MapPublicIpOnLaunch: true
InternetGateway:
Type: AWS::EC2::InternetGateway
GatewayAttachement:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref 'VPC'
InternetGatewayId: !Ref 'InternetGateway'
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
PublicRoute:
Type: AWS::EC2::Route
DependsOn: GatewayAttachement
Properties:
RouteTableId: !Ref 'PublicRouteTable'
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
PublicSubnetOneRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetOne
RouteTableId: !Ref PublicRouteTable
PublicSubnetTwoRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetTwo
RouteTableId: !Ref PublicRouteTable
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId: !Ref 'VPC'
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: -1
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Ref 'LoadBalancerName'
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: "30"
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups: [!Ref "PublicLoadBalancerSG"]
TargetGroupStaging:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
TargetType: ip
UnhealthyThresholdCount: 2
VpcId: !Ref 'VPC'
TargetGroupProduction:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
TargetType: ip
UnhealthyThresholdCount: 2
VpcId: !Ref 'VPC'
ListenerRuleProduction:
Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref "TargetGroupProduction"
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- /production/*
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 100
ListenerRuleStaging:
Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref "TargetGroupStaging"
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- /staging/*
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 50
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: "redirect"
RedirectConfig:
Protocol: "#{protocol}"
Port: "#{port}"
Host: "#{host}"
Path: "/production/"
StatusCode: "HTTP_301"
LoadBalancerArn: !Ref "PublicLoadBalancer"
Port: 80
Protocol: HTTP
ClusterECS:
Type: AWS::ECS::Cluster
DependsOn: PublicLoadBalancerListener
Properties:
ClusterName: !Ref 'ClusterName'
CapacityProviders:
- FARGATE
ServicesSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for cluster services
VpcId: !Ref 'VPC'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId: !Ref "PublicLoadBalancerSG"
ServiceStaging:
Type: AWS::ECS::Service
Properties:
ServiceName: pouch-svc-staging
TaskDefinition: pouch-td-staging:4
Cluster: !Ref 'ClusterECS'
DesiredCount: 2
SchedulingStrategy: REPLICA
LaunchType: FARGATE
EnableECSManagedTags: true
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups:
- !Ref ServicesSG
LoadBalancers:
- ContainerName: pouch-image-staging
TargetGroupArn: !Ref 'TargetGroupStaging'
ContainerPort: 3100
ServiceProduction:
Type: AWS::ECS::Service
Properties:
ServiceName: pouch-svc-production
TaskDefinition: pouch-td-production:4
Cluster: !Ref 'ClusterECS'
DesiredCount: 2
SchedulingStrategy: REPLICA
LaunchType: FARGATE
EnableECSManagedTags: true
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups:
- !Ref ServicesSG
LoadBalancers:
- ContainerName: pouch-image-production
TargetGroupArn: !Ref 'TargetGroupProduction'
ContainerPort: 3100
Outputs:
VpcId:
Description: The ID of the VPC that this stack is deployed in
Value: !Ref 'VPC'
PublicSubnetOne:
Description: Public subnet one
Value: !Ref 'PublicSubnetOne'
PublicSubnetTwo:
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
ExternalUrl:
Description: The url of the external load balancer
Value: !Sub http://${PublicLoadBalancer.DNSName}
现在我收到“带有 targetGroupArn arn:aws:elasticloadbalancing 的目标组:...:targetgroup/pouch-Targe-XFJ4AI7HCF6G/f2a665925da27326 没有关联的负载均衡器”
我还不能添加评论。我认为以下 link 可以帮助解决问题 Fargate 不支持 Classic Load Balancer
AWS Load Balancing multiple ports for an ECS Service with Fargate
来自官方AWS documentation:
负载均衡器名称
与 Amazon ECS 服务或任务集关联的负载均衡器的名称。
负载均衡器名称仅在使用 Classic Load Balancer 时指定。如果您使用的是应用程序负载均衡器或网络负载均衡器,则应省略负载均衡器名称参数。
这意味着您不应在 CloudFormation 模板中指定负载均衡器的名称,因为您使用的是 Fargate,因此,请勿使用经典负载均衡器。
此外,在您的位置,我会考虑使用 Former2 之类的东西。这是一个很棒的工具,可以为您生成 CloudFormation 模板。您可以扫描您的帐户,选择要为其创建模板的服务。不过,为了使用它,您需要一个访问密钥和一个秘密密钥,因此请考虑创建一个具有只读权限的 IAM 用户。
编辑以涵盖有关目标组的第二个错误:
The Amazon ECS service requires an explicit dependency on the
Application Load Balancer listener rule and the Application Load
Balancer listener. This prevents the service from starting before the
listener is ready.
可能 AWS::ECS::Service
在将目标组添加到负载均衡器之前尝试附加到目标组。为了解决这个问题,您应该在您的服务中添加一个依赖项,如下所示:
Type: AWS::ECS::Service
DependsOn: Listener # Add exact listener name, depending on the service
Properties:
这应该有助于解决问题。
我正在尝试将手动创建的服务转换为 cloudformation 模板,但我不断收到错误。
已经使用 UI 创建了任务定义,因为它需要一些特定角色
这个模板给我:Classic Load Balancers are not supported with Fargate
ServicesSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for cluster services
VpcId: !Ref 'VPC'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId: !Ref "PublicLoadBalancerSG"
ServiceStaging:
Type: AWS::ECS::Service
Properties:
ServiceName: pouch-svc-staging
TaskDefinition: pouch-td-staging:4
Cluster: !Ref 'ClusterECS'
DesiredCount: 2
SchedulingStrategy: REPLICA
LaunchType: FARGATE
EnableECSManagedTags: true
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups:
- !Ref ServicesSG
LoadBalancers:
- ContainerName: pouch-image-staging
LoadBalancerName: !Ref 'LoadBalancerName'
ContainerPort: 3100
更新:这是修改后的完整 cloudformation 模板,没有一些评论明确指出的负载均衡器名称
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC, subnets and external, public facing load balancer, for forwarding public traffic to containers
Parameters:
LoadBalancerName:
Type: String
Default: pouch-api-elb
ClusterName:
Type: String
Default: pouch-api-cluster
Mappings:
SubnetConfig:
VPC:
CIDR: '172.16.0.0/16'
PublicOne:
CIDR: '172.16.0.0/24'
PublicTwo:
CIDR: '172.16.1.0/24'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
EnableDnsSupport: true
EnableDnsHostnames: true
CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR']
PublicSubnetOne:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR']
MapPublicIpOnLaunch: true
PublicSubnetTwo:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: {Ref: 'AWS::Region'}
VpcId: !Ref 'VPC'
CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR']
MapPublicIpOnLaunch: true
InternetGateway:
Type: AWS::EC2::InternetGateway
GatewayAttachement:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref 'VPC'
InternetGatewayId: !Ref 'InternetGateway'
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref 'VPC'
PublicRoute:
Type: AWS::EC2::Route
DependsOn: GatewayAttachement
Properties:
RouteTableId: !Ref 'PublicRouteTable'
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
PublicSubnetOneRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetOne
RouteTableId: !Ref PublicRouteTable
PublicSubnetTwoRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetTwo
RouteTableId: !Ref PublicRouteTable
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Access to the public facing load balancer
VpcId: !Ref 'VPC'
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: -1
PublicLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Ref 'LoadBalancerName'
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: "30"
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups: [!Ref "PublicLoadBalancerSG"]
TargetGroupStaging:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
TargetType: ip
UnhealthyThresholdCount: 2
VpcId: !Ref 'VPC'
TargetGroupProduction:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
TargetType: ip
UnhealthyThresholdCount: 2
VpcId: !Ref 'VPC'
ListenerRuleProduction:
Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref "TargetGroupProduction"
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- /production/*
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 100
ListenerRuleStaging:
Type: "AWS::ElasticLoadBalancingV2::ListenerRule"
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref "TargetGroupStaging"
Conditions:
- Field: path-pattern
PathPatternConfig:
Values:
- /staging/*
ListenerArn: !Ref PublicLoadBalancerListener
Priority: 50
PublicLoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: "redirect"
RedirectConfig:
Protocol: "#{protocol}"
Port: "#{port}"
Host: "#{host}"
Path: "/production/"
StatusCode: "HTTP_301"
LoadBalancerArn: !Ref "PublicLoadBalancer"
Port: 80
Protocol: HTTP
ClusterECS:
Type: AWS::ECS::Cluster
DependsOn: PublicLoadBalancerListener
Properties:
ClusterName: !Ref 'ClusterName'
CapacityProviders:
- FARGATE
ServicesSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for cluster services
VpcId: !Ref 'VPC'
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 0
ToPort: 65535
SourceSecurityGroupId: !Ref "PublicLoadBalancerSG"
ServiceStaging:
Type: AWS::ECS::Service
Properties:
ServiceName: pouch-svc-staging
TaskDefinition: pouch-td-staging:4
Cluster: !Ref 'ClusterECS'
DesiredCount: 2
SchedulingStrategy: REPLICA
LaunchType: FARGATE
EnableECSManagedTags: true
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups:
- !Ref ServicesSG
LoadBalancers:
- ContainerName: pouch-image-staging
TargetGroupArn: !Ref 'TargetGroupStaging'
ContainerPort: 3100
ServiceProduction:
Type: AWS::ECS::Service
Properties:
ServiceName: pouch-svc-production
TaskDefinition: pouch-td-production:4
Cluster: !Ref 'ClusterECS'
DesiredCount: 2
SchedulingStrategy: REPLICA
LaunchType: FARGATE
EnableECSManagedTags: true
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DeploymentCircuitBreaker:
Enable: false
Rollback: false
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- !Ref PublicSubnetOne
- !Ref PublicSubnetTwo
SecurityGroups:
- !Ref ServicesSG
LoadBalancers:
- ContainerName: pouch-image-production
TargetGroupArn: !Ref 'TargetGroupProduction'
ContainerPort: 3100
Outputs:
VpcId:
Description: The ID of the VPC that this stack is deployed in
Value: !Ref 'VPC'
PublicSubnetOne:
Description: Public subnet one
Value: !Ref 'PublicSubnetOne'
PublicSubnetTwo:
Description: Public subnet two
Value: !Ref 'PublicSubnetTwo'
ExternalUrl:
Description: The url of the external load balancer
Value: !Sub http://${PublicLoadBalancer.DNSName}
现在我收到“带有 targetGroupArn arn:aws:elasticloadbalancing 的目标组:...:targetgroup/pouch-Targe-XFJ4AI7HCF6G/f2a665925da27326 没有关联的负载均衡器”
我还不能添加评论。我认为以下 link 可以帮助解决问题 Fargate 不支持 Classic Load Balancer
AWS Load Balancing multiple ports for an ECS Service with Fargate
来自官方AWS documentation:
负载均衡器名称 与 Amazon ECS 服务或任务集关联的负载均衡器的名称。
负载均衡器名称仅在使用 Classic Load Balancer 时指定。如果您使用的是应用程序负载均衡器或网络负载均衡器,则应省略负载均衡器名称参数。
这意味着您不应在 CloudFormation 模板中指定负载均衡器的名称,因为您使用的是 Fargate,因此,请勿使用经典负载均衡器。
此外,在您的位置,我会考虑使用 Former2 之类的东西。这是一个很棒的工具,可以为您生成 CloudFormation 模板。您可以扫描您的帐户,选择要为其创建模板的服务。不过,为了使用它,您需要一个访问密钥和一个秘密密钥,因此请考虑创建一个具有只读权限的 IAM 用户。
编辑以涵盖有关目标组的第二个错误:
The Amazon ECS service requires an explicit dependency on the Application Load Balancer listener rule and the Application Load Balancer listener. This prevents the service from starting before the listener is ready.
可能 AWS::ECS::Service
在将目标组添加到负载均衡器之前尝试附加到目标组。为了解决这个问题,您应该在您的服务中添加一个依赖项,如下所示:
Type: AWS::ECS::Service
DependsOn: Listener # Add exact listener name, depending on the service
Properties:
这应该有助于解决问题。