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 da aplicação. 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, o que gera sua aplicação azul (atual). O CloudFormation cria somente os recursos azuis 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çãoAWS::CodeDeployBlueGreen
, e uma seçãoHook
que invoque o hookAWS::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
eAWS::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 recurso, consulte Atualizar comportamentos de recursos da 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. Para ter mais informações, consulte Atualizar pilhas usando conjuntos de alterações.
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 |
Opcional. 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 |
Opcional. | 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
eTransform
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 verdes.
Não é possível incluir atualizações de recursos que acionam 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 verdes.
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. Isso inclui:
Parâmetros definidos com o atributo
NoEcho
.Parâmetros que usam referências dinâmicas para recuperar seus valores de serviços externos. Para ter mais informações, consulte Usar referências dinâmicas para especificar valores de modelos.
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 ter 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. Porém, é possível atualizar uma pilha novamente com as configurações anteriores.)
No momento, não há suporte à declaração de Outputs ou ao uso de para importar valores de outras pilhas para modelos que definem implantações azul/verde do ECS.
No momento, não há suporte a modelos que definem implantações azul/verde do ECS.
Não é possível usar o hook
AWS::CodeDeploy::BlueGreen
em um modelo que inclua recursos de pilha aninhados.Não é possível usar o hook
AWS::CodeDeploy::BlueGreen
em uma pilha aninhada.
Para obter informações sobre como o uso do CloudFormation para executar suas implantações do ECS azul/verde por meio de CodeDeploy difere de uma implantação padrão do Amazon ECS usando apenas CodeDeploy, consulte Diferenças entre implantações azul/verde do Amazon ECS por meio do CloudFormation e implantações padrão do Amazon ECS, no Guia 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 hookAWS::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 ter 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 Events (Eventos) da página Stack (Pilha) e usando a AWS CLI. Para ter mais informações, consulte Monitorar o progresso da atualização de uma 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" } }
Propriedades
Logical ID
-
O ID lógico deve ser alfanumérico (A-Z a-z 0-9) e exclusivo no modelo.
Obrigatório: Sim
Properties
-
Propriedades do hook.
Obrigatório: Sim
TrafficRoutingConfig
-
Definição das configurações de roteamento de tráfego.
Obrigatório: não
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
Obrigatório: Sim
TimeBasedCanary
-
Especifica uma configuração que desloca o tráfego de uma versão da implantação para outra em incrementos de dois.
Necessário: Condicional: se você especificar
TimeBasedCanary
como o tipo de roteamento de tráfego, deverá incluir o parâmetroTimeBasedCanary
.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.Obrigatório: não
BakeTimeMins
-
O número de minutos entre o primeiro e o segundo deslocamento de tráfego de uma implantação
TimeBasedCanary
.Obrigatório: não
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.
Necessário: Condicional: se você especificar
TimeBasedLinear
como o tipo de roteamento de tráfego, deverá incluir o parâmetroTimeBasedLinear
.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.Obrigatório: não
BakeTimeMins
-
O número de minutos entre cada deslocamento de tráfego incremental de uma implantação
TimeBasedLinear
.Obrigatório: não
AdditionalOptions
-
Opções adicionais para a implantação azul/verde.
Obrigatório: não
TerminationWaitTimeInMinutes
-
Especifica o tempo de espera, em minutos, antes de encerrar os recursos azuis.
Obrigatório: não
LifecycleEventHooks
-
Use hooks 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
ouFailed
.Para mais informações, consulte a seção “Hooks” do AppSpec no Guia do usuário do AWS CodeDeploy.
Obrigatório: não
BeforeInstall
-
Função a ser usada para executar tarefas antes que o conjunto de tarefas de substituição seja criado.
Obrigatório: não
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.
Obrigatório: não
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.
Obrigatório: não
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.
Obrigatório: não
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.
Obrigatório: não
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.
Obrigatório: Sim
Applications
-
Especifica as propriedades do aplicativo do Amazon ECS.
Obrigatório: Sim
Target
-
Obrigatório: Sim
Type
-
O tipo de recurso.
Obrigatório: Sim
LogicalID
-
O ID lógico do recurso.
Obrigatório: Sim
ECSAttributes
-
Os recursos que representam os vários requisitos de sua implantação de aplicativos do Amazon ECS.
Obrigatório: Sim
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.Obrigatório: Sim
TaskSets
-
Os IDs lógicos dos recursos
AWS::ECS::TaskSet
a serem usados como conjuntos de tarefas para o aplicativo.Obrigatório: Sim
TrafficRouting
-
Especifica os recursos usados para roteamento de tráfego.
Obrigatório: Sim
ProdTrafficRoute
-
O listener é usado pelo load balancer para direcionar o tráfego para seus grupos de destino.
Obrigatório: Sim
Type
-
O tipo do recurso.
AWS::ElasticLoadBalancingV2::Listener
Obrigatório: Sim
LogicalID
-
O ID lógico do recurso.
Obrigatório: Sim
TestTrafficRoute
-
O listener é usado pelo load balancer para direcionar o tráfego para seus grupos de destino.
Obrigatório: Sim
Type
-
O tipo do recurso.
AWS::ElasticLoadBalancingV2::Listener
Obrigatório: Sim
LogicalID
-
O ID lógico do recurso.
Obrigatório: não
TargetGroups
-
ID lógico dos recursos a serem usados como grupos de destino para rotear o tráfego para o destino registrado.
Obrigatório: Sim
Type
-
O tipo do hook.
AWS::ElasticLoadBalancingV2::Listener
Obrigatório: Sim
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 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