Posted on

Running services on Fargate without giving them public Internet access

This post enumerates some critical points on running containerized services on AWS Fargate with restricted access to the public Internet.

VPC Endpoints

Such setup depends on the following VPC endpoints:

See https://docs.aws.amazon.com/AmazonECR/latest/userguide/vpc-endpoints.html.

S3Endpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcId: !Ref VPC
    ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
    VpcEndpointType: Gateway
    RouteTableIds:
      - !Ref RouteTable

ECRDockerEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcId: !Ref VPC
    ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.dkr"
    VpcEndpointType: Interface
    PrivateDnsEnabled: true
    SubnetIds:
      - !Ref Subnet1
      - !Ref Subnet2
    SecurityGroupIds:
      - !Ref VPCEndpointSecurityGroup

ECRAPIEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcId: !Ref VPC
    ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.api"
    VpcEndpointType: Interface
    PrivateDnsEnabled: true
    SubnetIds:
      - !Ref Subnet1
      - !Ref Subnet2
    SecurityGroupIds:
      - !Ref VPCEndpointSecurityGroup

CloudWatchLogsEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcId: !Ref VPC
    ServiceName: !Sub "com.amazonaws.${AWS::Region}.logs"
    VpcEndpointType: Interface
    PrivateDnsEnabled: true
    SubnetIds:
      - !Ref Subnet1
      - !Ref Subnet2
    SecurityGroupIds:
      - !Ref VPCEndpointSecurityGroup

VPCEndpointSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: VPC endpoints
    VpcId: !Ref VPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIp: !GetAtt VPC.CidrBlock

ECS Execution Role

Service execution role must explicitly allow access to S3 bucket holding ECR data:

ExecutionRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Action: sts:AssumeRole
          Principal:
            Service: ecs-tasks.amazonaws.com
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
    Policies:
      - PolicyName: ecr-s3-access
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: Allow
              Action: s3:GetObject
              Resource: !Sub "arn:aws:s3:::prod-${AWS::Region}-starport-layer-bucket/*"

Security Group

Service security group egress must allow access to VPC CIDR.

To allow S3 access via its VPC gateway endpoint (required to pull container images) security group has to permit access to AWS-managed region-specific prefix list for S3. This prefix list ID can be found in AWS VPC console under “Managed Prefix Lists” section.

ServiceSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Service without Internet access
    VpcId: !Ref VPC
    SecurityGroupEgress:
      - IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        CidrIp: !GetAtt VPC.CidrBlock
      - IpProtocol: tcp
        FromPort: 443
        ToPort: 443
        # region-specific managed prefix list for s3
        DestinationPrefixListId: pl-63a5400a