Attention

For production workloads, we recommend to use an existing VPC using Lookup .

x-vpc

x-vpc:
  Properties: {}
  Lookup: {}

Allows you to create / lookup an AWS VPC to deploy your services into. When using Lookup , you simply identify the VPC and the subnets you then place the services and AWS Resources into.

If x-vpc is not specified, ECS Compose-X will try to figure out whether a new VPC should be created for the given services. For instance, if using ECS Anywhere and have no services in AWS VPC, the VPC won’t be created.

Tip

To see how to override the subnets to use for services, see networks

Properties

Create example with a single NAT and 3 VPC Endpoints
x-vpc:
  Properties:
    SingleNat: true
    VpcCidr: 172.6.42.0/24
    Endpoints:
      AwsServices:
        - service: s3
        - service: ecr.api
        - service: ecr.dkr

VpcCidr

The CIDR you want to use. Default is 100.127.254.0/24 .

SingleNat

Whether you want to have 1 NAT per AZ for your application subnets. Reduces the costs for dev environments!

DisableNat

When you deploy services that will be in the public subnets only, you might not need a NAT at all. Disabling it can save you the costs of the NAT that wouldn’t be used.

Note

If you want your services to be public facing with the awsvpc networking mode, make sure to enable AssignPublicIp

Tip

See Deploy services with EIP on public subnets to have a full example of how to implement this feature.

Endpoints

List of VPC Endpoints from AWS Services you want to create. Default will create Endpoints for ECR (DKR and API).

EnableFlowLogs

Whether you want to have a VPC Flow Log created for the VPC. It will create a new LogGroup and IAM Role to allow logging to CloudWatch.

FlowLogsRoleBoundary

For those of you who require IAM PermissionsBoundary for your IAM Roles, this allows to set the boundary. If it starts with arn:aws it will assume this is a valid ARN, otherwise, it will use the value as policy name.

Lookup

x-vpc:
  Lookup:
    VpcId:
      Tags:
        - key: value
    PublicSubnets:
      Tags:
        - vpc::usage: public
    AppSubnets:
      Tags:
        - vpc::usage: application
    StorageSubnets:
      Tags:
        - vpc::usage: storage0

Warning

When using Use or Lookup you MUST define all 4 settings: * VpcId * StorageSubnets * AppSubnets * PublicSubnets

Warning

When creating newly defined subnets groups, the name must be in the format ^[a-zA-Z0-9]+$

Hint

You can define extra subnet groups based on different tags and map them to your services for override when using Lookup or Use

Extra subnets definition
x-vpc:
  Lookup:
    VpcId: {}
    AppSubnets: {}
    StorageSubnets: {}
    PublicSubnets: {}
    Custom01:
      Tags: {}

networks:
  custom01:
    x-vpc: Custom01


services:
  serviceA:
    networks:
      - custom01

Default VPC Network design

The design of the VPC generated is very simple 3-tiers:

  • Public subnets, 1/4 of the available IPs of the VPC CIDR Range

  • Storage subnets, 1/4 of the available IPs of the VPC CIDR Range

  • Application subnets, 1/2 of the available IPs of the VPC CIDR Range

Default range

The default CIDR range for the VPC is 100.127.254.0/24 This leaves a just under 120 IP address for the EC2 hosts and/or Docker containers.

Hint

The range can be changed via VpcCidr but not the structure detailed above. Works for all RFC 1918 and the 100.64.0.0/10 ranges.

JSON Schema

Model

x-vpc

x-vpc.spec.json

x-vpc specification

type

object

properties

  • Lookup

type

object

#/definitions/VpcLookup

  • Properties

type

object

#/definitions/VpcCreate

oneOf

type

object

type

object

definitions

  • VpcLookup

type

object

properties

  • VpcId

x-resources.common.spec.json#/definitions/Lookup

  • AppSubnets

x-resources.common.spec.json#/definitions/Lookup

  • StorageSubnets

x-resources.common.spec.json#/definitions/Lookup

  • PublicSubnets

x-resources.common.spec.json#/definitions/Lookup

  • RoleArn

