

# Criar recursos do Amazon ECS usando o console do CloudFormation
<a name="ecs-cloudformation-console"></a>

Uma forma de usar o Amazon ECS com o CloudFormation é por meio do Console de gerenciamento da AWS. Aqui você pode criar suas pilhas do CloudFormation para componentes do Amazon ECS, como definições de tarefas, clusters e serviços, e implantá-los diretamente via console. O tutorial a seguir mostra como você pode usar o console do CloudFormation para criar recursos do Amazon ECS usando um modelo.

## Pré-requisitos
<a name="ecs-cloudformation-console-prerequisites"></a>

Esse tutorial pressupõe que os pré-requisitos a seguir foram concluídos.
+ As etapas em [Configuração para usar o Amazon ECS](get-set-up-for-amazon-ecs.md) foram concluídas.
+ O usuário do IAM tem as permissões necessárias especificadas no exemplo de política do IAM de [AmazonECS\$1FullAccess](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonECS_FullAccess).

## Etapa 1: criar um modelo de pilha
<a name="ecs-cloudformation-create-template-file"></a>

Use as etapas a seguir para criar um modelo de pilha do CloudFormation para um serviço e outros recursos relacionados do Amazon ECS.

1. Usando um editor de texto qualquer, crie um arquivo chamado `ecs-tutorial-template.yaml`.

