Executar implantações azul/verde do ECS por meio do CodeDeploy usando o AWS CloudFormation - AWS CloudFormation

Executar implantações azul/verde do ECS por meio do CodeDeploy usando o AWS CloudFormation

É possível usar o CloudFormation para executar implantações azul/verde do ECS por meio do AWS CodeDeploy. As implantações azul/verde são uma estratégia de implantação segura fornecida pelo CodeDeploy para minimizar interrupções causadas pela alteração das versões do aplicativo. Isso é realizado por meio da criação de seu novo ambiente de aplicativo, chamado de verde, junto com seu aplicativo atual que está veiculando seu tráfego dinâmico, chamado de azul. Isso permite um período para o monitoramento e o teste do ambiente verde antes que o tráfego dinâmico seja roteado de azul para verde e, posteriormente, desative os recursos azuis.

Ao usar o CloudFormation para executar implantações azul/verde do ECS, você começa criando um modelo de pilha que define os recursos para seus ambientes de aplicativo azul e verde, incluindo a especificação das configurações de roteamento de tráfego e de estabilização a serem usadas. Depois, você cria uma pilha a partir desse modelo. Isso gera seu aplicativo azul (atual). O CloudFormation cria os recursos azuis somente durante a criação da pilha. Os recursos para uma implantação verde não são criados até que sejam necessários.

Depois, se em uma futura atualização de pilha você atualizar os recursos de definição de tarefa ou do conjunto de tarefas no aplicativo azul, o CloudFormation fará o seguinte:

  • Gerará todos os recursos de ambiente do aplicativo verde necessários

  • Deslocará o tráfego com base nos parâmetros de roteamento de tráfego especificados

  • Excluirá os recursos azuis

Se ocorrer um erro em qualquer ponto antes da implantação verde ser finalizada com êxito, o CloudFormation reverterá a pilha para seu estado anterior ao início de toda a implantação verde.

Para permitir que o CloudFormation execute implantações azul/verde em uma pilha, inclua as seguintes informações no modelo de pilha:

  • Uma seção do Transform em seu modelo que invoque a transformação AWS::CodeDeployBlueGreen, e uma seção Hook que invoque o gancho AWS::CodeDeploy::BlueGreen.

  • Pelo menos um dos recursos do ECS que acionará uma implantação azul/verde se for substituído durante uma atualização de pilha. Atualmente, esses recursos são AWS::ECS::TaskDefinition e AWS::ECS::TaskSet.

Depois, se você iniciar uma atualização de pilha que atualize qualquer propriedade dos recursos acima que exijam que o CloudFormation substitua o recurso, o CloudFormation executará uma implantação azul/verde conforme descrito acima. Para obter mais informações sobre o comportamento de atualização de recursos, consulte Atualizar comportamentos de recursos de pilha.

Em alguns casos, será melhor configurar seu modelo de pilha para habilitar implantações azul/verde antes de criar a pilha. No entanto, também é possível adicionar a possibilidade de fazer com que o CloudFormation execute implantações azul/verde em uma pilha existente. Para fazer isso, adicione as informações necessárias ao modelo existente da pilha.

Além disso, recomendamos que o CloudFormation gere um conjunto de alterações para a implantação verde, antes de iniciar a atualização da pilha. Isso permite que você revise as alterações que serão feitas na pilha.

Modelar sua implantação azul/verde usando recursos do CloudFormation

Para executar a implantação azul/verde do ECS usando CodeDeploy por meio do CloudFormation, o modelo deve incluir os recursos que modelam sua implantação, como um serviço do Amazon ECS e um balanceador de carga. Para mais detalhes sobre o que esses recursos representam, consulte Antes de iniciar uma implantação do Amazon ECS no AWS CodeDeployGuia do usuário.

