Automating .NET ECS Deployment with Boto3 and EventBridge

Deploying containerized applications on AWS ECS can be a tedious, multi-step process. Between setting up IAM roles, creating repositories, configuring clusters, and scheduling tasks, there’s a lot of moving parts. To streamline this, I built a Python deployment script using Boto3 that automates the entire process from Docker build to scheduled execution with Amazon EventBridge.

Overview of the Workflow

The script covers the following:

  • Ensures IAM roles exist with the right policies
  • Creates or resets an Amazon ECR repository
  • Builds and pushes a Docker image
  • Creates a CloudWatch Logs group for container logging
  • Creates an ECS cluster (if missing)
  • Registers a new ECS Fargate task definition
  • Deregisters old task definitions
  • Stops old running ECS tasks
  • Creates or updates an EventBridge schedule to trigger ECS tasks

IAM Roles and Permissions

The first step in ECS deployments is to make sure ECS tasks can assume the right IAM roles. The script ensures that:

  • ecsTaskExecutionRole is created with the AmazonECSTaskExecutionRolePolicy attached.
  • ecsTaskRole is created with AdministratorAccess (for testing; should be more restrictive in production).
  • An inline policy is added to allow s3:PutObject for a specific S3 bucket.
def ensure_iam_role(role_name, assume_role_service, s3_bucket):
    ...
    iam.create_role(...)
    iam.attach_role_policy(...)
    iam.put_role_policy(...)

Why it matters: Without proper IAM roles, ECS tasks can’t pull images from ECR or send logs to CloudWatch.

Handling Networking

The function ensure_outbound_rule() makes sure the assigned Security Group allows outbound traffic to the internet. This is critical for containers that need to fetch dependencies or communicate externally.

Building and Pushing the Docker Image

After setting up IAM and networking, the script deletes and recreates the ECR repository, logs in with Docker, builds the image from the local Dockerfile, tags it, and pushes it to ECR.

subprocess.run(["docker", "build", "-t", f"{ECR_REPO_NAME}:{IMAGE_TAG}", DOCKERFILE_DIR], check=True)
subprocess.run(["docker", "tag", ...], check=True)
subprocess.run(["docker", "push", ...], check=True)

Tip: The script always rebuilds and pushes the image, ensuring the cluster always runs the latest code.

Creating the ECS Cluster and Task Definition

The cluster is created if it doesn’t exist. Then a new task definition is registered, pointing to the Docker image. It specifies 1 vCPU, 4 GB memory, and a CloudWatch Logs configuration.

ecs.register_task_definition(
    family=ECS_TASK_DEF_NAME,
    networkMode='awsvpc',
    requiresCompatibilities=['FARGATE'],
    cpu='1024',
    memory='4096',
    containerDefinitions=[{
        'name': CONTAINER_NAME,
        'image': image_uri,
        'command': ["python3", "run_tests.py"]
    }]
)

Key design choice: Each deployment creates a new revision of the task definition. Old definitions are automatically deregistered to keep the account clean.

Cleaning Up Old Tasks

Any ECS tasks running an outdated task definition are stopped to prevent resource leaks and ensure consistency.

Scheduling with EventBridge

The script integrates with Amazon EventBridge to run the ECS task on a cron schedule. It creates the rule if it doesn’t exist, ensures EventBridge has an IAM role to run ECS tasks, and updates the target to point to the latest task definition.

events.put_rule(
    Name=EVENTBRIDGE_RULE_NAME,
    ScheduleExpression='cron(59 23 ? * SUN *)',
    State='ENABLED'
)

response = events.put_targets(
    Rule=event_rule_name,
    Targets=[{
        'Arn': f'arn:aws:ecs:{AWS_REGION}:{AWS_ACCOUNT_ID}:cluster/{ECS_CLUSTER_NAME}',
        'EcsParameters': {
            'TaskDefinitionArn': task_def_arn,
            'LaunchType': 'FARGATE',
            'NetworkConfiguration': {...}
        }
    }]
)

Benefit: This allows fully automated, recurring execution of the container without manual intervention.

Diagnostics and Debugging

To help with visibility, the script includes dump_eventbridge_targets() which prints the current EventBridge targets. This is useful when debugging why a scheduled task didn’t fire.

Final Thoughts

This deployment script ties together IAM, ECR, ECS, CloudWatch Logs, and EventBridge into a single repeatable workflow. It’s designed for automation — making deployments fast, reliable, and easy to repeat.

Key Takeaways

  • Always verify IAM roles and permissions first — most ECS errors trace back to IAM issues.
  • Rebuilding and pushing Docker images on every run ensures reproducibility.
  • Use EventBridge rules for fully automated scheduled ECS workloads.
  • Deregister old task definitions and stop outdated tasks to keep environments clean.

With this script, you can deploy .NET (or any containerized app) to AWS ECS Fargate with confidence, while also ensuring that scheduled tasks continue to run seamlessly.

Comments

Popular posts from this blog

Building and Deploying a Fargate Container that runs Python and performs CloudWatch Logging

Automate Your API Gateway Setup with Boto3: Rendering HTML from Lambda

Setting up an AWS Cognito User Pool and building a React login component