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 ¶
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
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 |
|||||
|
type |
object |
|||
#/definitions/VpcLookup |
|||||
|
type |
object |
|||
#/definitions/VpcCreate |
|||||
oneOf |
type |
object |
|||
type |
object |
||||
definitions |
|||||
|
type |
object |
|||
properties |
|||||
|
x-resources.common.spec.json#/definitions/Lookup |
||||
|
x-resources.common.spec.json#/definitions/Lookup |
||||
|
x-resources.common.spec.json#/definitions/Lookup |
||||
|
x-resources.common.spec.json#/definitions/Lookup |
||||
|
type |
string |
|||
patternProperties |
|||||
|
x-resources.common.spec.json#/definitions/Lookup |
||||
|
type |
object |
|||
properties |
|||||
|
format |
ipv4 |
|||
|
If true, will create only 1 NAT Gateway for all subnets. Saves costs. Mutually exclusive with DisableNat |
||||
type |
boolean |
||||
default |
False |
||||
|
If true, won’t create any NAT. Mutually exclusive with SingleNat |
||||
type |
boolean |
||||
default |
False |
||||
|
type |
object |
|||
properties |
|||||
|
|||||
type |
string |
||||
additionalProperties |
False |
||||
|
type |
object |
|||
properties |
|||||
|
type |
array |
|||
items |
type |
object |
|||
|
type |
boolean |
|||
|
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.