type

string

patternProperties

  • \b(?!RoleArn\b)\w+

x-resources.common.spec.json#/definitions/Lookup

  • VpcCreate

type

object

properties

  • VpcCidr

format

ipv4

  • SingleNat

If true, will create only 1 NAT Gateway for all subnets. Saves costs. Mutually exclusive with DisableNat

type

boolean

default

False

  • DisableNat

If true, won’t create any NAT. Mutually exclusive with SingleNat

type

boolean

default

False

  • DHCPOptions

type

object

properties

  • DomainName

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcpoptions.html#cfn-ec2-dhcpoptions-domainname

type

string

additionalProperties

False

  • Endpoints

type

object

properties

  • AwsServices

type

array

items

type

object

  • EnableFlowLogs

type

boolean

  • FlowLogsRoleBoundary

type

string

additionalProperties

False

oneOf

not

not

allOf

not

not

Definition

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "id": "x-vpc.spec.json",
  "$id": "x-vpc.spec.json",
  "title": "x-vpc",
  "description": "x-vpc specification",
  "type": "object",
  "properties": {
    "Lookup": {
      "type": "object",
      "$ref": "#/definitions/VpcLookup"
    },
    "Properties": {
      "type": "object",
      "$ref": "#/definitions/VpcCreate"
    }
  },
  "oneOf": [
    {
      "type": "object",
      "required": [
        "Lookup"
      ]
    },
    {
      "type": "object",
      "required": [
        "Properties"
      ]
    }
  ],
  "definitions": {
    "VpcLookup": {
      "type": "object",
      "required": [
        "VpcId",
        "AppSubnets",
        "PublicSubnets",
        "StorageSubnets"
      ],
      "properties": {
        "VpcId": {
          "$ref": "x-resources.common.spec.json#/definitions/Lookup"
        },
        "AppSubnets": {
          "$ref": "x-resources.common.spec.json#/definitions/Lookup"
        },
        "StorageSubnets": {
          "$ref": "x-resources.common.spec.json#/definitions/Lookup"
        },
        "PublicSubnets": {
          "$ref": "x-resources.common.spec.json#/definitions/Lookup"
        },
        "RoleArn": {
          "type": "string"
        }
      },
      "patternProperties": {
        "\\b(?!RoleArn\\b)\\w+": {
          "$ref": "x-resources.common.spec.json#/definitions/Lookup"
        }
      }
    },
    "VpcCreate": {
      "additionalProperties": false,
      "type": "object",
      "oneOf": [
        {
          "required": [
            "SingleNat"
          ],
          "not": {
            "required": [
              "DisableNat"
            ]
          }
        },
        {
          "required": [
            "DisableNat"
          ],
          "not": {
            "required": [
              "SingleNat"
            ]
          }
        },
        {
          "allOf": [
            {
              "not": {
                "required": [
                  "DisableNat"
                ]
              }
            },
            {
              "not": {
                "required": [
                  "SingleNat"
                ]
              }
            }
          ]
        }
      ],
      "properties": {
        "VpcCidr": {
          "format": "ipv4"
        },
        "SingleNat": {
          "type": "boolean",
          "description": "If true, will create only 1 NAT Gateway for all subnets. Saves costs. Mutually exclusive with DisableNat",
          "default": false
        },
        "DisableNat": {
          "type": "boolean",
          "description": "If true, won't create any NAT. Mutually exclusive with SingleNat",
          "default": false
        },
        "DHCPOptions": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "DomainName": {
              "type": "string",
              "description": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcpoptions.html#cfn-ec2-dhcpoptions-domainname"
            }
          }
        },
        "Endpoints": {
          "type": "object",
          "properties": {
            "AwsServices": {
              "type": "array",
              "items": {
                "type": "object"
              }
            }
          }
        },
        "EnableFlowLogs": {
          "type": "boolean"
        },
        "FlowLogsRoleBoundary": {
          "type": "string"
        }
      }
    }
  }
}

Test files

You can find the test files here to use as reference for your use-case.