Requisito Recurso Obrigatório/opcional Aciona a implantação azul/verde se substituído
Cluster do Amazon ECS AWS::ECS::Cluster Optional. O cluster padrão pode ser usado. Não
Serviço do Amazon ECS AWS::ECS::Service Obrigatório. Não
Application ou Network Load Balancer AWS::ECS::Service LoadBalancer Obrigatório. Não
Listener de produção AWS::ElasticLoadBalancingV2::Listener Obrigatório. Não
Listener de teste AWS::ElasticLoadBalancingV2::Listener Optional. Não
Dois grupos de destino AWS::ElasticLoadBalancingV2::TargetGroup Obrigatório. Não
Definição de tarefa do Amazon ECS AWS::ECS::TaskDefinition Obrigatório. Sim
Contêiner para seu aplicativo do Amazon ECS AWS::ECS::TaskDefinition ContainerDefinition Name Obrigatório. Não
Porta para o conjunto de tarefas de substituição AWS::ECS::TaskDefinition PortMapping ContainerPort Obrigatório. Não

Atualizações de recursos que acionam implantações verdes

Se você executar uma atualização de pilha que atualize qualquer propriedade que exija substituição dos seguintes recursos do ECS, o CloudFormation iniciará uma implantação verde:

Atualizar propriedades nesses recursos que não exigem substituição de recursos não aciona uma implantação verde.

Não é possível incluir atualizações para os recursos acima com atualizações para outros recursos na mesma atualização de pilha. Se for necessário atualizar recursos na lista acima, bem como outros recursos na mesma pilha, siga um destes procedimentos:

  • Execute duas operações de atualização de pilha separadas: uma que inclua somente as atualizações para os recursos acima e uma atualização de pilha separada que inclua alterações em quaisquer outros recursos.

  • Remova as seções Hook e Transform do modelo e execute a atualização da pilha. Neste caso, o CloudFormation não executará uma implantação verde.

Considerações ao gerenciar implantações azul/verde do ECS usando o CloudFormation

Considere o seguinte ao definir sua implantação azul/verde usando o CloudFormation:

  • Somente atualizações de determinados recursos acionarão uma implantação verde, conforme discutido em Atualizações de recursos que acionam implantações azul/verde do ECS.

  • Não é possível incluir atualizações de recursos que iniciem implantações verdes e atualizações de outros recursos na mesma atualização de pilha, conforme discutido em Atualizações de recursos que acionam implantações azul/verde do ECS.

  • Só é possível especificar um único serviço do ECS como o destino de implantação.

  • Os parâmetros que tenham valores ofuscados pelo CloudFormation não poderão ser atualizados pelo serviço CodeDeploy durante uma implantação verde, e causarão um erro e uma falha na atualização da pilha. Dentre elas estão:

  • Para cancelar uma implantação verde que ainda está em andamento, cancele a atualização da pilha no CloudFormation, e não no CodeDeploy ou ECS. Para obter mais informações, consulte Cancelar uma atualização de pilha. Após a conclusão de uma atualização, não será possível cancelá-la. No entanto, é possível atualizar uma pilha novamente com as definições anteriores.

  • No momento, não há suporte à declaração de valores de saída ou à importação de valores de outras pilhas para modelos que definam implantações azul/verde do ECS.

  • No momento, não há suporte à importação de recursos existentes para modelos que definam implantações azul/verde do ECS.

  • Não é possível usar o gancho AWS::CodeDeploy::BlueGreen em um modelo que inclua recursos de pilha aninhados.

  • Não é possível usar o gancho AWS::CodeDeploy::BlueGreen em uma pilha aninhada.

Para informações sobre como usar CloudFormation para executar suas implantações azuis/verdes do ECS por meio deCodeDeploy diferentes de uma implantação Amazon ECS padrão usando apenas CodeDeploy, consulte Diferenças entre implantações azuis/verdes do Amazon ECS por meio de CloudFormation e implantações padrão do Amazon ECS noManual do usuário do AWS CodeDeploy.

Preparar seu modelo para executar implantações azul/verde do ECS

Para permitir implantações azul/verde em sua pilha, inclua as seções a seguir no modelo de pilha antes de executar uma atualização dela.

  • Adicione uma referência à transformação AWS::CodeDeployBlueGreen ao modelo:

    "Transform": [ "AWS::CodeDeployBlueGreen" ],
  • Adicione uma seção Hook que invoque o gancho AWS::CodeDeploy::BlueGreen e especifique as propriedades para a implantação. Use a referência do modelo abaixo como guia.

  • Na seção Resources, defina os recursos azuis e verdes para a implantação.

É possível adicionar essas seções ao criar o modelo pela primeira vez (ou seja, antes de criar a pilha) ou adicioná-las a um modelo existente antes de executar uma atualização de pilha. Se você especificar a implantação azul/verde para uma nova pilha, o CloudFormation criará somente os recursos azuis durante a criação. Os recursos — para a implantação verde não serão criados até que sejam necessários durante uma atualização da pilha.

Revisar os conjuntos de alterações para a implantação azul/verde

É altamente recomendável que você crie um conjunto de alterações antes de executar uma atualização de pilha que iniciará uma implantação verde. Isso permite que você veja as alterações que serão feitas antes de executar a atualização da pilha. Esteja ciente de que as alterações de recursos podem não ser listadas na ordem em que serão executadas durante a atualização da pilha. Para obter mais informações, consulte Atualizar pilhas usando conjuntos de alterações.

Visualizar eventos da pilha para sua implantação azul/verde

É possível visualizar os eventos da pilha gerados em cada etapa da implantação do ECS na guia Eventos da página Pilha e usando a AWS CLI. Para obter mais informações, consulte Monitorar o andamento de uma atualização de pilha.

Referência do modelo

"Hooks": { "Logical ID": { "Properties": { "TrafficRoutingConfig": { "Type": "Traffic routing type" "TimeBasedCanary": { "StepPercentage": Integer, "BakeTimeMins": Integer } "TimeBasedLinear": { "StepPercentage": Integer, "BakeTimeMins": Integer } }, "AdditionalOptions": { "TerminationWaitTimeInMinutes": Integer }, "LifecycleEventHooks": { "BeforeInstall": "FunctionName", "AfterInstall": "FunctionName", "AfterAllowTestTraffic": "FunctionName", "BeforeAllowTraffic": "FunctionName", "AfterAllowTraffic": "FunctionName" }, "ServiceRole": "CodeDeployServiceRoleName", "Applications": [{ "Target": { "Type": "AWS::ECS::Service", "LogicalID": "Resource Logical ID" }, "ECSAttributes": { "TaskDefinitions": ["AWS::ECS::TaskDefinition Resource Logical ID (Blue)", "AWS::ECS::TaskDefinition Resource Logical ID (Green)"], "TaskSets": ["AWS::ECS::TaskSet Resource Logical ID (Blue)", "AWS::ECS::TaskSet Resource Logical ID (Green)"], "TrafficRouting": { "ProdTrafficRoute": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "LogicalID": "Resource Logical ID (Production)" }, "TestTrafficRoute": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "LogicalID": "Resource Logical ID (Test)" }, "TargetGroups": [ "AWS::ElasticLoadBalancingV2::TargetGroup Resource Logical ID (Blue)", "AWS::ElasticLoadBalancingV2::TargetGroup Resource Logical ID (Green)" ] } } } ] }, "Type": "AWS::CodeDeploy::BlueGreen" }

Properties

Logical ID

O ID lógico deve ser alfanumérico (A-Z a-z 0-9) e exclusivo no modelo.

Required: Yes

Properties

Propriedades do gancho.

Required: Yes

TrafficRoutingConfig

Definição das configurações de roteamento de tráfego.

Required: No

A configuração padrão é o deslocamento de tráfego canário baseado em tempo, com uma porcentagem de 15% de etapa e um tempo de incorporação de cinco minutos.

Type

O tipo de deslocamento de tráfego usado pela configuração de implantação.

Valores válidos: AllAtOnce | TimeBasedCanary | TimeBasedLinear

Required: Yes

TimeBasedCanary

Especifica uma configuração que desloca o tráfego de uma versão da implantação para outra em incrementos de dois.

Required: Conditional: se especificar TimeBasedCanary como o tipo de deslocamento de tráfego, você deverá incluir o parâmetro TimeBasedCanary.

StepPercentage

A porcentagem de tráfego a ser deslocado no primeiro incremento de uma implantação TimeBasedCanary. A porcentagem da etapa deve ser 14% ou maior.

Required: No

BakeTimeMins

O número de minutos entre o primeiro e o segundo deslocamento de tráfego de uma implantação TimeBasedCanary.

Required: No

TimeBasedLinear

Especifica uma configuração que desloca o tráfego de uma versão da implantação para outra em incrementos iguais, com um número igual de minutos entre cada incremento.

Required: Conditional: se especificar TimeBasedLinear como o tipo de deslocamento de tráfego, você deverá incluir o parâmetro TimeBasedLinear.

StepPercentage

A porcentagem de tráfego deslocado no início de cada incremento de uma implantação TimeBasedLinear. A porcentagem da etapa deve ser 14% ou maior.

Required: No

BakeTimeMins

O número de minutos entre cada deslocamento de tráfego incremental de uma implantação TimeBasedLinear.

Required: No

AdditionalOptions

Opções adicionais para a implantação azul/verde.

Required: No

TerminationWaitTimeInMinutes

Especifica o tempo de espera, em minutos, antes de encerrar os recursos azuis.

Required: No

LifecycleEventHooks

Use ganchos de eventos de ciclo de vida para especificar uma função do Lambda que o CodeDeploy possa chamar para validar uma implantação. É possível usar a mesma função ou uma diferente para os eventos de ciclo de vida de implantação. Após a conclusão dos testes de validação, a função AfterAllowTraffic do Lambda chama de volta o CodeDeploy e entrega um resultado de Succeeded ou Failed.

Para mais informações, consulte a seção “Ganchos” do AppSpec no Guia do usuário do AWS CodeDeploy.

Required: No

BeforeInstall

Função a ser usada para executar tarefas antes que o conjunto de tarefas de substituição seja criado.

Required: No

AfterInstall

Função a ser usada para executar tarefas depois que o conjunto de tarefas de substituição for criado e um dos grupos de destino for associado a ele.

Required: No

AfterAllowTestTraffic

Função a ser usada para executar tarefas depois que o listener de teste distribuir o tráfego para o conjunto de tarefas de substituição.

Required: No

BeforeAllowTraffic

Função a ser usada para executar tarefas depois que o segundo grupo de destino for associado ao conjunto de tarefas de substituição, mas antes que o tráfego seja deslocado para o conjunto de tarefas de substituição.

Required: No

AfterAllowTraffic

Função a ser usada para executar tarefas depois que o segundo grupo de destino distribuir o tráfego para o conjunto de tarefas de substituição.

Required: No

ServiceRole

A função de execução a ser usada pelo CloudFormation para executar as implantações azul/verde. Para obter uma lista das permissões necessárias, consulte Permissões do IAM necessárias para implantações azul/verde

Required: Yes

Applications

Especifica as propriedades do aplicativo do Amazon ECS.

Required: Yes

Target

Required: Yes

Type

O tipo de recurso.

Required: Yes

LogicalID

O ID lógico do recurso.

Required: Yes

ECSAttributes

Os recursos que representam os vários requisitos de sua implantação de aplicativos do Amazon ECS.

Required: Yes

TaskDefinitions

O ID lógico do AWS::ECS::TaskDefinition recurso para executar o contêiner do Docker que contém seu aplicativo do Amazon ECS.

Required: Yes

TaskSets

Os IDs lógicos dos recursos AWS::ECS::TaskSet a serem usados como conjuntos de tarefas para o aplicativo.

Required: Yes

TrafficRouting

Especifica os recursos usados para roteamento de tráfego.

Required: Yes

ProdTrafficRoute

O listener é usado pelo load balancer para direcionar o tráfego para seus grupos de destino.

Required: Yes

Type

O tipo de recurso. AWS::ElasticLoadBalancingV2::Listener

Required: Yes

LogicalID

O ID lógico do recurso.

Required: Yes

TestTrafficRoute

O listener é usado pelo load balancer para direcionar o tráfego para seus grupos de destino.

Required: Yes

Type

O tipo de recurso. AWS::ElasticLoadBalancingV2::Listener

Required: Yes

LogicalID

O ID lógico do recurso.

Required: No

TargetGroups

ID lógico dos recursos a serem usados como grupos de destino para rotear o tráfego para o destino registrado.

Required: Yes

Type

O tipo de gancho. AWS::ElasticLoadBalancingV2::Listener

Required: Yes

Permissões do IAM necessárias para implantações azul/verde

Para que o CloudFormation execute com sucesso as implantações azul/verde, você deve ter as seguintes permissões do CodeDeploy:

  • codedeploy:Get*

  • codedeploy:CreateCloudFormationDeployment

Para mais informações, consulte Actions, resources, and condition keys for CodeDeploy (Ações, recursos e chaves de condição para o CodeDeploy) no Guia do usuário do AWS Identity and Access Management.

Exemplo de modelo

O exemplo a seguir configura uma implantação azul/verde do ECS por meio do CodeDeploy, com um progresso de roteamento de tráfego de 15% por etapa, com um período de estabilização de 5 minutos entre cada etapa. Criar uma pilha com o modelo provisiona a configuração inicial da implantação.

Se você fez alguma alteração nas propriedades do recurso "BlueTaskSet" que exija que esse recurso seja substituído, o CloudFormation inicializará uma implantação verde como parte da atualização da pilha.

JSON

{ "Parameters": { "Vpc": { "Type": "AWS::EC2::VPC::Id" }, "Subnet1": { "Type": "AWS::EC2::Subnet::Id" }, "Subnet2": { "Type": "AWS::EC2::Subnet::Id" } }, "Transform": [ "AWS::CodeDeployBlueGreen" ], "Hooks": { "CodeDeployBlueGreenHook": { "Properties": { "TrafficRoutingConfig": { "Type": "TimeBasedCanary", "TimeBasedCanary": { "StepPercentage": 15, "BakeTimeMins": 5 } }, "Applications": [ { "Target": { "Type": "AWS::ECS::Service", "LogicalID": "ECSDemoService" }, "ECSAttributes": { "TaskDefinitions": [ "BlueTaskDefinition", "GreenTaskDefinition" ], "TaskSets": [ "BlueTaskSet", "GreenTaskSet" ], "TrafficRouting": { "ProdTrafficRoute": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "LogicalID": "ALBListenerProdTraffic" }, "TargetGroups": [ "ALBTargetGroupBlue", "ALBTargetGroupGreen" ] } } } ] }, "Type": "AWS::CodeDeploy::BlueGreen" } }, "Resources": { "ExampleSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Security group for ec2 access", "VpcId": { "Ref": "Vpc" }, "SecurityGroupIngress": [ { "IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080, "CidrIp": "0.0.0.0/0" }, { "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": "0.0.0.0/0" } ] } }, "ALBTargetGroupBlue": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 5, "HealthCheckPath": "/", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 2, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "Tags": [ { "Key": "Group", "Value": "Example" } ], "TargetType": "ip", "UnhealthyThresholdCount": 4, "VpcId": { "Ref": "Vpc" } } }, "ALBTargetGroupGreen": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "HealthCheckIntervalSeconds": 5, "HealthCheckPath": "/", "HealthCheckPort": "80", "HealthCheckProtocol": "HTTP", "HealthCheckTimeoutSeconds": 2, "HealthyThresholdCount": 2, "Matcher": { "HttpCode": "200" }, "Port": 80, "Protocol": "HTTP", "Tags": [ { "Key": "Group", "Value": "Example" } ], "TargetType": "ip", "UnhealthyThresholdCount": 4, "VpcId": { "Ref": "Vpc" } } }, "ExampleALB": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "Scheme": "internet-facing", "SecurityGroups": [ { "Ref": "ExampleSecurityGroup" } ], "Subnets": [ { "Ref": "Subnet1" }, { "Ref": "Subnet2" } ], "Tags": [ { "Key": "Group", "Value": "Example" } ], "Type": "application", "IpAddressType": "ipv4" } }, "ALBListenerProdTraffic": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": { "Ref": "ALBTargetGroupBlue" }, "Weight": 1 } ] } } ], "LoadBalancerArn": { "Ref": "ExampleALB" }, "Port": 80, "Protocol": "HTTP" } }, "ALBListenerProdRule": { "Type": "AWS::ElasticLoadBalancingV2::ListenerRule", "Properties": { "Actions": [ { "Type": "forward", "ForwardConfig": { "TargetGroups": [ { "TargetGroupArn": { "Ref": "ALBTargetGroupBlue" }, "Weight": 1 } ] } } ], "Conditions": [ { "Field": "http-header", "HttpHeaderConfig": { "HttpHeaderName": "User-Agent", "Values": [ "Mozilla" ] } } ], "ListenerArn": { "Ref": "ALBListenerProdTraffic" }, "Priority": 1 } }, "ECSTaskExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "ManagedPolicyArns": [ "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" ] } }, "BlueTaskDefinition": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ExecutionRoleArn": { "Fn::GetAtt": [ "ECSTaskExecutionRole", "Arn" ] }, "ContainerDefinitions": [ { "Name": "DemoApp", "Image": "nginxdemos/hello:latest", "Essential": true, "PortMappings": [ { "HostPort": 80, "Protocol": "tcp", "ContainerPort": 80 } ] } ], "RequiresCompatibilities": [ "FARGATE" ], "NetworkMode": "awsvpc", "Cpu": "256", "Memory": "512", "Family": "ecs-demo" } }, "ECSDemoCluster": { "Type": "AWS::ECS::Cluster", "Properties": {} }, "ECSDemoService": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": { "Ref": "ECSDemoCluster" }, "DesiredCount": 1, "DeploymentController": { "Type": "EXTERNAL" } } }, "BlueTaskSet": { "Type": "AWS::ECS::TaskSet", "Properties": { "Cluster": { "Ref": "ECSDemoCluster" }, "LaunchType": "FARGATE", "NetworkConfiguration": { "AwsVpcConfiguration": { "AssignPublicIp": "ENABLED", "SecurityGroups": [ { "Ref": "ExampleSecurityGroup" } ], "Subnets": [ { "Ref": "Subnet1" }, { "Ref": "Subnet2" } ] } }, "PlatformVersion": "1.4.0", "Scale": { "Unit": "PERCENT", "Value": 100 }, "Service": { "Ref": "ECSDemoService" }, "TaskDefinition": { "Ref": "BlueTaskDefinition" }, "LoadBalancers": [ { "ContainerName": "DemoApp", "ContainerPort": 80, "TargetGroupArn": { "Ref": "ALBTargetGroupBlue" } } ] } }, "PrimaryTaskSet": { "Type": "AWS::ECS::PrimaryTaskSet", "Properties": { "Cluster": { "Ref": "ECSDemoCluster" }, "Service": { "Ref": "ECSDemoService" }, "TaskSetId": { "Fn::GetAtt": [ "BlueTaskSet", "Id" ] } } } } }

YAML

