Criar recursos do Amazon ECS usando o AWS CloudFormation
O Amazon ECS é integrado ao AWS CloudFormation, um serviço que pode ser usado para modelar e configurar recursos da AWS com modelos definidos por você. Dessa forma, você pode passar menos tempo criando e gerenciando recursos e infraestrutura. Com o AWS CloudFormation, é possível criar um modelo para descrever todos os recursos da AWS que você deseja, como clusters específicos do Amazon ECS. Em seguida, o AWS CloudFormation se encarrega de provisionar e configurar esses recursos para você.
Quando o AWS CloudFormation é usado, é possível reutilizar o modelo para configurar os recursos do Amazon ECS repetidamente e de forma consistente. Você descreve seus recursos uma vez e, em seguida, provisiona os mesmos recursos novamente em várias Contas da AWS e Regiões da AWS.
Modelos do AWS CloudFormation
Para provisionar e configurar recursos para o Amazon ECS e serviços relacionados, certifique-se de estar familiarizado com os modelos do AWS CloudFormation. Os modelos do AWS CloudFormation são arquivos de texto no formato JSON ou YAML que descrevem os recursos que você deseja provisionar nas pilhas do AWS CloudFormation. Se não estiver familiarizado com os formatos JSON, YAML ou ambos, poderá usar o AWS CloudFormation Designer para começar usando modelos do AWS CloudFormation. Para obter mais informações, consulte O que é o AWS CloudFormation Designer? no Guia do usuário do AWS CloudFormation.
O Amazon ECS é compatível com a criação de clusters, definições de tarefa, serviços e conjuntos de tarefas no AWS CloudFormation. Os exemplos a seguir demonstram como criar recursos com esses modelos usando a AWS CLI. Também é possível criar e gerenciar esses recursos usando o console do AWS CloudFormation. Para obter mais informações sobre como criar recursos usando o console do AWS CloudFormation, consulte o Guia do usuário do AWS CloudFormation.
Exemplos de modelos
Criar recursos do Amazon ECS usando pilhas separadas
Os exemplos a seguir mostram como criar recursos do Amazon ECS usando pilhas separadas para cada recurso.
Definições de tarefa
O modelo a seguir pode ser usado para criar uma tarefa do Fargate Linux.
- JSON
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "ECSTaskDefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ { "Command": [ "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\"" ], "EntryPoint": [ "sh", "-c" ], "Essential": true, "Image": "httpd:2.4", "LogConfiguration": { "LogDriver": "awslogs", "Options": { "awslogs-group": "/ecs/fargate-task-definition", "awslogs-region": "us-east-1", "awslogs-stream-prefix": "ecs" } }, "Name": "sample-fargate-app", "PortMappings": [ { "ContainerPort": 80, "HostPort": 80, "Protocol": "tcp" } ] } ], "Cpu": 256, "ExecutionRoleArn": "arn:aws:iam::
aws_account_id
:role/ecsTaskExecutionRole", "Family": "task-definition-cfn", "Memory": 512, "NetworkMode": "awsvpc", "RequiresCompatibilities": [ "FARGATE" ], "RuntimePlatform": { "OperatingSystemFamily": "LINUX" } } } } }- YAML
AWSTemplateFormatVersion: 2010-09-09 Resources: ECSTaskDefinition: Type: 'AWS::ECS::TaskDefinition' Properties: ContainerDefinitions: - Command: - >- /bin/sh -c "echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground" EntryPoint: - sh - '-c' Essential: true Image: 'httpd:2.4' LogConfiguration: LogDriver: awslogs Options: awslogs-group: /ecs/fargate-task-definition awslogs-region: us-east-1 awslogs-stream-prefix: ecs Name: sample-fargate-app PortMappings: - ContainerPort: 80 HostPort: 80 Protocol: tcp Cpu: 256 ExecutionRoleArn: 'arn:aws:iam::
aws_account_id
:role/ecsTaskExecutionRole' Family: task-definition-cfn Memory: 512 NetworkMode: awsvpc RequiresCompatibilities: - FARGATE RuntimePlatform: OperatingSystemFamily: LINUX
Clusters
O modelo a seguir pode ser usado para criar um cluster vazio.
- JSON
-
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "ECSCluster": { "Type": "AWS::ECS::Cluster", "Properties": { "ClusterName": "MyEmptyCluster" } } } }
- YAML
-
AWSTemplateFormatVersion: 2010-09-09 Resources: ECSCluster: Type: 'AWS::ECS::Cluster' Properties: ClusterName: MyEmptyCluster
Criar um cluster com a AMI otimizada para Amazon ECS para AL2023
Defina um cluster que usa um provedor de capacidade que executa instâncias AL2023 no Amazon EC2.
Importante
Para os IDs da AMI mais recente, consulte AMI otimizada pelo Amazon ECS, no Amazon Elastic Container Service Developer Guide.
- JSON
-
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "EC2 ECS cluster that starts out empty, with no EC2 instances yet. An ECS capacity provider automatically launches more EC2 instances as required on the fly when you request ECS to launch services or standalone tasks.", "Parameters": { "InstanceType": { "Type": "String", "Description": "EC2 instance type", "Default": "t2.medium", "AllowedValues": [ "t1.micro", "t2.2xlarge", "t2.large", "t2.medium", "t2.micro", "t2.nano", "t2.small", "t2.xlarge", "t3.2xlarge", "t3.large", "t3.medium", "t3.micro", "t3.nano", "t3.small", "t3.xlarge" ] }, "DesiredCapacity": { "Type": "Number", "Default": "0", "Description": "Number of EC2 instances to launch in your ECS cluster." }, "MaxSize": { "Type": "Number", "Default": "100", "Description": "Maximum number of EC2 instances that can be launched in your ECS cluster." }, "ECSAMI": { "Description": "The Amazon Machine Image ID used for the cluster", "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>", "Default": "/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id" }, "VpcId": { "Type": "AWS::EC2::VPC::Id", "Description": "VPC ID where the ECS cluster is launched", "Default": "vpc-1234567890abcdef0" }, "SubnetIds": { "Type": "List<AWS::EC2::Subnet::Id>", "Description": "List of subnet IDs where the EC2 instances will be launched", "Default": "subnet-021345abcdef67890" } }, "Resources": { "ECSCluster": { "Type": "AWS::ECS::Cluster", "Properties": { "ClusterSettings": [ { "Name": "containerInsights", "Value": "enabled" } ] } }, "ECSAutoScalingGroup": { "Type": "AWS::AutoScaling::AutoScalingGroup", "DependsOn": [ "ECSCluster", "EC2Role" ], "Properties": { "VPCZoneIdentifier": { "Ref": "SubnetIds" }, "LaunchTemplate": { "LaunchTemplateId": { "Ref": "ContainerInstances" }, "Version": { "Fn::GetAtt": [ "ContainerInstances", "LatestVersionNumber" ] } }, "MinSize": 0, "MaxSize": { "Ref": "MaxSize" }, "DesiredCapacity": { "Ref": "DesiredCapacity" }, "NewInstancesProtectedFromScaleIn": true }, "UpdatePolicy": { "AutoScalingReplacingUpdate": { "WillReplace": "true" } } }, "ContainerInstances": { "Type": "AWS::EC2::LaunchTemplate", "Properties": { "LaunchTemplateName": "asg-launch-template-2", "LaunchTemplateData": { "ImageId": { "Ref": "ECSAMI" }, "InstanceType": { "Ref": "InstanceType" }, "IamInstanceProfile": { "Name": { "Ref": "EC2InstanceProfile" } }, "SecurityGroupIds": [ { "Ref": "ContainerHostSecurityGroup" } ], "UserData": { "Fn::Base64": { "Fn::Sub": "#!/bin/bash -xe\n echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config\n yum install -y aws-cfn-bootstrap\n /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource ContainerInstances --configsets full_install --region ${AWS::Region} &\n" } }, "MetadataOptions": { "HttpEndpoint": "enabled", "HttpTokens": "required" } } } }, "EC2InstanceProfile": { "Type": "AWS::IAM::InstanceProfile", "Properties": { "Path": "/", "Roles": [ { "Ref": "EC2Role" } ] } }, "CapacityProvider": { "Type": "AWS::ECS::CapacityProvider", "Properties": { "AutoScalingGroupProvider": { "AutoScalingGroupArn": { "Ref": "ECSAutoScalingGroup" }, "ManagedScaling": { "InstanceWarmupPeriod": 60, "MinimumScalingStepSize": 1, "MaximumScalingStepSize": 100, "Status": "ENABLED", "TargetCapacity": 100 }, "ManagedTerminationProtection": "ENABLED" } } }, "CapacityProviderAssociation": { "Type": "AWS::ECS::ClusterCapacityProviderAssociations", "Properties": { "CapacityProviders": [ { "Ref": "CapacityProvider" } ], "Cluster": { "Ref": "ECSCluster" }, "DefaultCapacityProviderStrategy": [ { "Base": 0, "CapacityProvider": { "Ref": "CapacityProvider" }, "Weight": 1 } ] } }, "ContainerHostSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Access to the EC2 hosts that run containers", "VpcId": { "Ref": "VpcId" } } }, "EC2Role": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] }, "Path": "/", "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role", "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" ] } }, "ECSTaskExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ecs-tasks.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ], "Condition": { "ArnLike": { "aws:SourceArn": { "Fn::Sub": "arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:*" } }, "StringEquals": { "aws:SourceAccount": { "Fn::Sub": "${AWS::AccountId}" } } } } ] }, "Path": "/", "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" ] } } }, "Outputs": { "ClusterName": { "Description": "The ECS cluster into which to launch resources", "Value": "ECSCluster" }, "ECSTaskExecutionRole": { "Description": "The role used to start up a task", "Value": "ECSTaskExecutionRole" }, "CapacityProvider": { "Description": "The cluster capacity provider that the service should use to request capacity when it wants to start up a task", "Value": "CapacityProvider" } } }
- YAML
-
AWSTemplateFormatVersion: '2010-09-09' Description: EC2 ECS cluster that starts out empty, with no EC2 instances yet. An ECS capacity provider automatically launches more EC2 instances as required on the fly when you request ECS to launch services or standalone tasks. Parameters: InstanceType: Type: String Description: EC2 instance type Default: t2.medium AllowedValues: - t1.micro - t2.2xlarge - t2.large - t2.medium - t2.micro - t2.nano - t2.small - t2.xlarge - t3.2xlarge - t3.large - t3.medium - t3.micro - t3.nano - t3.small - t3.xlarge DesiredCapacity: Type: Number Default: '0' Description: Number of EC2 instances to launch in your ECS cluster. MaxSize: Type: Number Default: '100' Description: Maximum number of EC2 instances that can be launched in your ECS cluster. ECSAMI: Description: The Amazon Machine Image ID used for the cluster Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> Default: /aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id VpcId: Type: AWS::EC2::VPC::Id Description: VPC ID where the ECS cluster is launched Default: vpc-1234567890abcdef0 SubnetIds: Type: List<AWS::EC2::Subnet::Id> Description: List of subnet IDs where the EC2 instances will be launched Default: subnet-021345abcdef67890 Resources: ECSCluster: Type: AWS::ECS::Cluster Properties: ClusterSettings: - Name: containerInsights Value: enabled ECSAutoScalingGroup: Type: AWS::AutoScaling::AutoScalingGroup DependsOn: - ECSCluster - EC2Role Properties: VPCZoneIdentifier: !Ref SubnetIds LaunchTemplate: LaunchTemplateId: !Ref ContainerInstances Version: !GetAtt ContainerInstances.LatestVersionNumber MinSize: 0 MaxSize: !Ref MaxSize DesiredCapacity: !Ref DesiredCapacity NewInstancesProtectedFromScaleIn: true UpdatePolicy: AutoScalingReplacingUpdate: WillReplace: 'true' ContainerInstances: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: asg-launch-template-2 LaunchTemplateData: ImageId: !Ref ECSAMI InstanceType: !Ref InstanceType IamInstanceProfile: Name: !Ref EC2InstanceProfile SecurityGroupIds: - !Ref ContainerHostSecurityGroup UserData: !Base64 Fn::Sub: | #!/bin/bash -xe echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config yum install -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource ContainerInstances --configsets full_install --region ${AWS::Region} & MetadataOptions: HttpEndpoint: enabled HttpTokens: required EC2InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref EC2Role CapacityProvider: Type: AWS::ECS::CapacityProvider Properties: AutoScalingGroupProvider: AutoScalingGroupArn: !Ref ECSAutoScalingGroup ManagedScaling: InstanceWarmupPeriod: 60 MinimumScalingStepSize: 1 MaximumScalingStepSize: 100 Status: ENABLED TargetCapacity: 100 ManagedTerminationProtection: ENABLED CapacityProviderAssociation: Type: AWS::ECS::ClusterCapacityProviderAssociations Properties: CapacityProviders: - !Ref CapacityProvider Cluster: !Ref ECSCluster DefaultCapacityProviderStrategy: - Base: 0 CapacityProvider: !Ref CapacityProvider Weight: 1 ContainerHostSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Access to the EC2 hosts that run containers VpcId: !Ref VpcId EC2Role: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore ECSTaskExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: Service: - ecs-tasks.amazonaws.com Action: - sts:AssumeRole Condition: ArnLike: aws:SourceArn: !Sub arn:${AWS::Partition}:ecs:${AWS::Region}:${AWS::AccountId}:* StringEquals: aws:SourceAccount: !Sub ${AWS::AccountId} Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy Outputs: ClusterName: Description: The ECS cluster into which to launch resources Value: ECSCluster ECSTaskExecutionRole: Description: The role used to start up a task Value: ECSTaskExecutionRole CapacityProvider: Description: The cluster capacity provider that the service should use to request capacity when it wants to start up a task Value: CapacityProvider
Implantar um serviço.
O modelo a seguir define um serviço que usa o provedor de capacidade para solicitar capacidade do AL2023 para execução. Os contêineres serão lançados nas instâncias do AL2023 assim que se tornarem online:
- JSON
-
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "An example service that deploys in AWS VPC networking mode on EC2 capacity. Service uses a capacity provider to request EC2 instances to run on. Service runs with networking in private subnets, but still accessible to the internet via a load balancer hosted in public subnets.", "Parameters": { "VpcId": { "Type": "String", "Description": "The VPC that the service is running inside of" }, "PublicSubnetIds": { "Type": "List<AWS::EC2::Subnet::Id>", "Description": "List of public subnet ID's to put the load balancer in" }, "PrivateSubnetIds": { "Type": "List<AWS::EC2::Subnet::Id>", "Description": "List of private subnet ID's that the AWS VPC tasks are in" }, "ClusterName": { "Type": "String", "Description": "The name of the ECS cluster into which to launch capacity." }, "ECSTaskExecutionRole": { "Type": "String", "Description": "The role used to start up an ECS task" }, "CapacityProvider": { "Type": "String", "Description": "The cluster capacity provider that the service should use to request capacity when it wants to start up a task" }, "ServiceName": { "Type": "String", "Default": "web", "Description": "A name for the service" }, "ImageUrl": { "Type": "String", "Default": "public.ecr.aws/docker/library/nginx:latest", "Description": "The url of a docker image that contains the application process that will handle the traffic for this service" }, "ContainerCpu": { "Type": "Number", "Default": 256, "Description": "How much CPU to give the container. 1024 is 1 CPU" }, "ContainerMemory": { "Type": "Number", "Default": 512, "Description": "How much memory in megabytes to give the container" }, "ContainerPort": { "Type": "Number", "Default": 80, "Description": "What port that the application expects traffic on" }, "DesiredCount": { "Type": "Number", "Default": 2, "Description": "How many copies of the service task to run" } }, "Resources": { "TaskDefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "Family": "ServiceName", "Cpu": "ContainerCpu", "Memory": "ContainerMemory", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ "EC2" ], "ExecutionRoleArn": "ECSTaskExecutionRole", "ContainerDefinitions": [ { "Name": "ServiceName", "Cpu": "ContainerCpu", "Memory": "ContainerMemory", "Image": "ImageUrl", "PortMappings": [ { "ContainerPort": "ContainerPort", "HostPort": "ContainerPort" } ], "LogConfiguration": { "LogDriver": "awslogs", "Options": { "mode": "non-blocking", "max-buffer-size": "25m", "awslogs-group": "LogGroup", "awslogs-region": "AWS::Region", "awslogs-stream-prefix": "ServiceName" } } } ] } }, "Service": { "Type": "AWS::ECS::Service", "DependsOn": "PublicLoadBalancerListener", "Properties": { "ServiceName": "ServiceName", "Cluster": "ClusterName", "PlacementStrategies": [ { "Field": "attribute:ecs.availability-zone", "Type": "spread" }, { "Field": "cpu", "Type": "binpack" } ], "CapacityProviderStrategy": [ { "Base": 0, "CapacityProvider": "CapacityProvider", "Weight": 1 } ], "NetworkConfiguration": { "AwsvpcConfiguration": { "SecurityGroups": [ "ServiceSecurityGroup" ], "Subnets": "PrivateSubnetIds" } }, "DeploymentConfiguration": { "MaximumPercent": 200, "MinimumHealthyPercent": 75 }, "DesiredCount": "DesiredCount", "TaskDefinition": "TaskDefinition", "LoadBalancers": [ { "ContainerName": "ServiceName", "ContainerPort": "ContainerPort", "TargetGroupArn": "ServiceTargetGroup" } ] } }, "ServiceSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Security group for service", "VpcId": "VpcId" } }, "ServiceTargetGroup": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 6, "HealthCheckPath": "/", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 5, "HealthyThresholdCount": 2, "TargetType": "ip", "Port": "ContainerPort", "Protocol": "HTTP", "UnhealthyThresholdCount": 10, "VpcId": "VpcId", "TargetGroupAttributes": [ { "Key": "deregistration_delay.timeout_seconds", "Value": 0 } ] } }, "PublicLoadBalancerSG": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Access to the public facing load balancer", "VpcId": "VpcId", "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", "IpProtocol": -1 } ] } }, "PublicLoadBalancer": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "Scheme": "internet-facing", "LoadBalancerAttributes": [ { "Key": "idle_timeout.timeout_seconds", "Value": "30" } ], "Subnets": "PublicSubnetIds", "SecurityGroups": [ "PublicLoadBalancerSG" ] } }, "PublicLoadBalancerListener": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": "ServiceTargetGroup", "Weight": 100 } ] } } ], "LoadBalancerArn": "PublicLoadBalancer", "Port": 80, "Protocol": "HTTP" } }, "ServiceIngressfromLoadBalancer": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "Description": "Ingress from the public ALB", "GroupId": "ServiceSecurityGroup", "IpProtocol": -1, "SourceSecurityGroupId": "PublicLoadBalancerSG" } }, "LogGroup": { "Type": "AWS::Logs::LogGroup" } } }
- YAML
-
AWSTemplateFormatVersion: '2010-09-09' Description: >- An example service that deploys in AWS VPC networking mode on EC2 capacity. Service uses a capacity provider to request EC2 instances to run on. Service runs with networking in private subnets, but still accessible to the internet via a load balancer hosted in public subnets. Parameters: VpcId: Type: String Description: The VPC that the service is running inside of PublicSubnetIds: Type: 'List<AWS::EC2::Subnet::Id>' Description: List of public subnet ID's to put the load balancer in PrivateSubnetIds: Type: 'List<AWS::EC2::Subnet::Id>' Description: List of private subnet ID's that the AWS VPC tasks are in ClusterName: Type: String Description: The name of the ECS cluster into which to launch capacity. ECSTaskExecutionRole: Type: String Description: The role used to start up an ECS task CapacityProvider: Type: String Description: >- The cluster capacity provider that the service should use to request capacity when it wants to start up a task ServiceName: Type: String Default: web Description: A name for the service ImageUrl: Type: String Default: 'public.ecr.aws/docker/library/nginx:latest' Description: >- The url of a docker image that contains the application process that will handle the traffic for this service ContainerCpu: Type: Number Default: 256 Description: How much CPU to give the container. 1024 is 1 CPU ContainerMemory: Type: Number Default: 512 Description: How much memory in megabytes to give the container ContainerPort: Type: Number Default: 80 Description: What port that the application expects traffic on DesiredCount: Type: Number Default: 2 Description: How many copies of the service task to run Resources: TaskDefinition: Type: 'AWS::ECS::TaskDefinition' Properties: Family: !Ref ServiceName Cpu: !Ref ContainerCpu Memory: !Ref ContainerMemory NetworkMode: awsvpc RequiresCompatibilities: - EC2 ExecutionRoleArn: !Ref ECSTaskExecutionRole ContainerDefinitions: - Name: !Ref ServiceName Cpu: !Ref ContainerCpu Memory: !Ref ContainerMemory Image: !Ref ImageUrl PortMappings: - ContainerPort: !Ref ContainerPort HostPort: !Ref ContainerPort LogConfiguration: LogDriver: awslogs Options: mode: non-blocking max-buffer-size: 25m awslogs-group: !Ref LogGroup awslogs-region: !Ref AWS::Region awslogs-stream-prefix: !Ref ServiceName Service: Type: AWS::ECS::Service DependsOn: PublicLoadBalancerListener Properties: ServiceName: !Ref ServiceName Cluster: !Ref ClusterName PlacementStrategies: - Field: 'attribute:ecs.availability-zone' Type: spread - Field: cpu Type: binpack CapacityProviderStrategy: - Base: 0 CapacityProvider: !Ref CapacityProvider Weight: 1 NetworkConfiguration: AwsvpcConfiguration: SecurityGroups: - !Ref ServiceSecurityGroup Subnets: !Ref PrivateSubnetIds DeploymentConfiguration: MaximumPercent: 200 MinimumHealthyPercent: 75 DesiredCount: !Ref DesiredCount TaskDefinition: !Ref TaskDefinition LoadBalancers: - ContainerName: !Ref ServiceName ContainerPort: !Ref ContainerPort TargetGroupArn: !Ref ServiceTargetGroup ServiceSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Security group for service VpcId: !Ref VpcId ServiceTargetGroup: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: HealthCheckIntervalSeconds: 6 HealthCheckPath: / HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 5 HealthyThresholdCount: 2 TargetType: ip Port: !Ref ContainerPort Protocol: HTTP UnhealthyThresholdCount: 10 VpcId: !Ref VpcId TargetGroupAttributes: - Key: deregistration_delay.timeout_seconds Value: 0 PublicLoadBalancerSG: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Access to the public facing load balancer VpcId: !Ref VpcId SecurityGroupIngress: - CidrIp: 0.0.0.0/0 IpProtocol: -1 PublicLoadBalancer: Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer' Properties: Scheme: internet-facing LoadBalancerAttributes: - Key: idle_timeout.timeout_seconds Value: '30' Subnets: !Ref PublicSubnetIds SecurityGroups: - !Ref PublicLoadBalancerSG PublicLoadBalancerListener: Type: 'AWS::ElasticLoadBalancingV2::Listener' Properties: DefaultActions: - Type: forward ForwardConfig: TargetGroups: - TargetGroupArn: !Ref ServiceTargetGroup Weight: 100 LoadBalancerArn: !Ref PublicLoadBalancer Port: 80 Protocol: HTTP ServiceIngressfromLoadBalancer: Type: 'AWS::EC2::SecurityGroupIngress' Properties: Description: Ingress from the public ALB GroupId: !Ref ServiceSecurityGroup IpProtocol: -1 SourceSecurityGroupId: !Ref PublicLoadBalancerSG LogGroup: Type: 'AWS::Logs::LogGroup'
Criar vários recursos do Amazon ECS em uma pilha
O modelo de exemplo a seguir pode ser usado para criar vários recursos do Amazon ECS em uma pilha. O modelo cria um cluster do Amazon ECS chamado CFNCluster
. O cluster contém uma definição de tarefa do Linux Fargate que configura um servidor da Web. O modelo também cria um serviço denominado cfn-service
que inicia e mantém a tarefa definida pela definição de tarefa. Antes de usar esse modelo, verifique se os IDs da sub-rede e do grupo de segurança em NetworkConfiguration
do serviço pertencem todos à mesma VPC e se o grupo de segurança possui as regras necessárias. Para obter mais informações sobre regras de grupos de segurança, consulte Regras de grupos de segurança no Guia do usuário da Amazon VPC.
- JSON
-
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "ECSCluster": { "Type": "AWS::ECS::Cluster", "Properties": { "ClusterName": "CFNCluster" } }, "ECSTaskDefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ { "Command": [ "/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\"" ], "EntryPoint": [ "sh", "-c" ], "Essential": true, "Image": "httpd:2.4", "LogConfiguration": { "LogDriver": "awslogs", "Options": { "awslogs-group": "/ecs/fargate-task-definition", "awslogs-region": "us-east-1", "awslogs-stream-prefix": "ecs" } }, "Name": "sample-fargate-app", "PortMappings": [ { "ContainerPort": 80, "HostPort": 80, "Protocol": "tcp" } ] } ], "Cpu": 256, "ExecutionRoleArn": "arn:aws:iam::
aws_account_id
::role/ecsTaskExecutionRole", "Family": "task-definition-cfn", "Memory": 512, "NetworkMode": "awsvpc", "RequiresCompatibilities": [ "FARGATE" ], "RuntimePlatform": { "OperatingSystemFamily": "LINUX" } } }, "ECSService": { "Type": "AWS::ECS::Service", "Properties": { "ServiceName": "cfn-service", "Cluster": { "Ref": "ECSCluster" }, "DesiredCount": 1, "LaunchType": "FARGATE", "NetworkConfiguration": { "AwsvpcConfiguration": { "AssignPublicIp": "ENABLED", "SecurityGroups": [ "sg-abcdef01234567890
" ], "Subnets": [ "subnet-abcdef01234567890
" ] } }, "TaskDefinition": { "Ref": "ECSTaskDefinition" } } } } } - YAML
AWSTemplateFormatVersion: 2010-09-09 Resources: ECSCluster: Type: 'AWS::ECS::Cluster' Properties: ClusterName: CFNCluster ECSTaskDefinition: Type: 'AWS::ECS::TaskDefinition' Properties: ContainerDefinitions: - Command: - >- /bin/sh -c "echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground" EntryPoint: - sh - '-c' Essential: true Image: 'httpd:2.4' LogConfiguration: LogDriver: awslogs Options: awslogs-group: /ecs/fargate-task-definition awslogs-region: us-east-1 awslogs-stream-prefix: ecs Name: sample-fargate-app PortMappings: - ContainerPort: 80 HostPort: 80 Protocol: tcp Cpu: 256 ExecutionRoleArn: 'arn:aws:iam::
aws_account_id
:role/ecsTaskExecutionRole' Family: task-definition-cfn Memory: 512 NetworkMode: awsvpc RequiresCompatibilities: - FARGATE RuntimePlatform: OperatingSystemFamily: LINUX ECSService: Type: 'AWS::ECS::Service' Properties: ServiceName: cfn-service Cluster: !Ref ECSCluster DesiredCount: 1 LaunchType: FARGATE NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED SecurityGroups: -sg-abcdef01234567890
Subnets: -subnet-abcdef01234567890
TaskDefinition: !Ref ECSTaskDefinition
Usar o AWS CLI para criar recursos baseados em modelos
O comando a seguir cria uma pilha chamada ecs-stack
usando um arquivo de corpo de modelo chamado ecs-template-body.json
. Verifique se o arquivo de corpo do modelo está no formato JSON ou YAML. A localização do arquivo é especificada no parâmetro --template-body
. Neste caso, o arquivo de corpo do modelo está localizado no diretório atual.
aws cloudformation create-stack \ --stack-name
ecs-stack
\ --template-body file://ecs-template-body.json
Para garantir que os recursos sejam criados corretamente, verifique o console do Amazon ECS ou, como alternativa, use os seguintes comandos:
-
O comando a seguir lista todas as definições de tarefa.
aws ecs list-task-definitions
-
O comando a seguir lista todos os clusters.
aws ecs list-clusters
-
O comando a seguir lista todos os serviços definidos no cluster
. SubstituaCFNCluster
pelo nome do cluster em que deseja criar o serviço.CFNCluster
aws ecs list-services \ --cluster
CFNCluster
Saiba mais sobre a AWS CloudFormation
Para mais sobre o AWS CloudFormation, consulte os seguintes atributos: