Some text some message..
Back 5. AWS INFRA PIPELINE: ECS SERVICE 12 Nov, 2025

### ECS Service

  ECSService:

    Type: AWS::ECS::Service

    DependsOn: AttachGateway

    Properties:

      ServiceName: document-portal-service

      Cluster: !Ref ECSCluster

      LaunchType: FARGATE

      DesiredCount: 1

      NetworkConfiguration:

        AwsvpcConfiguration:

          AssignPublicIp: ENABLED

          Subnets:

            - !Ref Subnet1

            - !Ref Subnet2

          SecurityGroups:

            - !Ref ECSSecurityGroup

      TaskDefinition: !Ref ECSTaskDefinition

Outputs:

  ECSClusterName:

    Value: !Ref ECSCluster

  TaskDefinitionArn:

    Value: !Ref ECSTaskDefinition



🔧 ECS Service — what it creates and why

ECSService:
  Type: AWS::ECS::Service
  DependsOn: AttachGateway
  • Type: AWS::ECS::Service — creates a running service which ensures your task(s) stay up and (optionally) register with a load balancer.

  • DependsOn: AttachGateway — CloudFormation will wait for the Internet Gateway attachment to complete before creating the service. This matters because your tasks are configured to get public IPs, and the IGW/route needs to exist for internet connectivity.


Properties — line by line

Properties:
  ServiceName: document-portal-service
  • Friendly name in the console for the service.

  Cluster: !Ref ECSCluster
  • Tells ECS which cluster the service should run in (the cluster you created earlier).

  LaunchType: FARGATE
  • Uses Fargate (serverless containers). You don't manage EC2 instances — AWS provisions the ENIs and infra for you.

  DesiredCount: 1
  • The service will try to keep 1 task running. If it crashes, ECS will launch another to maintain this count.

  • For HA, you’ll likely want DesiredCount >= 2 across AZs or set up an autoscaling policy.


Network configuration (very important)

  NetworkConfiguration:
    AwsvpcConfiguration:
      AssignPublicIp: ENABLED
      Subnets:
        - !Ref Subnet1
        - !Ref Subnet2
      SecurityGroups:
        - !Ref ECSSecurityGroup
  • NetworkMode = awsvpc (from task definition) + this section means:

    • Each task gets its own ENI (Elastic Network Interface) and private IP within the specified subnets.

    • AssignPublicIp: ENABLED means each task’s ENI also gets a public IP assigned. That makes the task directly reachable from the internet (subject to security group rules and routing).

    • Subnets: the task ENIs will be created in the listed subnets (you gave two — AZ spread). ECS will place tasks across the subnets for availability.

    • SecurityGroups: the ENIs will use this security group (you earlier opened port 8080 to 0.0.0.0/0).

Implications & cautions:

  • Assigning public IPs to tasks exposes them directly to the internet. This is simpler but less secure than placing tasks in private subnets and fronting them with an Application Load Balancer (ALB).

  • Common, more secure pattern:

    • Put tasks in private subnets (no public IP).

    • Create an ALB in public subnets that receives internet traffic and forwards to tasks in private subnets (ALB has public IPs; tasks do not).

    • Security groups: ALB SG allows 80/443 from internet; task SG allows traffic only from ALB SG.

  • If you keep AssignPublicIp: ENABLED, lock down the security group to only required sources (avoid 0.0.0.0/0 unless absolutely needed).


  TaskDefinition: !Ref ECSTaskDefinition
  • Points the service to the task definition revision to run (the blueprint you defined earlier).


❗ What this service will (not) do by default

  • This service will run tasks and restart them if they fail to maintain DesiredCount.

  • It will not:

    • Create or register a Load Balancer (unless you add LoadBalancers + Role properties).

    • Configure automatic scaling (you must add ECS Service Auto Scaling).

    • Perform application-level health checks unless you integrate a load balancer or configure healthCheckGracePeriodSeconds and proper task health checks.


✅ Recommended improvements (practical)

  1. Use an ALB + private tasks

    • Add an Application Load Balancer in public subnets, target group pointing to tasks (port 8080), and set AssignPublicIp: DISABLED.

    • Secure traffic with security groups: ALB SG (internet → ALB), Task SG (ALB SG → tasks). This is standard production pattern.

  2. Enable high availability

    • DesiredCount: 2 (or use an autoscaling policy) so tasks run across both subnets/AZs.

  3. Add health checks

    • If using ALB, configure health checks (path, interval, healthy/unhealthy thresholds).

    • Optionally set healthCheckGracePeriodSeconds for startup time.

  4. Service Auto Scaling

    • Add AWS::ApplicationAutoScaling::ScalingPolicy and ScalableTarget to scale tasks based on CPU/RAM or custom CloudWatch metrics.

  5. Use Deployment Configuration

    • Control deployment strategy (minimum healthy percent, maximum percent) to avoid downtime during updates.

  6. Consider a Service Role

    • If you register with load balancer, ECS may need an Role (service-linked role or Role property depending on deployment). CloudFormation often creates an AutomaticIAMRole but check docs and permissions.

  7. Logging and Monitoring

    • Ensure CloudWatch Logs, Container Insights, and ALB access logs are enabled for observability.


🧾 Outputs — what they return after deployment

Outputs:
  ECSClusterName:
    Value: !Ref ECSCluster

  TaskDefinitionArn:
    Value: !Ref ECSTaskDefinition
  • ECSClusterName — exports the cluster name (the logical id you created). Handy to show in stack outputs or reference in other stacks (you can add Export: Name: if you want cross-stack usage).

  • TaskDefinitionArn — returns the task definition revision ARN or family:revision (the CloudFormation Ref for a task definition returns the task definition ARN). Useful for CI/CD pipelines to know which task definition is deployed.


TL;DR — plain language

  • You’ve defined a service that runs your container on Fargate, keeps 1 copy running, places the task ENIs in two subnets, and gives them public IPs so they are reachable from the internet.

  • That works for quick testing, but for production:

    • prefer private tasks + ALB,

    • increase redundancy (DesiredCount or autoscaling),

    • add health checks and tighter security group rules,

    • and integrate autoscaling and deployment configuration for smooth updates.