Parameters: Vpc: Type: 'AWS::EC2::VPC::Id' Subnet1: Type: 'AWS::EC2::Subnet::Id' Subnet2: Type: 'AWS::EC2::Subnet::Id' Transform: - 'AWS::CodeDeployBlueGreen' Hooks: CodeDeployBlueGreenHook: Properties: TrafficRoutingConfig: Type: TimeBasedCanary TimeBasedCanary: StepPercentage: 15 BakeTimeMins: 5 Applications: - Target: Type: 'AWS::ECS::Service' LogicalID: ECSDemoService ECSAttributes: TaskDefinitions: - BlueTaskDefinition - GreenTaskDefinition TaskSets: - BlueTaskSet - GreenTaskSet TrafficRouting: ProdTrafficRoute: Type: 'AWS::ElasticLoadBalancingV2::Listener' LogicalID: ALBListenerProdTraffic TargetGroups: - ALBTargetGroupBlue - ALBTargetGroupGreen Type: 'AWS::CodeDeploy::BlueGreen' Resources: ExampleSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Security group for ec2 access VpcId: !Ref Vpc SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 8080 ToPort: 8080 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 ALBTargetGroupBlue: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: HealthCheckIntervalSeconds: 5 HealthCheckPath: / HealthCheckPort: '80' HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 2 HealthyThresholdCount: 2 Matcher: HttpCode: '200' Port: 80 Protocol: HTTP Tags: - Key: Group Value: Example TargetType: ip UnhealthyThresholdCount: 4 VpcId: !Ref Vpc ALBTargetGroupGreen: Type: 'AWS::ElasticLoadBalancingV2::TargetGroup' Properties: HealthCheckIntervalSeconds: 5 HealthCheckPath: / HealthCheckPort: '80' HealthCheckProtocol: HTTP HealthCheckTimeoutSeconds: 2 HealthyThresholdCount: 2 Matcher: HttpCode: '200' Port: 80 Protocol: HTTP Tags: - Key: Group Value: Example TargetType: ip UnhealthyThresholdCount: 4 VpcId: !Ref Vpc ExampleALB: Type: 'AWS::ElasticLoadBalancingV2::LoadBalancer' Properties: Scheme: internet-facing SecurityGroups: - !Ref ExampleSecurityGroup Subnets: - !Ref Subnet1 - !Ref Subnet2 Tags: - Key: Group Value: Example Type: application IpAddressType: ipv4 ALBListenerProdTraffic: Type: 'AWS::ElasticLoadBalancingV2::Listener' Properties: DefaultActions: - Type: forward ForwardConfig: TargetGroups: - TargetGroupArn: !Ref ALBTargetGroupBlue Weight: 1 LoadBalancerArn: !Ref ExampleALB Port: 80 Protocol: HTTP ALBListenerProdRule: Type: 'AWS::ElasticLoadBalancingV2::ListenerRule' Properties: Actions: - Type: forward ForwardConfig: TargetGroups: - TargetGroupArn: !Ref ALBTargetGroupBlue Weight: 1 Conditions: - Field: http-header HttpHeaderConfig: HttpHeaderName: User-Agent Values: - Mozilla ListenerArn: !Ref ALBListenerProdTraffic Priority: 1 ECSTaskExecutionRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Sid: '' Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: 'sts:AssumeRole' ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy' BlueTaskDefinition: Type: 'AWS::ECS::TaskDefinition' Properties: ExecutionRoleArn: !GetAtt - ECSTaskExecutionRole - Arn ContainerDefinitions: - Name: DemoApp Image: 'nginxdemos/hello:latest' Essential: true PortMappings: - HostPort: 80 Protocol: tcp ContainerPort: 80 RequiresCompatibilities: - FARGATE NetworkMode: awsvpc Cpu: '256' Memory: '512' Family: ecs-demo ECSDemoCluster: Type: 'AWS::ECS::Cluster' Properties: {} ECSDemoService: Type: 'AWS::ECS::Service' Properties: Cluster: !Ref ECSDemoCluster DesiredCount: 1 DeploymentController: Type: EXTERNAL BlueTaskSet: Type: 'AWS::ECS::TaskSet' Properties: Cluster: !Ref ECSDemoCluster LaunchType: FARGATE NetworkConfiguration: AwsVpcConfiguration: AssignPublicIp: ENABLED SecurityGroups: - !Ref ExampleSecurityGroup Subnets: - !Ref Subnet1 - !Ref Subnet2 PlatformVersion: 1.4.0 Scale: Unit: PERCENT Value: 100 Service: !Ref ECSDemoService TaskDefinition: !Ref BlueTaskDefinition LoadBalancers: - ContainerName: DemoApp ContainerPort: 80 TargetGroupArn: !Ref ALBTargetGroupBlue PrimaryTaskSet: Type: 'AWS::ECS::PrimaryTaskSet' Properties: Cluster: !Ref ECSDemoCluster Service: !Ref ECSDemoService TaskSetId: !GetAtt - BlueTaskSet - Id