AWS VPC to ECS – Day 2: Internet Gateway, Public Route Table & ECR Repository



This content originally appeared on DEV Community and was authored by Utkarsh Rastogi

Welcome back to our “AWS VPC to ECS with CloudFormation” series, which is on its second day!

We constructed the VPC and subnets on Day 1, which you can catch up on here:
🔗 Day 1: AWS VPC Basics with CloudFormation

We’ll set up a Elastic Container Registry (ECR) to house our container images and enable our VPC to communicate with the internet today.

📌 What We’ll Build Today

By the end of this post, you will:

  • Attach an Internet Gateway to your VPC
  • Create a Public Route Table and link it to your public subnets
  • Create an ECR Repository for storing Docker images

Internet Gateway (IGW)

An Internet Gateway can be thought of as the primary gateway that connects your VPC to the internet.

Without it, you’re stranded on a remote island with no supplies.

AWSTemplateFormatVersion: "2010-09-09"
Description: "Creating Internet Gateway for Learning Purpose"
Parameters:
  VPC:
    Type: AWS::SSM::Parameter::Value<String>
    Description: VPC ID
    Default: "/learner/vpcid"
  TeamNameValue:
    Type: String
    Description: TeamName Tag Value
    Default: "awslearner"
  EnvironmentValue:
    Type: String
    Description: Environment Tag Value
    Default: "dev"
  SSMName:
    Type: String
    Description:  IGW
    Default: "/learner/igw"

Resources:
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentValue}internetgateway
        - Key: TeamName
          Value: !Ref TeamNameValue
        - Key: Environment
          Value: !Ref EnvironmentValue

  InternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    DependsOn: InternetGateway
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  SSMParameter:
    Type: "AWS::SSM::Parameter"
    DependsOn: InternetGatewayAttachment
    Properties:
      Name: !Ref SSMName
      Type: "String"
      Value: !Ref InternetGateway 
      Description: "IGW"
      Tags:
        Name: !Ref SSMName
        TeamName: !Ref TeamNameValue
        Environment: !Ref EnvironmentValue

Outputs:
  InternetGatewayDetails:
    Description: IGW Details
    Value: !Ref InternetGateway

Deployment

aws cloudformation deploy \
  --template-file internet_gateway.yaml \
  --stack-name AWSLearner-IGW-Stack \
  --capabilities CAPABILITY_NAMED_IAM

Public Route Table

The Route Table determines the path of network traffic.

To enable our public subnet to send and receive internet traffic, we will in this instance establish a Public Route Table.

A rule that routes all internet traffic (0.0.0.0/0) through our Internet Gateway (IGW) will be added.

AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS CloudFormation template to create a public route table and associate it with an internet gateway and a public subnet'

Parameters:
  VpcId:
    Type: AWS::SSM::Parameter::Value<String>
    Description: VPC ID
    Default: "/learner/vpcid"
  InternetGatewayId:
    Type: AWS::SSM::Parameter::Value<String>
    Description: ID of the Internet Gateway to associate with the route table
    Default: "/learner/igw"
  PublicSubnetId:
    Type: AWS::SSM::Parameter::Value<String>
    Description: Subnet ID to associate with the route table
    Default: "/learner/public/subnetids"
  PublicRouteTableName:
    Type: String
    Description: Name Tag Value
    Default: "awslearner-publicroutetable"
  TeamNameValue:
    Type: String
    Description: TeamName Tag Value
    Default: "awslearner"
  EnvironmentValue:
    Type: String
    Description: Environment Tag Value
    Default: "dev"

Resources:
  PublicRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VpcId
      Tags:
        - Key: Name
          Value: !Ref PublicRouteTableName
        - Key: TeamName
          Value: !Ref TeamNameValue
        - Key: Environment
          Value: !Ref EnvironmentValue

  InternetGatewayRoute:
    Type: 'AWS::EC2::Route'
    DependsOn: PublicRouteTable
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGatewayId

  PublicSubnetRouteTableAssociation:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Select 
        - 0
        - !Split 
          - ","
          - !Ref PublicSubnetId
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetRouteTableAssociation1:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Select 
        - 1
        - !Split 
          - ","
          - !Ref PublicSubnetId
      RouteTableId: !Ref PublicRouteTable

Outputs:
  RouteTableId:
    Description: The ID of the created public route table
    Value: !Ref PublicRouteTable

Deployment

aws cloudformation deploy \
  --template-file public_route_table.yaml \
  --stack-name AWSLearner-PRT-Stack \
  --capabilities CAPABILITY_NAMED_IAM

Elastic Container Registry (ECR)

Prior to deploying our Docker images to ECS, we require a location to store them.

Securely storing, managing, and deploying container images is made simple with AWS’s fully-managed, private container registry, Amazon ECR (Elastic Container Registry), which works smoothly with ECS.

Why use ECR?

  • Private, secure storage for Docker images.
  • Integrates directly with ECS and IAM for permissions.
  • Supports image versioning and lifecycle policies.

We’ll create an ECR repository to store our application’s Docker image before deploying it to our ECS service.

AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS CloudFormation template to create  ECR Repository'

Parameters:
  TeamNameValue:
    Type: String
    Description: TeamName Tag Value
    Default: "awslearner"
  EnvironmentValue:
    Type: String
    Description: Environment Tag Value
    Default: "dev"
  RepositoryName:
    Type: String
    Description: Name of the ECR Repository
    Default: "learner-ecr"


Resources:
  MyECRRepository:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: !Ref RepositoryName
      LifecyclePolicy:
        LifecyclePolicyText: |
          {
            "rules": [
              {
                "rulePriority": 1,
                "description": "Keep only latest 1 image",
                "selection": {
                  "tagStatus": "any",
                  "countType": "imageCountMoreThan",
                  "countNumber": 1
                },
                "action": {
                  "type": "expire"
                }
              }
            ]
          }
        RegistryId: !Ref AWS::AccountId
      Tags:
        - Key: Name
          Value: !Ref RepositoryName
        - Key: TeamName
          Value: !Ref TeamNameValue
        - Key: Environment
          Value: !Ref EnvironmentValue

Deployment

aws cloudformation deploy \
  --template-file ecr.yaml \
  --stack-name AWSLearner-ECR-Stack  \
  --capabilities CAPABILITY_NAMED_IAM

📝 Recap

Today, we:

  • For our public resources to have internet access, we set up a Public Route Table and connected it to our Internet Gateway.
  • We set up a Elastic Container Registry (ECR) in AWS to safely store our Docker images.

📢 Stay tuned for the next part

💡 To understand how to set up VPC → ECS step-by-step using distinct YAML files for each AWS resource, follow this series.

📬 Please remember to bookmark this blog series, share it with your cloud friends, and if you found it helpful, leave a remark 💬 and a like 👍.

Your criticism inspires me to produce more hands-on AWS content and helps me get better! 🚀

👨‍💻 About Me

Hi! I’m Utkarsh, a Cloud Specialist & AWS Community Builder who loves turning complex AWS topics into fun chai-time stories ☕

👉 Explore more


This content originally appeared on DEV Community and was authored by Utkarsh Rastogi