1. No arquivo `ecs-tutorial-template.yaml`, cole o modelo a seguir e salve as alterações.

   ```
   AWSTemplateFormatVersion: '2010-09-09'
   Description: '[AWSDocs] ECS: load-balanced-web-application'
   
   Parameters:
     VpcCidr:
       Type: String
       Default: '10.0.0.0/16'
       Description: CIDR block for the VPC
     ContainerImage:
       Type: String
       Default: 'public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'
       Description: Container image to use in task definition
   
     PublicSubnet1Cidr:
       Type: String
       Default: '10.0.1.0/24'
       Description: CIDR block for public subnet 1
     
     PublicSubnet2Cidr:
       Type: String
       Default: '10.0.2.0/24'
       Description: CIDR block for public subnet 2
     
     PrivateSubnet1Cidr:
       Type: String
       Default: '10.0.3.0/24'
       Description: CIDR block for private subnet 1
     
     PrivateSubnet2Cidr:
       Type: String
       Default: '10.0.4.0/24'
       Description: CIDR block for private subnet 2
     
     ServiceName:
       Type: String
       Default: 'tutorial-app'
       Description: Name of the ECS service
     
     ContainerPort:
       Type: Number
       Default: 80
       Description: Port on which the container listens
     
     DesiredCount:
       Type: Number
       Default: 2
       Description: Desired number of tasks
     
     MinCapacity:
       Type: Number
       Default: 1
       Description: Minimum number of tasks for auto scaling
     
     MaxCapacity:
       Type: Number
       Default: 10
       Description: Maximum number of tasks for auto scaling
   
   Resources:
     # VPC and Networking
     VPC:
       Type: AWS::EC2::VPC
       Properties:
         CidrBlock: !Ref VpcCidr
         EnableDnsHostnames: true
         EnableDnsSupport: true
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-vpc'
   
     # Internet Gateway
     InternetGateway:
       Type: AWS::EC2::InternetGateway
       Properties:
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-igw'
   
     InternetGatewayAttachment:
       Type: AWS::EC2::VPCGatewayAttachment
       Properties:
         InternetGatewayId: !Ref InternetGateway
         VpcId: !Ref VPC
   
     # Public Subnets for ALB
     PublicSubnet1:
       Type: AWS::EC2::Subnet
       Properties:
         VpcId: !Ref VPC
         AvailabilityZone: !Select [0, !GetAZs '']
         CidrBlock: !Ref PublicSubnet1Cidr
         MapPublicIpOnLaunch: true
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-public-subnet-1'
   
     PublicSubnet2:
       Type: AWS::EC2::Subnet
       Properties:
         VpcId: !Ref VPC
         AvailabilityZone: !Select [1, !GetAZs '']
         CidrBlock: !Ref PublicSubnet2Cidr
         MapPublicIpOnLaunch: true
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-public-subnet-2'
   
     # Private Subnets for ECS Tasks
     PrivateSubnet1:
       Type: AWS::EC2::Subnet
       Properties:
         VpcId: !Ref VPC
         AvailabilityZone: !Select [0, !GetAZs '']
         CidrBlock: !Ref PrivateSubnet1Cidr
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-private-subnet-1'
   
     PrivateSubnet2:
       Type: AWS::EC2::Subnet
       Properties:
         VpcId: !Ref VPC
         AvailabilityZone: !Select [1, !GetAZs '']
         CidrBlock: !Ref PrivateSubnet2Cidr
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-private-subnet-2'
   
     # NAT Gateways for private subnet internet access
     NatGateway1EIP:
       Type: AWS::EC2::EIP
       DependsOn: InternetGatewayAttachment
       Properties:
         Domain: vpc
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-nat-eip-1'
   
     NatGateway2EIP:
       Type: AWS::EC2::EIP
       DependsOn: InternetGatewayAttachment
       Properties:
         Domain: vpc
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-nat-eip-2'
   
     NatGateway1:
       Type: AWS::EC2::NatGateway
       Properties:
         AllocationId: !GetAtt NatGateway1EIP.AllocationId
         SubnetId: !Ref PublicSubnet1
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-nat-1'
   
     NatGateway2:
       Type: AWS::EC2::NatGateway
       Properties:
         AllocationId: !GetAtt NatGateway2EIP.AllocationId
         SubnetId: !Ref PublicSubnet2
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-nat-2'
   
     # Route Tables
     PublicRouteTable:
       Type: AWS::EC2::RouteTable
       Properties:
         VpcId: !Ref VPC
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-public-routes'
   
     DefaultPublicRoute:
       Type: AWS::EC2::Route
       DependsOn: InternetGatewayAttachment
       Properties:
         RouteTableId: !Ref PublicRouteTable
         DestinationCidrBlock: 0.0.0.0/0
         GatewayId: !Ref InternetGateway
   
     PublicSubnet1RouteTableAssociation:
       Type: AWS::EC2::SubnetRouteTableAssociation
       Properties:
         RouteTableId: !Ref PublicRouteTable
         SubnetId: !Ref PublicSubnet1
   
     PublicSubnet2RouteTableAssociation:
       Type: AWS::EC2::SubnetRouteTableAssociation
       Properties:
         RouteTableId: !Ref PublicRouteTable
         SubnetId: !Ref PublicSubnet2
   
     PrivateRouteTable1:
       Type: AWS::EC2::RouteTable
       Properties:
         VpcId: !Ref VPC
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-private-routes-1'
   
     DefaultPrivateRoute1:
       Type: AWS::EC2::Route
       Properties:
         RouteTableId: !Ref PrivateRouteTable1
         DestinationCidrBlock: 0.0.0.0/0
         NatGatewayId: !Ref NatGateway1
   
     PrivateSubnet1RouteTableAssociation:
       Type: AWS::EC2::SubnetRouteTableAssociation
       Properties:
         RouteTableId: !Ref PrivateRouteTable1
         SubnetId: !Ref PrivateSubnet1
   
     PrivateRouteTable2:
       Type: AWS::EC2::RouteTable
       Properties:
         VpcId: !Ref VPC
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-private-routes-2'
   
     DefaultPrivateRoute2:
       Type: AWS::EC2::Route
       Properties:
         RouteTableId: !Ref PrivateRouteTable2
         DestinationCidrBlock: 0.0.0.0/0
         NatGatewayId: !Ref NatGateway2
   
     PrivateSubnet2RouteTableAssociation:
       Type: AWS::EC2::SubnetRouteTableAssociation
       Properties:
         RouteTableId: !Ref PrivateRouteTable2
         SubnetId: !Ref PrivateSubnet2
   
     # Security Groups
     ALBSecurityGroup:
       Type: AWS::EC2::SecurityGroup
       Properties:
         GroupName: !Sub '${AWS::StackName}-alb-sg'
         GroupDescription: Security group for Application Load Balancer
         VpcId: !Ref VPC
         SecurityGroupIngress:
           - IpProtocol: tcp
             FromPort: 80
             ToPort: 80
             CidrIp: 0.0.0.0/0
             Description: Allow HTTP traffic from internet
         SecurityGroupEgress:
           - IpProtocol: -1
             CidrIp: 0.0.0.0/0
             Description: Allow all outbound traffic
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-alb-sg'
   
     ECSSecurityGroup:
       Type: AWS::EC2::SecurityGroup
       Properties:
         GroupName: !Sub '${AWS::StackName}-ecs-sg'
         GroupDescription: Security group for ECS tasks
         VpcId: !Ref VPC
         SecurityGroupIngress:
           - IpProtocol: tcp
             FromPort: !Ref ContainerPort
             ToPort: !Ref ContainerPort
             SourceSecurityGroupId: !Ref ALBSecurityGroup
             Description: Allow traffic from ALB
         SecurityGroupEgress:
           - IpProtocol: -1
             CidrIp: 0.0.0.0/0
             Description: Allow all outbound traffic
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-ecs-sg'
   
     # Application Load Balancer
     ApplicationLoadBalancer:
       Type: AWS::ElasticLoadBalancingV2::LoadBalancer
       Properties:
         Name: !Sub '${AWS::StackName}-alb'
         Scheme: internet-facing
         Type: application
         Subnets:
           - !Ref PublicSubnet1
           - !Ref PublicSubnet2
         SecurityGroups:
           - !Ref ALBSecurityGroup
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-alb'
   
     ALBTargetGroup:
       Type: AWS::ElasticLoadBalancingV2::TargetGroup
       Properties:
         Name: !Sub '${AWS::StackName}-tg'
         Port: !Ref ContainerPort
         Protocol: HTTP
         VpcId: !Ref VPC
         TargetType: ip
         HealthCheckIntervalSeconds: 30
         HealthCheckPath: /
         HealthCheckProtocol: HTTP
         HealthCheckTimeoutSeconds: 5
         HealthyThresholdCount: 2
         UnhealthyThresholdCount: 5
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-tg'
   
     ALBListener:
       Type: AWS::ElasticLoadBalancingV2::Listener
       Properties:
         DefaultActions:
           - Type: forward
             TargetGroupArn: !Ref ALBTargetGroup
         LoadBalancerArn: !Ref ApplicationLoadBalancer
         Port: 80
         Protocol: HTTP
   
     # ECS Cluster
     ECSCluster:
       Type: AWS::ECS::Cluster
       Properties:
         ClusterName: !Sub '${AWS::StackName}-cluster'
         CapacityProviders:
           - FARGATE
           - FARGATE_SPOT
         DefaultCapacityProviderStrategy:
           - CapacityProvider: FARGATE
             Weight: 1
           - CapacityProvider: FARGATE_SPOT
             Weight: 4
         ClusterSettings:
           - Name: containerInsights
             Value: enabled
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-cluster'
   
     # IAM Roles
     ECSTaskExecutionRole:
       Type: AWS::IAM::Role
       Properties:
         RoleName: !Sub '${AWS::StackName}-task-execution-role'
         AssumeRolePolicyDocument:
           Version: '2012-10-17		 	 	 '
           Statement:
             - Effect: Allow
               Principal:
                 Service: ecs-tasks.amazonaws.com
               Action: sts:AssumeRole
         ManagedPolicyArns:
           - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-task-execution-role'
   
     ECSTaskRole:
       Type: AWS::IAM::Role
       Properties:
         RoleName: !Sub '${AWS::StackName}-task-role'
         AssumeRolePolicyDocument:
           Version: '2012-10-17		 	 	 '
           Statement:
             - Effect: Allow
               Principal:
                 Service: ecs-tasks.amazonaws.com
               Action: sts:AssumeRole
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-task-role'
   
     # CloudWatch Log Group
     LogGroup:
       Type: AWS::Logs::LogGroup
       Properties:
         LogGroupName: !Sub '/ecs/${AWS::StackName}'
         RetentionInDays: 7
   
     # ECS Task Definition
     TaskDefinition:
       Type: AWS::ECS::TaskDefinition
       Properties:
         Family: !Sub '${AWS::StackName}-task'
         Cpu: '256'
         Memory: '512'
         NetworkMode: awsvpc
         RequiresCompatibilities:
           - FARGATE
         ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
         TaskRoleArn: !GetAtt ECSTaskRole.Arn
         ContainerDefinitions:
           - Name: !Ref ServiceName
             Image: !Ref ContainerImage
             PortMappings:
               - ContainerPort: !Ref ContainerPort
                 Protocol: tcp
             Essential: true
             LogConfiguration:
               LogDriver: awslogs
               Options:
                 awslogs-group: !Ref LogGroup
                 awslogs-region: !Ref AWS::Region
                 awslogs-stream-prefix: ecs
             HealthCheck:
               Command:
                 - CMD-SHELL
                 - curl -f http://localhost/ || exit 1
               Interval: 30
               Timeout: 5
               Retries: 3
               StartPeriod: 60
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-task'
   
     # ECS Service
     ECSService:
       Type: AWS::ECS::Service
       DependsOn: ALBListener
       Properties:
         ServiceName: !Sub '${AWS::StackName}-service'
         Cluster: !Ref ECSCluster
         TaskDefinition: !Ref TaskDefinition
         DesiredCount: !Ref DesiredCount
         LaunchType: FARGATE
         PlatformVersion: LATEST
         NetworkConfiguration:
           AwsvpcConfiguration:
             AssignPublicIp: DISABLED 
             SecurityGroups:
               - !Ref ECSSecurityGroup
             Subnets:
               - !Ref PrivateSubnet1
               - !Ref PrivateSubnet2
         LoadBalancers:
           - ContainerName: !Ref ServiceName
             ContainerPort: !Ref ContainerPort
             TargetGroupArn: !Ref ALBTargetGroup
         DeploymentConfiguration:
           MaximumPercent: 200
           MinimumHealthyPercent: 50
           DeploymentCircuitBreaker:
             Enable: true
             Rollback: true
         EnableExecuteCommand: true  # For debugging
         Tags:
           - Key: Name
             Value: !Sub '${AWS::StackName}-service'
   
     # Auto Scaling Target
     ServiceScalingTarget:
       Type: AWS::ApplicationAutoScaling::ScalableTarget
       Properties:
         MaxCapacity: !Ref MaxCapacity
         MinCapacity: !Ref MinCapacity
         ResourceId: !Sub 'service/${ECSCluster}/${ECSService.Name}'
         RoleARN: !Sub 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService'
         ScalableDimension: ecs:service:DesiredCount
         ServiceNamespace: ecs
   
     # Auto Scaling Policy - CPU Utilization
     ServiceScalingPolicy:
       Type: AWS::ApplicationAutoScaling::ScalingPolicy
       Properties:
         PolicyName: !Sub '${AWS::StackName}-cpu-scaling-policy'
         PolicyType: TargetTrackingScaling
         ScalingTargetId: !Ref ServiceScalingTarget
         TargetTrackingScalingPolicyConfiguration:
           PredefinedMetricSpecification:
             PredefinedMetricType: ECSServiceAverageCPUUtilization
           TargetValue: 70.0
           ScaleOutCooldown: 300
           ScaleInCooldown: 300
   
   Outputs:
     VPCId:
       Description: VPC ID
       Value: !Ref VPC
       Export:
         Name: !Sub '${AWS::StackName}-VPC-ID'
   
     LoadBalancerURL:
       Description: URL of the Application Load Balancer
       Value: !Sub 'http://${ApplicationLoadBalancer.DNSName}'
       Export:
         Name: !Sub '${AWS::StackName}-ALB-URL'
   
     ECSClusterName:
       Description: Name of the ECS Cluster
       Value: !Ref ECSCluster
       Export:
         Name: !Sub '${AWS::StackName}-ECS-Cluster'
   
     ECSServiceName:
       Description: Name of the ECS Service
       Value: !GetAtt ECSService.Name
       Export:
         Name: !Sub '${AWS::StackName}-ECS-Service'
   
     PrivateSubnet1:
       Description: Private Subnet 1 ID
       Value: !Ref PrivateSubnet1
       Export:
         Name: !Sub '${AWS::StackName}-Private-Subnet-1'
   
     PrivateSubnet2:
       Description: Private Subnet 2 ID
       Value: !Ref PrivateSubnet2
       Export:
         Name: !Sub '${AWS::StackName}-Private-Subnet-2'
   ```

    O modelo usado neste tutorial cria um serviço do Amazon ECS com duas tarefas que são executadas no Fargate. Cada uma das tarefas executa uma aplicação do Amazon ECS de exemplo. O modelo também cria um Application Load Balancer que distribui o tráfego da aplicação e uma política de ajuste de escala automático da aplicação que dimensiona a aplicação com base na utilização da CPU. O modelo também cria os recursos de rede necessários para implantar a aplicação, os recursos de registro para logs de contêineres e um perfil do IAM de execução de tarefas no Amazon ECS. Para obter mais informações sobre a função de execução de tarefas, consulte [Função do IAM de execução de tarefas do Amazon ECS](task_execution_IAM_role.md). Para obter mais informações sobre o ajuste de escala automático, consulte [Como escalar automaticamente o serviço do Amazon ECS](service-auto-scaling.md).

