Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides AWS CloudFormation patterns for ECS clusters, task definitions, services, container definitions, auto scaling, blue/green deployments, CodeDeploy integration, ALB integration, service discovery, monitoring, logging, template structure, parameters, outputs, and cross-stack references. Use when creating ECS clusters with CloudFormation, configuring Fargate and EC2 launch types, implementing blue/green deployments, managing auto scaling, integrating with ALB and NLB, and implementing ECS b
.claude/skills/giuseppe-trisciuoglio-aws-cloudformation-ecs/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 177% | 0% |
| case-19 | ✗→✓ | ▲ Improved | 121% | 0% |
| case-12 | ✓→✓ | = Same ✓ | 130% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 343% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 177% | 0% |
Provides CloudFormation patterns for ECS clusters, task definitions, services, container definitions, auto scaling, blue/green deployments, ALB integration, monitoring, and cross-stack references.
Follow these steps to create ECS infrastructure with CloudFormation:
Specify launch type, networking, and capacity settings:
yamlParameters: LaunchType: Type: String Default: FARGATE AllowedValues: - EC2 - FARGATE Description: ECS launch type ContainerPort: Type: Number Default: 80 Description: Container port TaskCPU: Type: String Default: 256 AllowedValues: - 256 - 512 - 1024 - 2048 - 4096 Description: Task CPU units TaskMemory: Type: String Default: 512 AllowedValues: - 512 - 1024 - 2048 - 3072 - 4096 - 5120 - 6144 - 7168 - 8192 - 9216 - 10240 Description: Task memory in MB
Define the cluster infrastructure:
yamlResources: ECSCluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Sub "${AWS::StackName}-cluster" ClusterSettings: - Name: containerInsights Value: enabled CapacityProviders: - FARGATE - FARGATE_SPOT DefaultCapacityProviderStrategy: - CapacityProvider: FARGATE Weight: 1 - CapacityProvider: FARGATE_SPOT Weight: 0
Define container configurations:
yamlResources: TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub "${AWS::StackName}-task" NetworkMode: awsvpc RequiresCompatibilities: - FARGATE Cpu: !Ref TaskCPU Memory: !Ref TaskMemory ExecutionRoleArn: !Ref ExecutionRole TaskRoleArn: !Ref TaskRole ContainerDefinitions: - Name: application Image: !Ref ImageUrl PortMappings: - ContainerPort: !Ref ContainerPort Protocol: tcp Environment: - Name: LOG_LEVEL Value: INFO LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref LogGroup awslogs-region: !Ref AWS::Region awslogs-stream-prefix: ecs Memory: !Ref TaskMemory
Validate task definition syntax before proceeding:
bashaws cloudformation validate-template --template-body file://template.yaml
Set up IAM roles for task execution:
yamlResources: ExecutionRole: Type: AWS::IAM::Role Properties: 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 TaskRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: S3Access PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - s3:GetObject Resource: !Sub "${DataBucket.Arn}/*"
Define the service configuration:
yamlResources: ECSService: Type: AWS::ECS::Service Properties: ServiceName: !Sub "${AWS::StackName}-service" Cluster: !Ref ECSCluster TaskDefinition: !Ref TaskDefinition DesiredCount: 2 LaunchType: FARGATE NetworkConfiguration: AwsvpcConfiguration: Subnets: - !Ref PrivateSubnet1 - !Ref PrivateSubnet2 SecurityGroups: - !Ref SecurityGroup AssignPublicIp: DISABLED LoadBalancers: - TargetGroupArn: !Ref TargetGroup ContainerName: application ContainerPort: !Ref ContainerPort
Set up ALB for traffic distribution:
yamlResources: LoadBalancer: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: !Sub "${AWS::StackName}-alb" Scheme: internet-facing Type: application Subnets: - !Ref PublicSubnet1 - !Ref PublicSubnet2 SecurityGroups: - !Ref ALBSecurityGroup TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 80 Protocol: HTTP VpcId: !Ref VPC TargetType: ip Listener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref TargetGroup Type: forward LoadBalancerArn: !Ref LoadBalancer Port: 80 Protocol: HTTP
Configure Application Auto Scaling:
yamlResources: ScalableTarget: Type: AWS::ApplicationAutoScaling::ScalableTarget Properties: MaxCapacity: 10 MinCapacity: 1 ResourceId: !Sub "service/${ECSCluster}/${ECSService}" ScalableDimension: ecs:service:DesiredCount ServiceNamespace: ecs ScalingPolicy: Type: AWS::ApplicationAutoScaling::ScalingPolicy Properties: PolicyName: !Sub "${AWS::StackName}-scaling" PolicyType: TargetTrackingScaling ScalingTargetId: !Ref ScalableTarget TargetTrackingScalingPolicyConfiguration: TargetValue: 70.0 PredefinedMetricSpecification: PredefinedMetricType: ECSServiceAverageCPUUtilization
Enable CloudWatch Container Insights:
yamlResources: LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/ecs/${AWS::StackName}" RetentionInDays: 7
Before deployment: Create a change set to preview changes:
bashaws cloudformation create-change-set \ --stack-name my-ecs-stack \ --template-body file://template.yaml \ --change-set-type CREATE aws cloudformation execute-change-set --change-set-name <arn>
Family naming for version tracking and immutable deploymentsHealthCheck in container definitions for ECS health monitoringCpu and Memory at task level for FargateDeploymentCircuitBreaker for automatic rollback on failuresHealthCheckGracePeriodSeconds matching application startup timeMinimumHealthyPercent (100) and MaximumPercent (200) for zero-downtime updatesawsvpc network mode for FargateMaxHealthyDuration on capacity provider strategy for Spot interruption handlingSTEADY_STATE failures in CloudWatch for task startup issuesDesiredCount updates during deployment may conflict with auto scaling policies!GetAtt for referencing stack outputs in same templateFn::Sub with stack name for portabilityyamlAWSTemplateFormatVersion: "2010-09-09" Description: Minimal ECS Fargate service Resources: Cluster: Type: AWS::ECS::Cluster Properties: ClusterName: !Sub "${AWS::StackName}-cluster" TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: !Sub "${AWS::StackName}-task" NetworkMode: awsvpc RequiresCompatibilities: [FARGATE] Cpu: 256 Memory: 512 ContainerDefinitions: - Name: app Image: nginx:latest PortMappings: - ContainerPort: 80 Service: Type: AWS::ECS::Service Properties: Cluster: !Ref Cluster ServiceName: !Sub "${AWS::StackName}-svc" TaskDefinition: !Ref TaskDefinition DesiredCount: 2 LaunchType: FARGATE DeploymentCircuitBreaker: Enable: true Rollback: true
yamlResources: Service: Type: AWS::ECS::Service Properties: Cluster: !Ref ECSCluster TaskDefinition: !Ref TaskDefinition DesiredCount: 2 LaunchType: FARGATE HealthCheckGracePeriodSeconds: 30 NetworkConfiguration: AwsvpcConfiguration: Subnets: [!Ref PrivateSubnet1, !Ref PrivateSubnet2] SecurityGroups: [!Ref TaskSecurityGroup] LoadBalancers: - TargetGroupArn: !Ref TargetGroup ContainerName: app ContainerPort: 8080 TargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 80 Protocol: HTTP VpcId: !Ref VPC TargetType: ip HealthCheckPath: /health
For detailed implementation guidance, see:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-12 | pass→pass | 10,096 | 7,979 | -21% | 1 | 1 | 0% | 2,032 | 4,669 | +130% | 0 | 0 | — |
case-01 | fail→fail | 22,293 | 17,276 | -23% | 1 | 1 | 0% | 4,949 | 6,881 | +39% | 0 | 0 | — |
case-02 | fail→fail | 9,757 | 7,837 | -20% | 1 | 1 | 0% | 1,762 | 4,600 | +161% | 0 | 0 | — |
case-03 | pass→pass | 5,010 | 3,555 | -29% | 1 | 1 | 0% | 841 | 3,722 | +343% | 0 | 0 | — |
case-04 | pass→pass | 9,546 | 8,870 | -7% | 1 | 1 | 0% | 1,695 | 4,697 | +177% | 0 | 0 | — |
case-05 | pass→pass | 12,459 | 9,991 | -20% | 1 | 1 | 0% | 2,473 | 5,230 | +111% | 0 | 0 | — |
case-06 | fail→pass | 9,658 | 9,242 | -4% | 1 | 1 | 0% | 1,785 | 4,936 | +177% | 0 | 0 | — |
case-07 | pass→pass | 12,494 | 10,388 | -17% | 1 | 1 | 0% | 2,099 | 4,974 | +137% | 0 | 0 | — |
case-08 | pass→pass | 8,843 | 6,404 | -28% | 1 | 1 | 0% | 1,465 | 4,214 | +188% | 0 | 0 | — |
case-09 | pass→pass | 9,095 | 7,247 | -20% | 1 | 1 | 0% | 1,725 | 4,543 | +163% | 0 | 0 | — |
case-10 | fail→fail | 14,330 | 12,095 | -16% | 1 | 1 | 0% | 2,372 | 5,441 | +129% | 0 | 0 | — |
case-11 | fail→fail | 10,716 | 8,486 | -21% | 1 | 1 | 0% | 1,804 | 4,612 | +156% | 0 | 0 | — |
case-13 | pass→pass | 5,401 | 5,971 | +11% | 1 | 1 | 0% | 908 | 4,214 | +364% | 0 | 0 | — |
case-14 | pass→pass | 14,291 | 5,845 | -59% | 1 | 1 | 0% | 2,539 | 4,183 | +65% | 0 | 0 | — |
case-15 | pass→pass | 7,010 | 4,926 | -30% | 1 | 1 | 0% | 1,241 | 4,060 | +227% | 0 | 0 | — |
case-16 | pass→pass | 15,444 | 13,367 | -13% | 1 | 1 | 0% | 2,940 | 5,735 | +95% | 0 | 0 | — |
case-17 | pass→pass | 5,687 | 1,720 | -70% | 1 | 1 | 0% | 607 | 3,388 | +458% | 0 | 0 | — |
case-18 | pass→pass | 10,612 | 6,535 | -38% | 1 | 1 | 0% | 1,711 | 4,205 | +146% | 0 | 0 | — |
case-19 | fail→pass | 11,093 | 5,466 | -51% | 1 | 1 | 0% | 1,841 | 4,063 | +121% | 0 | 0 | — |
case-20 | pass→pass | 5,880 | 6,053 | +3% | 1 | 1 | 0% | 1,197 | 4,408 | +268% | 0 | 0 | — |
case-21 | pass→pass | 8,712 | 7,833 | -10% | 1 | 1 | 0% | 1,658 | 4,653 | +181% | 0 | 0 | — |
case-22 | pass→pass | 9,315 | 10,613 | +14% | 1 | 1 | 0% | 1,871 | 5,331 | +185% | 0 | 0 | — |
case-23 | pass→pass | 11,358 | 8,938 | -21% | 1 | 1 | 0% | 2,076 | 4,930 | +137% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.