## Etapa 2: criar uma pilha para recursos do Amazon ECS
<a name="ecs-cloudformation-create-stack"></a>

Depois de criar um arquivo para o modelo, siga estas etapas para criar uma pilha com o modelo usando o console do CloudFormation.

Para obter informações sobre como criar uma pilha usando o console do CloudFormation, consulte [Criar uma pilha no console do CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html) no *Guia do usuário do AWS CloudFormation* e use a tabela a seguir para determinar quais opções devem ser especificadas.


| Opção | Valor | 
| --- | --- | 
|  Pré-requisito: preparar o modelo  | Escolher um modelo existente. | 
| Especificar um modelo |  Fazer upload de um arquivo de modelo  | 
| Escolher arquivo |  ecs-tutorial-template.yaml  | 
| Nome da pilha |  ecs-tutorial-stack  | 
| Parâmetros |  Mantenha os parâmetros com seus valores padrão.  | 
| Capacidades |  Escolha **Eu reconheço que este modelo pode criar recursos do IAM** para reconhecer a criação de recursos do IAM pelo CloudFormation.  | 

## Etapa 3: verificar
<a name="ecs-cloudformation-verify"></a>

Use as etapas a seguir para verificar a criação de recursos do Amazon ECS usando o modelo fornecido.

Para obter informações sobre como visualizar informações e recursos da pilha, consulte [Visualizar informações da pilha no console do CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-view-stack-data-resources.html) no *Guia do usuário do AWS CloudFormation* e use a tabela a seguir para determinar o que verificar.


| Campo de detalhes da pilha | O que procurar | 
| --- | --- | 
|  Informações da pilha  | Um status de CREATE\$1COMPLETE. | 
| Recursos |  Uma lista dos recursos criados com links para o console do serviço. Escolha links para `ECSCluster`, `ECSService`, `TaskDefinition` para ver mais detalhes sobre o serviço criado, o cluster e a definição da tarefa no console do Amazon ECS.  | 
| Saídas |  **LoadBalancerURL**. Cole o URL em um navegador da Web para visualizar uma página da Web que exibe uma aplicação do Amazon ECS de exemplo.  | 

## Etapa 4: Limpar os recursos
<a name="ecs-cloudformation-console-cleanup"></a>

Para limpar recursos e evitar custos adicionais, siga as etapas em [Excluir uma pilha do console do CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-delete-stack.html) no *Guia do usuário do CloudFormation*.