Created
March 15, 2018 19:43
-
-
Save mwarkentin/4c5748b585d63a74080df98daac05313 to your computer and use it in GitHub Desktop.
Convox yml conversion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: '2010-09-09' | |
Conditions: | |
Autoscale: !Equals | |
- !Ref 'Autoscale' | |
- 'Yes' | |
BlankAmi: !Equals | |
- !Ref 'Ami' | |
- '' | |
BlankBuildImage: !Equals | |
- !Ref 'BuildImage' | |
- '' | |
BlankExistingVpc: !Equals | |
- !Ref 'ExistingVpc' | |
- '' | |
BlankExistingVpcAndThirdAvailabilityZone: !And | |
- !Condition 'BlankExistingVpc' | |
- !Condition 'ThirdAvailabilityZone' | |
BlankInstanceBootCommand: !Equals | |
- !Ref 'InstanceBootCommand' | |
- '' | |
BlankInstanceRunCommand: !Equals | |
- !Ref 'InstanceRunCommand' | |
- '' | |
BlankInstanceSecurityGroup: !Equals | |
- !Ref 'InstanceSecurityGroup' | |
- '' | |
BlankInternetGateway: !Equals | |
- !Ref 'InternetGateway' | |
- '' | |
BlankKey: !Equals | |
- !Ref 'Key' | |
- '' | |
BlankLogBucket: !Equals | |
- !Ref 'LogBucket' | |
- '' | |
DedicatedBuilder: !Not | |
- !Equals | |
- !Ref 'BuildInstance' | |
- '' | |
Development: !Equals | |
- !Ref 'Development' | |
- 'Yes' | |
EncryptEbs: !Equals | |
- !Ref 'EncryptEbs' | |
- 'Yes' | |
ExistingVpc: !Not | |
- !Equals | |
- !Ref 'ExistingVpc' | |
- '' | |
ExistingVpcAndBlankInternetGateway: !And | |
- !Condition 'ExistingVpc' | |
- !Condition 'BlankInternetGateway' | |
ExistingVpcAndInternetGateway: !And | |
- !Condition 'ExistingVpc' | |
- !Condition 'InternetGateway' | |
HttpProxy: !Not | |
- !Equals | |
- !Ref 'HttpProxy' | |
- '' | |
Internal: !Equals | |
- !Ref 'Internal' | |
- 'Yes' | |
InternetGateway: !Not | |
- !Equals | |
- !Ref 'InternetGateway' | |
- '' | |
NotExistingVpcAndBlankInternetGateway: !Not | |
- !Condition 'ExistingVpcAndBlankInternetGateway' | |
Private: !Equals | |
- !Ref 'Private' | |
- 'Yes' | |
PrivateAndThirdAvailabilityZone: !And | |
- !Condition 'Private' | |
- !Condition 'ThirdAvailabilityZone' | |
PrivateApi: !Equals | |
- !Ref 'PrivateApi' | |
- 'Yes' | |
RegionHasEFS: !Equals | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- EFS | |
- 'Yes' | |
RegionHasEFSAndThirdAvailabilityZone: !And | |
- !Condition 'RegionHasEFS' | |
- !Condition 'ThirdAvailabilityZone' | |
SpotInstances: !Not | |
- !Equals | |
- !Ref 'SpotInstanceBid' | |
- '' | |
ThirdAvailabilityZone: !And | |
- !Equals | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- ThirdAvailabilityZone | |
- 'Yes' | |
- !Equals | |
- !Ref 'MaxAvailabilityZones' | |
- '3' | |
ThirdAvailabilityZoneAndNotExistingVpcAndBlankInternetGateway: !And | |
- !Condition 'ThirdAvailabilityZone' | |
- !Condition 'NotExistingVpcAndBlankInternetGateway' | |
Mappings: | |
RegionConfig: | |
ap-northeast-1: | |
Ami: ami-bb5f13dd | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '582318560864' | |
Fargate: 'No' | |
ap-northeast-2: | |
Ami: ami-3b19b455 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '600734575887' | |
Fargate: 'No' | |
ap-south-1: | |
Ami: ami-9e91cff1 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '718504428378' | |
Fargate: 'No' | |
ap-southeast-1: | |
Ami: ami-f88ade84 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '114774131450' | |
Fargate: 'No' | |
ap-southeast-2: | |
Ami: ami-a677b6c4 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '783225319266' | |
Fargate: 'No' | |
ca-central-1: | |
Ami: ami-db48cfbf | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '985666609251' | |
Fargate: 'No' | |
eu-central-1: | |
Ami: ami-3b7d1354 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: 054676820928 | |
Fargate: 'No' | |
eu-west-1: | |
Ami: ami-64c4871d | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '156460612806' | |
Fargate: 'No' | |
eu-west-2: | |
Ami: ami-25f51242 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '652711504416' | |
Fargate: 'No' | |
eu-west-3: | |
Ami: ami-0356e07e | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: 009996457667 | |
Fargate: 'No' | |
sa-east-1: | |
Ami: ami-da2c66b6 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '507241528517' | |
Fargate: 'No' | |
us-east-1: | |
Ami: ami-cad827b7 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '127311923021' | |
Fargate: 'Yes' | |
us-east-2: | |
Ami: ami-ef64528a | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: 033677994240 | |
Fargate: 'No' | |
us-west-1: | |
Ami: ami-29b8b249 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: 027434742980 | |
Fargate: 'No' | |
us-west-2: | |
Ami: ami-baa236c2 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '797873946194' | |
Fargate: 'No' | |
Outputs: | |
Autoscale: | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
AutoscaleExtra: | |
Value: !Ref 'AutoscaleExtra' | |
AutoscalingGroup: | |
Value: !Ref 'Instances' | |
AwsRegion: | |
Value: !Ref 'AWS::Region' | |
BuildAutoscalingGroup: | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildInstances' | |
- !Ref 'Instances' | |
BuildCluster: | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
CloudformationTopic: | |
Value: !Ref 'CloudformationTopic' | |
Cluster: | |
Export: | |
Name: !Sub '${AWS::StackName}:Cluster' | |
Value: !Ref 'Cluster' | |
CustomTopic: | |
Value: !GetAtt 'CustomTopic.Arn' | |
Dashboard: | |
Value: !GetAtt 'Balancer.DNSName' | |
Domain: | |
Export: | |
Name: !Sub '${AWS::StackName}:Domain' | |
Value: !GetAtt 'Router.DNSName' | |
DomainInternal: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:DomainInternal' | |
Value: !GetAtt 'RouterInternal.DNSName' | |
DynamoBuilds: | |
Value: !Ref 'DynamoBuilds' | |
DynamoReleases: | |
Value: !Ref 'DynamoReleases' | |
EncryptionKey: | |
Export: | |
Name: !Sub '${AWS::StackName}:EncryptionKey' | |
Value: !Ref 'EncryptionKey' | |
Endpoint: | |
Value: !Sub | |
- rack.${Param1}.${Param2}.convox.site | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
Fargate: | |
Value: !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Fargate | |
Gateway: | |
Condition: BlankExistingVpc | |
Value: !Ref 'Gateway' | |
GatewayAttachment: | |
Condition: BlankExistingVpc | |
Value: !Ref 'GatewayAttachment' | |
HostedZone: | |
Export: | |
Name: !Sub '${AWS::StackName}:HostedZone' | |
Value: !Ref 'HostedZone' | |
InstancesRole: | |
Value: !GetAtt 'InstancesRole.Arn' | |
Internal: | |
Value: !Ref 'Internal' | |
LogBucket: | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
LogGroup: | |
Value: !Ref 'LogGroup' | |
NatGateways: | |
Value: !If | |
- Private | |
- !Sub | |
- ${Nat0},${Nat1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'Nat2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
NatIPs: | |
Value: !If | |
- Private | |
- !Sub | |
- ${NatAddress0},${NatAddress1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'NatAddress2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
NotificationHost: | |
Value: !GetAtt 'Balancer.DNSName' | |
NotificationTopic: | |
Value: !Ref 'NotificationTopic' | |
OnDemandMinCount: | |
Value: !Ref 'OnDemandMinCount' | |
Password: | |
Condition: Development | |
Value: !Ref 'Password' | |
Private: | |
Value: !Ref 'Private' | |
Provider: | |
Condition: Development | |
Value: aws | |
Rack: | |
Value: !Ref 'AWS::StackName' | |
Release: | |
Value: !Ref 'Version' | |
RouterCertificate: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterCertificate' | |
Value: !Ref 'RouterApiCertificate' | |
RouterHost: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterHost' | |
Value: !Sub | |
- ${Param1}.${Param2}.convox.site | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
RouterListener80: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterListener80' | |
Value: !Ref 'RouterListener80' | |
RouterListener443: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterListener443' | |
Value: !Ref 'RouterListener443' | |
RouterInternalHost: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterInternalHost' | |
Value: !Sub | |
- ${Param1}.${Param2}.convox.site | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
RouterInternalListener80: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterInternalListener80' | |
Value: !Ref 'RouterInternalListener80' | |
RouterInternalListener443: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterInternalListener443' | |
Value: !Ref 'RouterInternalListener443' | |
RouteTablePublic: | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Value: !Ref 'Routes' | |
RouteTablesPrivate: | |
Value: !If | |
- Private | |
- !Sub | |
- ${RouteTablePrivate0},${RouteTablePrivate1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'RouteTablePrivate2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
SecurityGroup: | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
ServiceRole: | |
Export: | |
Name: !Sub '${AWS::StackName}:ServiceRole' | |
Value: !GetAtt 'ServiceRole.Arn' | |
SettingsBucket: | |
Value: !Ref 'Settings' | |
SpotInstances: | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
Subnets: | |
Value: !Sub | |
- ${Subnet0},${Subnet1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Subnet0: | |
Export: | |
Name: !Sub '${AWS::StackName}:Subnet0' | |
Value: !Ref 'Subnet0' | |
Subnet1: | |
Export: | |
Name: !Sub '${AWS::StackName}:Subnet1' | |
Value: !Ref 'Subnet1' | |
Subnet2: | |
Condition: ThirdAvailabilityZone | |
Export: | |
Name: !Sub '${AWS::StackName}:Subnet2' | |
Value: !Ref 'Subnet2' | |
SubnetsPrivate: | |
Value: !If | |
- Private | |
- !Sub | |
- ${SubnetPrivate0},${SubnetPrivate1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
StackId: | |
Value: !Ref 'AWS::StackId' | |
Vpc: | |
Export: | |
Name: !Sub '${AWS::StackName}:Vpc' | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Vpccidr: | |
Export: | |
Name: !Sub '${AWS::StackName}:VpcCidr' | |
Value: !Ref 'VPCCIDR' | |
Parameters: | |
Ami: | |
Type: String | |
Description: 'Amazon Machine Image: http://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_container_instance.html' | |
Default: '' | |
ApiCount: | |
Type: String | |
Description: The number of api web processes to run | |
Default: '2' | |
ApiMemory: | |
Type: String | |
Description: How much memory should be reserved by the api web process | |
Default: '256' | |
Autoscale: | |
Type: String | |
Description: Autoscale rack instances | |
Default: 'Yes' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
AutoscaleExtra: | |
Type: Number | |
Description: The number of instances of extra capacity that autoscale should keep | |
running | |
Default: '1' | |
BuildCpu: | |
Type: String | |
Description: How much cpu should be reserved by the builder | |
Default: '0' | |
BuildImage: | |
Type: String | |
Description: Override the default builder image | |
Default: '' | |
BuildInstance: | |
Type: String | |
Description: Instance type for a dedicated build cluster | |
Default: '' | |
BuildMemory: | |
Type: String | |
Description: How much memory should be reserved by the builder | |
Default: '1000' | |
BuildVolumeSize: | |
Type: Number | |
Description: Default build disk size in GB | |
Default: '200' | |
ClientId: | |
Type: String | |
Description: Anonymous identifier | |
Default: '' | |
ContainerDisk: | |
Type: Number | |
Description: Default container disk size in GB | |
Default: '10' | |
Development: | |
Type: String | |
Description: Development mode | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
EncryptEbs: | |
Type: String | |
Description: Enable encryption at rest for EBS volumes | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
Encryption: | |
Type: String | |
Description: Encrypt secrets with KMS | |
Default: 'Yes' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
ExistingVpc: | |
Description: Existing VPC ID (if blank a VPC will be created) | |
Type: String | |
Default: '' | |
HttpProxy: | |
Description: Connect using an outbound HTTP proxy (for network-restricted Racks) | |
Type: String | |
Default: '' | |
Internal: | |
Type: String | |
Description: Support applications that are only accessible inside the VPC | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
InstanceBootCommand: | |
Type: String | |
Description: A single line of shell script to run as CloudInit command early during | |
instance boot. | |
Default: '' | |
InstanceRunCommand: | |
Type: String | |
Description: A single line of shell script to run as CloudInit command late during | |
instance boot. | |
Default: '' | |
InstanceCount: | |
Default: '3' | |
Description: The number of instances in the runtime cluster | |
MinValue: '3' | |
Type: Number | |
InstanceType: | |
Default: t2.small | |
Description: The type of the instances in the runtime cluster | |
Type: String | |
InstanceUpdateBatchSize: | |
Default: '1' | |
Description: The number of instances to update in a batch | |
MinValue: '1' | |
Type: Number | |
InstanceSecurityGroup: | |
Default: '' | |
Description: The security group to assign to the ECS instances. If blank, convox | |
will create a security group open to all IPs in your VPC | |
Type: String | |
InternetGateway: | |
Description: The InternetGatway to route to if an Existing VPC is specified | |
Type: String | |
Default: '' | |
Key: | |
Default: '' | |
Description: SSH key name for access to cluster instances | |
Type: String | |
LogBucket: | |
Default: '' | |
Description: Bucket to receive S3 logs | |
Type: String | |
MaxAvailabilityZones: | |
Type: Number | |
Default: '3' | |
AllowedValues: | |
- '2' | |
- '3' | |
OnDemandMinCount: | |
Default: '3' | |
Description: The minimum number of on-demand instances in the runtime cluster | |
Type: Number | |
Password: | |
Description: (REQUIRED) API HTTP password | |
Type: String | |
MinLength: '1' | |
MaxLength: '50' | |
NoEcho: true | |
Private: | |
Type: String | |
Description: Create non publicly routable resources | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
PrivateApi: | |
Type: String | |
Description: Put Rack API Load Balancer in private network | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
SpotInstanceBid: | |
Default: '' | |
Description: Bid price for spot instances | |
Type: String | |
Subnet0CIDR: | |
Default: 10.0.1.0/24 | |
Description: Public Subnet 0 CIDR Block | |
Type: String | |
Subnet1CIDR: | |
Default: 10.0.2.0/24 | |
Description: Public Subnet 1 CIDR Block | |
Type: String | |
Subnet2CIDR: | |
Default: 10.0.3.0/24 | |
Description: Public Subnet 2 CIDR Block | |
Type: String | |
SubnetPrivate0CIDR: | |
Default: 10.0.4.0/24 | |
Description: Private Subnet 0 CIDR Block | |
Type: String | |
SubnetPrivate1CIDR: | |
Default: 10.0.5.0/24 | |
Description: Private Subnet 1 CIDR Block | |
Type: String | |
SubnetPrivate2CIDR: | |
Default: 10.0.6.0/24 | |
Description: Private Subnet 2 CIDR Block | |
Type: String | |
SwapSize: | |
Type: Number | |
Description: Default swap volume size in GB | |
Default: '5' | |
RootSize: | |
Type: Number | |
Description: Default root disk size in GB | |
Default: '8' | |
Version: | |
Description: (REQUIRED) Convox release version | |
MinLength: '1' | |
Type: String | |
VolumeSize: | |
Type: Number | |
Description: Default disk size in GB | |
Default: '50' | |
VPCCIDR: | |
Default: 10.0.0.0/16 | |
Description: VPC CIDR Block | |
Type: String | |
Tenancy: | |
Type: String | |
Description: Dedicated Hardware | |
Default: default | |
AllowedValues: | |
- default | |
- dedicated | |
Resources: | |
AvailabilityZones: | |
Type: Custom::EC2AvailabilityZones | |
Properties: | |
ServiceToken: !GetAtt 'CustomTopic.Arn' | |
Vpc: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
EncryptionKey: | |
Type: Custom::KMSKey | |
Properties: | |
ServiceToken: !GetAtt 'CustomTopic.Arn' | |
Description: Convox Master Encryption | |
KeyUsage: ENCRYPT_DECRYPT | |
EncryptionKeyAlias: | |
Type: AWS::KMS::Alias | |
Properties: | |
AliasName: !Sub 'alias/convox-${AWS::StackName}' | |
TargetKeyId: !Ref 'EncryptionKey' | |
LogGroup: | |
Type: AWS::Logs::LogGroup | |
CustomTopicRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- lambda.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: Administrator | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: '*' | |
Resource: '*' | |
- Effect: Deny | |
Action: s3:DeleteObject | |
Resource: '*' | |
NotificationTopic: | |
Type: AWS::SNS::Topic | |
Properties: | |
TopicName: !Sub '${AWS::StackName}-notifications' | |
CustomTopic: | |
Type: AWS::Lambda::Function | |
Properties: | |
Code: | |
S3Bucket: !Sub 'convox-${AWS::Region}' | |
S3Key: !Sub 'release/${Version}/lambda/formation.zip' | |
Description: Convox handler for custom resources | |
Handler: index.external | |
MemorySize: '128' | |
Role: !GetAtt 'CustomTopicRole.Arn' | |
Runtime: nodejs4.3 | |
Timeout: '300' | |
Vpc: | |
Type: AWS::EC2::VPC | |
Condition: BlankExistingVpc | |
Properties: | |
CidrBlock: !Ref 'VPCCIDR' | |
EnableDnsSupport: 'true' | |
EnableDnsHostnames: 'true' | |
InstanceTenancy: !Ref 'Tenancy' | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
Gateway: | |
Type: AWS::EC2::InternetGateway | |
Condition: BlankExistingVpc | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
GatewayAttachment: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Condition: BlankExistingVpc | |
Properties: | |
InternetGatewayId: !Ref 'Gateway' | |
VpcId: !Ref 'Vpc' | |
ExistingGatewayAttachment: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Condition: ExistingVpcAndInternetGateway | |
DeletionPolicy: Retain | |
Properties: | |
InternetGatewayId: !Ref 'InternetGateway' | |
VpcId: !Ref 'ExistingVpc' | |
Nat0: | |
Condition: Private | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt 'NatAddress0.AllocationId' | |
SubnetId: !Ref 'Subnet0' | |
Nat1: | |
Condition: Private | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt 'NatAddress1.AllocationId' | |
SubnetId: !Ref 'Subnet1' | |
Nat2: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt 'NatAddress2.AllocationId' | |
SubnetId: !Ref 'Subnet2' | |
NatAddress0: | |
Condition: Private | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
NatAddress1: | |
Condition: Private | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
NatAddress2: | |
Condition: Private | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
SecureEnvironmentRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs-tasks.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: SecureEnvironmentPolicy | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
Effect: Allow | |
Action: | |
- kms:Decrypt | |
Resource: | |
- !Ref 'EncryptionKey' | |
Subnet0: | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName} public 0' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone0' | |
CidrBlock: !Ref 'Subnet0CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Subnet1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName} public 1' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone1' | |
CidrBlock: !Ref 'Subnet1CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Subnet2: | |
Condition: ThirdAvailabilityZone | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName} public 2' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone2' | |
CidrBlock: !Ref 'Subnet2CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
SubnetPrivate0: | |
Condition: Private | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName} private 0' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone0' | |
CidrBlock: !Ref 'SubnetPrivate0CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
SubnetPrivate1: | |
Condition: Private | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName} private 1' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone1' | |
CidrBlock: !Ref 'SubnetPrivate1CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
SubnetPrivate2: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName} private 2' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone2' | |
CidrBlock: !Ref 'SubnetPrivate2CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Routes: | |
Type: AWS::EC2::RouteTable | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Properties: | |
Tags: | |
- Key: GatewayAttachment | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'GatewayAttachment' | |
- existing | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteDefault: | |
Type: AWS::EC2::Route | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Properties: | |
DestinationCidrBlock: 0.0.0.0/0 | |
GatewayId: !If | |
- ExistingVpcAndInternetGateway | |
- !Ref 'InternetGateway' | |
- !Ref 'Gateway' | |
RouteTableId: !Ref 'Routes' | |
RouteTablePrivate0: | |
Condition: Private | |
DependsOn: | |
- Nat0 | |
Type: AWS::EC2::RouteTable | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteTablePrivate1: | |
Condition: Private | |
DependsOn: | |
- Nat1 | |
Type: AWS::EC2::RouteTable | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteTablePrivate2: | |
Condition: PrivateAndThirdAvailabilityZone | |
DependsOn: | |
- Nat2 | |
Type: AWS::EC2::RouteTable | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteDefaultPrivate0: | |
Condition: Private | |
Type: AWS::EC2::Route | |
Properties: | |
DestinationCidrBlock: 0.0.0.0/0 | |
NatGatewayId: !Ref 'Nat0' | |
RouteTableId: !Ref 'RouteTablePrivate0' | |
RouteDefaultPrivate1: | |
Condition: Private | |
Type: AWS::EC2::Route | |
Properties: | |
DestinationCidrBlock: 0.0.0.0/0 | |
NatGatewayId: !Ref 'Nat1' | |
RouteTableId: !Ref 'RouteTablePrivate1' | |
RouteDefaultPrivate2: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::Route | |
Properties: | |
DestinationCidrBlock: 0.0.0.0/0 | |
NatGatewayId: !Ref 'Nat2' | |
RouteTableId: !Ref 'RouteTablePrivate2' | |
Subnet0Routes: | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'Subnet0' | |
RouteTableId: !Ref 'Routes' | |
Subnet1Routes: | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'Subnet1' | |
RouteTableId: !Ref 'Routes' | |
Subnet2Routes: | |
Condition: ThirdAvailabilityZoneAndNotExistingVpcAndBlankInternetGateway | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'Subnet2' | |
RouteTableId: !Ref 'Routes' | |
SubnetPrivate0Routes: | |
Condition: Private | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'SubnetPrivate0' | |
RouteTableId: !Ref 'RouteTablePrivate0' | |
SubnetPrivate1Routes: | |
Condition: Private | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'SubnetPrivate1' | |
RouteTableId: !Ref 'RouteTablePrivate1' | |
SubnetPrivate2Routes: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'SubnetPrivate2' | |
RouteTableId: !Ref 'RouteTablePrivate2' | |
HostedZone: | |
Type: AWS::Route53::HostedZone | |
Properties: | |
Name: !Sub '${AWS::StackName}.convox' | |
VPCs: | |
- VPCId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
VPCRegion: !Ref 'AWS::Region' | |
RecordSetRack: | |
Type: AWS::Route53::RecordSet | |
Properties: | |
HostedZoneId: !Ref 'HostedZone' | |
Name: !Sub 'rack.${AWS::StackName}.convox.' | |
Type: CNAME | |
TTL: '3600' | |
ResourceRecords: | |
- !GetAtt 'Balancer.DNSName' | |
InstancesSecurity: | |
DependsOn: ApiRole | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} instances' | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: '0' | |
ToPort: '65535' | |
CidrIp: !Ref 'VPCCIDR' | |
- IpProtocol: udp | |
FromPort: '0' | |
ToPort: '65535' | |
CidrIp: !Ref 'VPCCIDR' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-instances' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
InstancesRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ec2.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Version: '2012-10-17' | |
Path: /convox/ | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role | |
- arn:aws:iam::aws:policy/AutoScalingFullAccess | |
InstancesProfile: | |
DependsOn: ApiRole | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Path: /convox/ | |
Roles: | |
- !Ref 'InstancesRole' | |
BuildCluster: | |
Condition: DedicatedBuilder | |
Type: AWS::ECS::Cluster | |
BuildLaunchConfiguration: | |
Condition: DedicatedBuilder | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
AssociatePublicIpAddress: !If | |
- Private | |
- false | |
- true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: !Ref 'RootSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdb | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'SwapSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdcz | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'BuildVolumeSize' | |
VolumeType: gp2 | |
IamInstanceProfile: !Ref 'InstancesProfile' | |
ImageId: !If | |
- BlankAmi | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Ami | |
- !Ref 'Ami' | |
InstanceMonitoring: true | |
InstanceType: !Ref 'BuildInstance' | |
KeyName: !If | |
- BlankKey | |
- !Ref 'AWS::NoValue' | |
- !Ref 'Key' | |
PlacementTenancy: !Ref 'Tenancy' | |
SecurityGroups: | |
- !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
UserData: !Base64 | |
Fn::Sub: | |
- | | |
#cloud-config | |
repo_upgrade_exclude: | |
- kernel* | |
packages: | |
- aws-cfn-bootstrap | |
mounts: | |
- ['/dev/xvdb', 'none', 'swap', 'sw', '0', '0'] | |
bootcmd: | |
- mkswap /dev/xvdb | |
- swapon /dev/xvdb | |
- [ cloud-init-per, instance, docker_storage_setup, /usr/bin/docker-storage-setup ] | |
- export http_proxy=${HttpProxy} | |
- echo http_proxy=${HttpProxy} >> /etc/environment | |
- export https_proxy=${HttpProxy} | |
- echo https_proxy=${HttpProxy} >> /etc/environment | |
- export HTTP_PROXY=${HttpProxy} | |
- echo HTTP_PROXY=${HttpProxy} >> /etc/environment | |
- export HTTPS_PROXY=${HttpProxy} | |
- echo HTTPS_PROXY=${HttpProxy} >> /etc/environment | |
- export NO_PROXY=169.254.169.254 | |
- echo NO_PROXY=169.254.169.254 >> /etc/environment | |
${Param1} - echo ECS_CLUSTER=${BuildCluster} >> /etc/ecs/ecs.config | |
- echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config | |
- echo 'ECS_INSTANCE_ATTRIBUTES={"asg":"build"}' >> /etc/ecs/ecs.config | |
- echo HTTP_PROXY=${HttpProxy} >> /etc/ecs/ecs.config | |
- echo NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock >> /etc/ecs/ecs.config | |
- head -n -1 /etc/sysconfig/docker >> /etc/sysconfig/docker-tmp | |
- mv /etc/sysconfig/docker-tmp /etc/sysconfig/docker | |
- echo 'OPTIONS="--default-ulimit nofile=1024000:1024000"' >> /etc/sysconfig/docker | |
${Param2}${Param3} - echo -e '/var/log/docker {\n rotate 7\n daily\n nocompress\n copytruncate\n}' >> /etc/logrotate.d/docker | |
${Param4}runcmd: | |
${Param5} - /opt/aws/bin/cfn-signal --http-proxy "${HttpProxy}" --stack ${AWS::StackName} --region ${AWS::Region} --resource BuildInstances | |
- Param1: !If | |
- HttpProxy | |
- !Sub |2 | |
- echo "proxy=${HttpProxy}/" >> /etc/yum.conf | |
- !Ref 'AWS::NoValue' | |
Param2: !Sub |2 | |
- echo 'OPTIONS="${!OPTIONS} --storage-opt dm.basesize=${ContainerDisk}G"' >> /etc/sysconfig/docker | |
- echo 'OPTIONS="${!OPTIONS} --log-opt max-file=2 --log-opt max-size=50m --host=unix:///var/run/docker.sock --host=0.0.0.0:2376"' >> /etc/sysconfig/docker | |
- echo 'ECS_ENGINE_AUTH_DATA={"index.docker.io":{"username":"","password":"","email":""}' >> /etc/ecs/ecs.config | |
Param3: !If | |
- HttpProxy | |
- !Sub |2 | |
- echo "export HTTP_PROXY=${HttpProxy}/" >> /etc/sysconfig/docker | |
- !Ref 'AWS::NoValue' | |
Param4: !If | |
- BlankInstanceBootCommand | |
- !Ref 'AWS::NoValue' | |
- !Sub |2 | |
- ${InstanceBootCommand} | |
Param5: !If | |
- BlankInstanceRunCommand | |
- !Ref 'AWS::NoValue' | |
- !Sub |2 | |
- ${InstanceRunCommand} | |
BuildInstances: | |
Condition: DedicatedBuilder | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
LaunchConfigurationName: !Ref 'BuildLaunchConfiguration' | |
VPCZoneIdentifier: !If | |
- Private | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Cooldown: 5 | |
DesiredCapacity: '1' | |
HealthCheckType: EC2 | |
HealthCheckGracePeriod: '120' | |
MinSize: '1' | |
MaxSize: '2' | |
MetricsCollection: | |
- Granularity: 1Minute | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
PropagateAtLaunch: false | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MaxBatchSize: !Ref 'InstanceUpdateBatchSize' | |
MinInstancesInService: '1' | |
PauseTime: PT15M | |
SuspendProcesses: | |
- ScheduledActions | |
WaitOnResourceSignals: 'true' | |
LaunchConfiguration: | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
AssociatePublicIpAddress: !If | |
- Private | |
- false | |
- true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: !Ref 'RootSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdb | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'SwapSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdcz | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'VolumeSize' | |
VolumeType: gp2 | |
IamInstanceProfile: !Ref 'InstancesProfile' | |
ImageId: !If | |
- BlankAmi | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Ami | |
- !Ref 'Ami' | |
InstanceMonitoring: true | |
InstanceType: !Ref 'InstanceType' | |
KeyName: !If | |
- BlankKey | |
- !Ref 'AWS::NoValue' | |
- !Ref 'Key' | |
PlacementTenancy: !Ref 'Tenancy' | |
SecurityGroups: | |
- !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
UserData: !Base64 | |
Fn::Sub: | |
- | | |
#cloud-config | |
repo_upgrade_exclude: | |
- kernel* | |
packages: | |
- aws-cfn-bootstrap | |
mounts: | |
- ['/dev/xvdb', 'none', 'swap', 'sw', '0', '0'] | |
bootcmd: | |
- mkswap /dev/xvdb | |
- swapon /dev/xvdb | |
- export http_proxy=${HttpProxy} | |
- echo http_proxy=${HttpProxy} >> /etc/environment | |
- export https_proxy=${HttpProxy} | |
- echo https_proxy=${HttpProxy} >> /etc/environment | |
- export HTTP_PROXY=${HttpProxy} | |
- echo HTTP_PROXY=${HttpProxy} >> /etc/environment | |
- export HTTPS_PROXY=${HttpProxy} | |
- echo HTTPS_PROXY=${HttpProxy} >> /etc/environment | |
- export NO_PROXY=169.254.169.254 | |
- echo NO_PROXY=169.254.169.254 >> /etc/environment | |
${Param1} - until yum install -y aws-cli nfs-utils; do echo "Waiting for network"; done; | |
- mkdir /volumes | |
${Param2} - [ cloud-init-per, instance, docker_storage_setup, /usr/bin/docker-storage-setup ] | |
- echo ECS_CLUSTER=${Cluster} >> /etc/ecs/ecs.config | |
- echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config | |
- echo 'ECS_INSTANCE_ATTRIBUTES={"asg":"primary"}' >> /etc/ecs/ecs.config | |
- echo HTTP_PROXY=${HttpProxy} >> /etc/ecs/ecs.config | |
- echo NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock >> /etc/ecs/ecs.config | |
- head -n -1 /etc/sysconfig/docker >> /etc/sysconfig/docker-tmp | |
- mv /etc/sysconfig/docker-tmp /etc/sysconfig/docker | |
- echo 'OPTIONS="--default-ulimit nofile=1024000:1024000"' >> /etc/sysconfig/docker | |
${Param3}${Param4} - echo -e '/var/log/docker {\n rotate 7\n daily\n nocompress\n copytruncate\n}' >> /etc/logrotate.d/docker | |
${Param5}runcmd: | |
${Param6} - export INSTANCE_ID=$(curl -s --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id) | |
- export ASG_NAME=$(env $(cat /etc/environment) /usr/bin/aws autoscaling describe-auto-scaling-instances --instance-ids=$INSTANCE_ID --region ${AWS::Region} --output text --query 'AutoScalingInstances[0].AutoScalingGroupName') | |
- export LIFECYCLE_HOOK=$(env $(cat /etc/environment) /usr/bin/aws autoscaling describe-lifecycle-hooks --auto-scaling-group-name $ASG_NAME --region ${AWS::Region} --output text --query "LifecycleHooks[?contains(LifecycleHookName, '${AWS::StackName}-InstancesLifecycleLaunching') == \`true\`].LifecycleHookName | [0]") | |
- env $(cat /etc/environment) /usr/bin/aws autoscaling complete-lifecycle-action --region ${AWS::Region} --instance-id $INSTANCE_ID --lifecycle-hook-name $LIFECYCLE_HOOK --auto-scaling-group-name $ASG_NAME --lifecycle-action-result CONTINUE | |
- env $(cat /etc/environment) /opt/aws/bin/cfn-signal --http-proxy "${HttpProxy}" --stack ${AWS::StackName} --region ${AWS::Region} --resource Instances | |
- Param1: !If | |
- HttpProxy | |
- !Sub |2 | |
- echo "proxy=${HttpProxy}/" >> /etc/yum.conf | |
- !Ref 'AWS::NoValue' | |
Param2: !If | |
- RegionHasEFS | |
- !Sub |2 | |
- while true; do mount -t nfs -o nfsvers=4.1 $(curl -s --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/placement/availability-zone).${VolumeFilesystem}.efs.${AWS::Region}.amazonaws.com:/ /volumes && break; sleep 5; done | |
- '' | |
Param3: !Sub |2 | |
- echo 'OPTIONS="${!OPTIONS} --storage-opt dm.basesize=${ContainerDisk}G"' >> /etc/sysconfig/docker | |
- echo 'OPTIONS="${!OPTIONS} --log-opt max-file=2 --log-opt max-size=50m --host=unix:///var/run/docker.sock --host=0.0.0.0:2376"' >> /etc/sysconfig/docker | |
- echo 'ECS_ENGINE_AUTH_DATA={"index.docker.io":{"username":"","password":"","email":""}' >> /etc/ecs/ecs.config | |
Param4: !If | |
- HttpProxy | |
- !Sub |2 | |
- echo "export HTTP_PROXY=${HttpProxy}/" >> /etc/sysconfig/docker | |
- !Ref 'AWS::NoValue' | |
Param5: !If | |
- BlankInstanceBootCommand | |
- !Ref 'AWS::NoValue' | |
- !Sub |2 | |
- ${InstanceBootCommand} | |
Param6: !If | |
- BlankInstanceRunCommand | |
- !Ref 'AWS::NoValue' | |
- !Sub |2 | |
- ${InstanceRunCommand} | |
Instances: | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
LaunchConfigurationName: !Ref 'LaunchConfiguration' | |
VPCZoneIdentifier: !If | |
- Private | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Cooldown: 5 | |
DesiredCapacity: !If | |
- SpotInstances | |
- !Ref 'AWS::NoValue' | |
- !Ref 'InstanceCount' | |
HealthCheckType: EC2 | |
HealthCheckGracePeriod: '120' | |
MinSize: !If | |
- SpotInstances | |
- !Ref 'OnDemandMinCount' | |
- !Ref 'InstanceCount' | |
MaxSize: '1000' | |
MetricsCollection: | |
- Granularity: 1Minute | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
PropagateAtLaunch: false | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MaxBatchSize: !Ref 'InstanceUpdateBatchSize' | |
MinInstancesInService: !If | |
- SpotInstances | |
- !Ref 'OnDemandMinCount' | |
- !Ref 'InstanceCount' | |
PauseTime: PT15M | |
SuspendProcesses: | |
- ScheduledActions | |
WaitOnResourceSignals: 'true' | |
InstancesLifecycleLaunching: | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'Instances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '600' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
InstancesLifecycleTerminating: | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'Instances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '300' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
InstancesLifecycleRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- autoscaling.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: InstancesLifecycleRole | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- sns:Publish | |
Resource: !Ref 'InstancesLifecycleTopic' | |
InstancesLifecycleTopic: | |
Type: AWS::SNS::Topic | |
Properties: | |
Subscription: | |
- Endpoint: !GetAtt 'InstancesLifecycleHandler.Arn' | |
Protocol: lambda | |
TopicName: !Sub '${AWS::StackName}-lifecycle' | |
InstancesLifecycleHandler: | |
Type: AWS::Lambda::Function | |
Properties: | |
Code: | |
S3Bucket: !Sub 'convox-${AWS::Region}' | |
S3Key: !Sub 'release/${Version}/lambda/lifecycle.zip' | |
Description: !Sub '{"Cluster": "${Cluster}", "Rack": "${AWS::StackName}"}' | |
Handler: index.external | |
MemorySize: '128' | |
Role: !GetAtt 'InstancesLifecycleHandlerRole.Arn' | |
Runtime: nodejs4.3 | |
Timeout: '300' | |
InstancesLifecycleHandlerPermission: | |
Type: AWS::Lambda::Permission | |
Properties: | |
FunctionName: !GetAtt 'InstancesLifecycleHandler.Arn' | |
Action: lambda:InvokeFunction | |
Principal: sns.amazonaws.com | |
SourceArn: !Ref 'InstancesLifecycleTopic' | |
InstancesLifecycleHandlerRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- lambda.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: InstancesLifecycleHandlerRole | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- autoscaling:CompleteLifecycleAction | |
- ecs:DeregisterContainerInstance | |
- ecs:DescribeContainerInstances | |
- ecs:DescribeServices | |
- ecs:DescribeTasks | |
- ecs:ListContainerInstances | |
- ecs:ListServices | |
- ecs:ListTasks | |
- ecs:StopTask | |
- ecs:UpdateContainerInstancesState | |
- lambda:GetFunction | |
- logs:CreateLogGroup | |
- logs:CreateLogStream | |
- logs:PutLogEvents | |
Resource: '*' | |
SpotLaunchConfiguration: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
AssociatePublicIpAddress: !If | |
- Private | |
- false | |
- true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: !Ref 'RootSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdb | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'SwapSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdcz | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'VolumeSize' | |
VolumeType: gp2 | |
IamInstanceProfile: !Ref 'InstancesProfile' | |
ImageId: !If | |
- BlankAmi | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Ami | |
- !Ref 'Ami' | |
InstanceMonitoring: true | |
InstanceType: !Ref 'InstanceType' | |
KeyName: !If | |
- BlankKey | |
- !Ref 'AWS::NoValue' | |
- !Ref 'Key' | |
SecurityGroups: | |
- !Ref 'InstancesSecurity' | |
SpotPrice: !Ref 'SpotInstanceBid' | |
UserData: !Base64 | |
Fn::Sub: | |
- | | |
#cloud-config | |
repo_upgrade_exclude: | |
- kernel* | |
packages: | |
- aws-cfn-bootstrap | |
mounts: | |
- ['/dev/xvdb', 'none', 'swap', 'sw', '0', '0'] | |
bootcmd: | |
- mkswap /dev/xvdb | |
- swapon /dev/xvdb | |
- export http_proxy=${HttpProxy} | |
- echo http_proxy=${HttpProxy} >> /etc/environment | |
- export https_proxy=${HttpProxy} | |
- echo https_proxy=${HttpProxy} >> /etc/environment | |
- export HTTP_PROXY=${HttpProxy} | |
- echo HTTP_PROXY=${HttpProxy} >> /etc/environment | |
- export HTTPS_PROXY=${HttpProxy} | |
- echo HTTPS_PROXY=${HttpProxy} >> /etc/environment | |
- export NO_PROXY=169.254.169.254 | |
- echo NO_PROXY=169.254.169.254 >> /etc/environment | |
${Param1} - until yum install -y aws-cli nfs-utils; do echo "Waiting for network"; done; | |
- mkdir /volumes | |
${Param2} - [ cloud-init-per, instance, docker_storage_setup, /usr/bin/docker-storage-setup ] | |
- echo ECS_CLUSTER=${Cluster} >> /etc/ecs/ecs.config | |
- echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config | |
- echo 'ECS_INSTANCE_ATTRIBUTES={"asg":"spot"}' >> /etc/ecs/ecs.config | |
- echo HTTP_PROXY=${HttpProxy} >> /etc/ecs/ecs.config | |
- echo NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock >> /etc/ecs/ecs.config | |
- head -n -1 /etc/sysconfig/docker >> /etc/sysconfig/docker-tmp | |
- mv /etc/sysconfig/docker-tmp /etc/sysconfig/docker | |
- echo 'OPTIONS="--default-ulimit nofile=1024000:1024000"' >> /etc/sysconfig/docker | |
${Param3}${Param4} - echo -e '/var/log/docker {\n rotate 7\n daily\n nocompress\n copytruncate\n}' >> /etc/logrotate.d/docker | |
${Param5}runcmd: | |
${Param6} - export INSTANCE_ID=$(curl -s --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id) | |
- export ASG_NAME=$(env $(cat /etc/environment) /usr/bin/aws autoscaling describe-auto-scaling-instances --instance-ids=$INSTANCE_ID --region ${AWS::Region} --output text --query 'AutoScalingInstances[0].AutoScalingGroupName') | |
- export LIFECYCLE_HOOK=$(env $(cat /etc/environment) /usr/bin/aws autoscaling describe-lifecycle-hooks --auto-scaling-group-name $ASG_NAME --region ${AWS::Region} --output text --query "LifecycleHooks[?contains(LifecycleHookName, '${AWS::StackName}-SpotInstancesLifecycleLaunching') == \`true\`].LifecycleHookName | [0]") | |
- env $(cat /etc/environment) /usr/bin/aws autoscaling complete-lifecycle-action --region ${AWS::Region} --instance-id $INSTANCE_ID --lifecycle-hook-name $LIFECYCLE_HOOK --auto-scaling-group-name $ASG_NAME --lifecycle-action-result CONTINUE | |
- env $(cat /etc/environment) /opt/aws/bin/cfn-signal --http-proxy "${HttpProxy}" --stack ${AWS::StackName} --region ${AWS::Region} --resource SpotInstances | |
- Param1: !If | |
- HttpProxy | |
- !Sub |2 | |
- echo "proxy=${HttpProxy}/" >> /etc/yum.conf | |
- !Ref 'AWS::NoValue' | |
Param2: !If | |
- RegionHasEFS | |
- !Sub |2 | |
- while true; do mount -t nfs -o nfsvers=4.1 $(curl -s --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/placement/availability-zone).${VolumeFilesystem}.efs.${AWS::Region}.amazonaws.com:/ /volumes && break; sleep 5; done | |
- '' | |
Param3: !Sub |2 | |
- echo 'OPTIONS="${!OPTIONS} --storage-opt dm.basesize=${ContainerDisk}G"' >> /etc/sysconfig/docker | |
- echo 'OPTIONS="${!OPTIONS} --log-opt max-file=2 --log-opt max-size=50m --host=unix:///var/run/docker.sock --host=0.0.0.0:2376"' >> /etc/sysconfig/docker | |
- echo 'ECS_ENGINE_AUTH_DATA={"index.docker.io":{"username":"","password":"","email":""}' >> /etc/ecs/ecs.config | |
Param4: !If | |
- HttpProxy | |
- !Sub |2 | |
- echo "export HTTP_PROXY=${HttpProxy}/" >> /etc/sysconfig/docker | |
- !Ref 'AWS::NoValue' | |
Param5: !If | |
- BlankInstanceBootCommand | |
- !Ref 'AWS::NoValue' | |
- !Sub |2 | |
- ${InstanceBootCommand} | |
Param6: !If | |
- BlankInstanceRunCommand | |
- !Ref 'AWS::NoValue' | |
- !Sub |2 | |
- ${InstanceRunCommand} | |
SpotInstances: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
LaunchConfigurationName: !Ref 'SpotLaunchConfiguration' | |
VPCZoneIdentifier: !If | |
- Private | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Cooldown: 5 | |
HealthCheckType: EC2 | |
HealthCheckGracePeriod: '120' | |
MinSize: '0' | |
MaxSize: '1000' | |
MetricsCollection: | |
- Granularity: 1Minute | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
PropagateAtLaunch: false | |
- Key: InstanceCount | |
Value: !Ref 'InstanceCount' | |
PropagateAtLaunch: false | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MaxBatchSize: !Ref 'InstanceUpdateBatchSize' | |
MinInstancesInService: '0' | |
PauseTime: PT15M | |
SuspendProcesses: | |
- ScheduledActions | |
WaitOnResourceSignals: 'true' | |
SpotInstancesLifecycleLaunching: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'SpotInstances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '600' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
SpotInstancesLifecycleTerminating: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'SpotInstances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '300' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
VolumeFilesystem: | |
Type: AWS::EFS::FileSystem | |
Condition: RegionHasEFS | |
Properties: | |
FileSystemTags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-shared-volumes' | |
VolumeSecurity: | |
DependsOn: ApiRole | |
Type: AWS::EC2::SecurityGroup | |
Condition: RegionHasEFS | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} volumes' | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: '2049' | |
ToPort: '2049' | |
CidrIp: !Ref 'VPCCIDR' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-volumes' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
VolumeTarget0: | |
Type: AWS::EFS::MountTarget | |
Condition: RegionHasEFS | |
Properties: | |
FileSystemId: !Ref 'VolumeFilesystem' | |
SubnetId: !If | |
- Private | |
- !Ref 'SubnetPrivate0' | |
- !Ref 'Subnet0' | |
SecurityGroups: | |
- !Ref 'VolumeSecurity' | |
VolumeTarget1: | |
Type: AWS::EFS::MountTarget | |
Condition: RegionHasEFS | |
Properties: | |
FileSystemId: !Ref 'VolumeFilesystem' | |
SubnetId: !If | |
- Private | |
- !Ref 'SubnetPrivate1' | |
- !Ref 'Subnet1' | |
SecurityGroups: | |
- !Ref 'VolumeSecurity' | |
VolumeTarget2: | |
Type: AWS::EFS::MountTarget | |
Condition: RegionHasEFSAndThirdAvailabilityZone | |
Properties: | |
FileSystemId: !Ref 'VolumeFilesystem' | |
SubnetId: !If | |
- Private | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'Subnet2' | |
SecurityGroups: | |
- !Ref 'VolumeSecurity' | |
AccountEvents: | |
Type: AWS::SQS::Queue | |
AccountEventsPolicy: | |
Type: AWS::SQS::QueuePolicy | |
Properties: | |
Queues: | |
- !Ref 'AccountEvents' | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
AWS: '*' | |
Action: sqs:SendMessage | |
Resource: !GetAtt 'AccountEvents.Arn' | |
Condition: | |
ArnEquals: | |
aws:SourceArn: !GetAtt 'AccountEventsRule.Arn' | |
AccountEventsRule: | |
Type: AWS::Events::Rule | |
Properties: | |
Description: Specified event changes | |
EventPattern: | |
account: | |
- !Ref 'AWS::AccountId' | |
source: | |
- aws.ecs | |
detail-type: | |
- ECS Task State Change | |
detail: | |
clusterArn: | |
- !Sub 'arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${Cluster}' | |
State: ENABLED | |
Targets: | |
- Arn: !GetAtt 'AccountEvents.Arn' | |
Id: Events | |
CloudformationEvents: | |
Type: AWS::SQS::Queue | |
CloudformationEventsPolicy: | |
Type: AWS::SQS::QueuePolicy | |
Properties: | |
Queues: | |
- !Ref 'CloudformationEvents' | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
AWS: '*' | |
Action: sqs:SendMessage | |
Resource: !GetAtt 'CloudformationEvents.Arn' | |
Condition: | |
ArnEquals: | |
aws:SourceArn: !Ref 'CloudformationTopic' | |
CloudformationTopic: | |
Type: AWS::SNS::Topic | |
Properties: | |
DisplayName: !Sub '${AWS::StackName}-events' | |
Subscription: | |
- Protocol: sqs | |
Endpoint: !GetAtt 'CloudformationEvents.Arn' | |
Router: | |
DependsOn: | |
- ApiRole | |
- LogsPolicy | |
Type: AWS::ElasticLoadBalancingV2::LoadBalancer | |
Properties: | |
LoadBalancerAttributes: | |
- Key: access_logs.s3.enabled | |
Value: 'true' | |
- Key: access_logs.s3.bucket | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
- Key: access_logs.s3.prefix | |
Value: !Sub 'convox/logs/${AWS::StackName}/alb' | |
- Key: idle_timeout.timeout_seconds | |
Value: '3600' | |
Subnets: | |
- !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
SecurityGroups: | |
- !Ref 'RouterSecurity' | |
RouterSecurity: | |
Type: AWS::EC2::SecurityGroup | |
DependsOn: ApiRole | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} router' | |
SecurityGroupIngress: | |
- CidrIp: 0.0.0.0/0 | |
IpProtocol: tcp | |
FromPort: '0' | |
ToPort: '65535' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-router' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouterListener80: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Properties: | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterApiTargetGroup' | |
LoadBalancerArn: !Ref 'Router' | |
Port: '80' | |
Protocol: HTTP | |
RouterListener443: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Properties: | |
Certificates: | |
- CertificateArn: !Ref 'RouterApiCertificate' | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterApiTargetGroup' | |
LoadBalancerArn: !Ref 'Router' | |
Port: '443' | |
Protocol: HTTPS | |
RouterApiCertificate: | |
Type: AWS::CertificateManager::Certificate | |
DependsOn: RouterApiTargetGroup | |
Properties: | |
DomainName: !Sub | |
- '*.${Param1}.${Param2}.convox.site' | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
DomainValidationOptions: | |
- DomainName: !Sub | |
- '*.${Param1}.${Param2}.convox.site' | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
ValidationDomain: convox.site | |
RouterApiTargetGroup: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
DependsOn: Router | |
Properties: | |
HealthCheckIntervalSeconds: '5' | |
HealthCheckTimeoutSeconds: '3' | |
UnhealthyThresholdCount: '2' | |
HealthCheckPath: /check | |
Port: '5443' | |
Protocol: HTTPS | |
TargetGroupAttributes: | |
- Key: deregistration_delay.timeout_seconds | |
Value: '30' | |
- Key: stickiness.enabled | |
Value: 'true' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouterInternal: | |
Type: AWS::ElasticLoadBalancingV2::LoadBalancer | |
Condition: Internal | |
DependsOn: | |
- ApiRole | |
- LogsPolicy | |
Properties: | |
LoadBalancerAttributes: | |
- Key: access_logs.s3.enabled | |
Value: 'true' | |
- Key: access_logs.s3.bucket | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
- Key: access_logs.s3.prefix | |
Value: !Sub 'convox/logs/${AWS::StackName}/alb' | |
- Key: idle_timeout.timeout_seconds | |
Value: '3600' | |
Name: !Sub '${AWS::StackName}-rti' | |
Scheme: internal | |
Subnets: | |
- !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
SecurityGroups: | |
- !Ref 'RouterSecurity' | |
RouterInternalSecurity: | |
Type: AWS::EC2::SecurityGroup | |
Condition: Internal | |
DependsOn: ApiRole | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} internal router' | |
SecurityGroupIngress: | |
- CidrIp: !Ref 'VPCCIDR' | |
IpProtocol: tcp | |
FromPort: '0' | |
ToPort: '65535' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-router-internal' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouterInternalListener80: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Condition: Internal | |
Properties: | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterInternalApiTargetGroup' | |
LoadBalancerArn: !Ref 'RouterInternal' | |
Port: '80' | |
Protocol: HTTP | |
RouterInternalListener443: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Condition: Internal | |
Properties: | |
Certificates: | |
- CertificateArn: !Ref 'RouterInternalCertificate' | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterInternalApiTargetGroup' | |
LoadBalancerArn: !Ref 'RouterInternal' | |
Port: '443' | |
Protocol: HTTPS | |
RouterInternalCertificate: | |
Type: AWS::CertificateManager::Certificate | |
Condition: Internal | |
DependsOn: RouterInternalApiTargetGroup | |
Properties: | |
DomainName: !Sub | |
- '*.${Param1}.${Param2}.convox.site' | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
DomainValidationOptions: | |
- DomainName: !Sub | |
- '*.${Param1}.${Param2}.convox.site' | |
- Param1: !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
Param2: !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
ValidationDomain: convox.site | |
RouterInternalApiTargetGroup: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
Condition: Internal | |
DependsOn: RouterInternal | |
Properties: | |
HealthCheckIntervalSeconds: '5' | |
HealthCheckTimeoutSeconds: '3' | |
UnhealthyThresholdCount: '2' | |
HealthCheckPath: /check | |
Port: '5443' | |
Protocol: HTTPS | |
TargetGroupAttributes: | |
- Key: deregistration_delay.timeout_seconds | |
Value: '30' | |
- Key: stickiness.enabled | |
Value: 'true' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Balancer: | |
Type: AWS::ElasticLoadBalancing::LoadBalancer | |
Properties: | |
ConnectionDrainingPolicy: | |
Enabled: true | |
Timeout: 60 | |
ConnectionSettings: | |
IdleTimeout: 3600 | |
CrossZone: true | |
HealthCheck: | |
HealthyThreshold: '2' | |
Interval: 5 | |
Target: !If | |
- PrivateApi | |
- HTTPS:3101/check | |
- HTTPS:3001/check | |
Timeout: 3 | |
UnhealthyThreshold: '2' | |
LBCookieStickinessPolicy: | |
- PolicyName: affinity | |
Listeners: !If | |
- PrivateApi | |
- - Protocol: TCP | |
LoadBalancerPort: '80' | |
InstanceProtocol: TCP | |
InstancePort: '3100' | |
- Protocol: TCP | |
LoadBalancerPort: '443' | |
InstanceProtocol: TCP | |
InstancePort: '3101' | |
- - Protocol: TCP | |
LoadBalancerPort: '80' | |
InstanceProtocol: TCP | |
InstancePort: '3000' | |
- Protocol: TCP | |
LoadBalancerPort: '443' | |
InstanceProtocol: TCP | |
InstancePort: '3001' | |
LoadBalancerName: !If | |
- PrivateApi | |
- !Sub '${AWS::StackName}-i' | |
- !Ref 'AWS::StackName' | |
Scheme: !If | |
- PrivateApi | |
- internal | |
- !Ref 'AWS::NoValue' | |
SecurityGroups: | |
- !Ref 'BalancerSecurity' | |
Subnets: !If | |
- PrivateApi | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Tags: | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
BalancerSecurity: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} balancer' | |
SecurityGroupIngress: | |
- CidrIp: !If | |
- PrivateApi | |
- !Ref 'VPCCIDR' | |
- 0.0.0.0/0 | |
IpProtocol: tcp | |
FromPort: '80' | |
ToPort: '80' | |
- CidrIp: !If | |
- PrivateApi | |
- !Ref 'VPCCIDR' | |
- 0.0.0.0/0 | |
IpProtocol: tcp | |
FromPort: '443' | |
ToPort: '443' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-balancer' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Cluster: | |
Type: AWS::ECS::Cluster | |
ServiceRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Version: '2012-10-17' | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole | |
Path: /convox/ | |
ApiRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs-tasks.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Version: '2012-10-17' | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/PowerUserAccess | |
Path: /convox/ | |
Policies: | |
- PolicyName: iam-convox | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- iam:* | |
Resource: | |
- arn:aws:iam::*:instance-profile/convox/* | |
- arn:aws:iam::*:policy/convox/* | |
- arn:aws:iam::*:role/convox/* | |
- arn:aws:iam::*:user/convox/* | |
- Effect: Allow | |
Action: | |
- iam:DeleteServerCertificate | |
- iam:GetServerCertificate | |
- iam:ListServerCertificates | |
- iam:PassRole | |
- iam:UploadServerCertificate | |
Resource: | |
- '*' | |
ApiMonitorService: | |
Type: AWS::ECS::Service | |
DependsOn: | |
- Instances | |
Properties: | |
Cluster: !Ref 'Cluster' | |
DeploymentConfiguration: | |
MinimumHealthyPercent: '100' | |
MaximumPercent: '200' | |
DesiredCount: '1' | |
PlacementConstraints: | |
- Type: memberOf | |
Expression: attribute:asg == primary | |
TaskDefinition: !Ref 'ApiMonitorTasks' | |
ApiWebService: | |
Type: AWS::ECS::Service | |
DependsOn: | |
- Instances | |
Properties: | |
Cluster: !Ref 'Cluster' | |
DeploymentConfiguration: | |
MinimumHealthyPercent: '50' | |
MaximumPercent: '200' | |
DesiredCount: !Ref 'ApiCount' | |
LoadBalancers: | |
- ContainerName: web | |
ContainerPort: '5443' | |
LoadBalancerName: !Ref 'Balancer' | |
Role: !GetAtt 'ServiceRole.Arn' | |
TaskDefinition: !Ref 'ApiWebTasks' | |
ApiBuildTasks: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
ContainerDefinitions: | |
- Cpu: !Ref 'BuildCpu' | |
DockerLabels: | |
convox.release: !Ref 'Version' | |
Environment: | |
- Name: AUTOSCALE | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
- Name: AWS_REGION | |
Value: !Ref 'AWS::Region' | |
- Name: BUILD_CLUSTER | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
- Name: CLIENT_ID | |
Value: !Ref 'ClientId' | |
- Name: CLOUDFORMATION_TOPIC | |
Value: !Ref 'CloudformationTopic' | |
- Name: CLUSTER | |
Value: !Ref 'Cluster' | |
- Name: CUSTOM_TOPIC | |
Value: !GetAtt 'CustomTopic.Arn' | |
- Name: DYNAMO_BUILDS | |
Value: !Ref 'DynamoBuilds' | |
- Name: DYNAMO_RELEASES | |
Value: !Ref 'DynamoReleases' | |
- Name: ENCRYPTION_KEY | |
Value: !Ref 'EncryptionKey' | |
- Name: HTTP_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: HTTPS_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: INTERNAL | |
Value: !Ref 'Internal' | |
- Name: LOG_BUCKET | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
- Name: LOG_GROUP | |
Value: !Ref 'LogGroup' | |
- Name: NOTIFICATION_HOST | |
Value: !GetAtt 'Balancer.DNSName' | |
- Name: NOTIFICATION_TOPIC | |
Value: !Ref 'NotificationTopic' | |
- Name: ON_DEMAND_MIN_COUNT | |
Value: !Ref 'OnDemandMinCount' | |
- Name: PASSWORD | |
Value: !Ref 'Password' | |
- Name: PRIVATE | |
Value: !Ref 'Private' | |
- Name: PROVIDER | |
Value: aws | |
- Name: RACK | |
Value: !Ref 'AWS::StackName' | |
- Name: RELEASE | |
Value: !Ref 'Version' | |
- Name: ROLLBAR_TOKEN | |
Value: f67f25b8a9024d5690f997bd86bf14b0 | |
- Name: SECURITY_GROUP | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
- Name: SEGMENT_WRITE_KEY | |
Value: KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i | |
- Name: SETTINGS_BUCKET | |
Value: !Ref 'Settings' | |
- Name: SPOT_INSTANCES | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
- Name: STACK_ID | |
Value: !Ref 'AWS::StackId' | |
- Name: SUBNETS | |
Value: !Sub | |
- ${Subnet0},${Subnet1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
- Name: VPC | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
- Name: VPCCIDR | |
Value: !Ref 'VPCCIDR' | |
Image: !If | |
- BlankBuildImage | |
- !Sub 'convox/rack:${Version}' | |
- !Ref 'BuildImage' | |
Memory: !Ref 'BuildMemory' | |
MountPoints: | |
- SourceVolume: config | |
ContainerPath: /etc/sysconfig/docker | |
- SourceVolume: docker | |
ContainerPath: /var/run/docker.sock | |
Name: build | |
Family: !Sub '${AWS::StackName}-build' | |
TaskRoleArn: !GetAtt 'ApiRole.Arn' | |
Volumes: | |
- Name: config | |
Host: | |
SourcePath: /etc/sysconfig/docker | |
- Name: docker | |
Host: | |
SourcePath: /var/run/docker.sock | |
ApiMonitorTasks: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
ContainerDefinitions: | |
- Command: | |
- bin/monitor | |
Cpu: '64' | |
DockerLabels: | |
convox.release: !Ref 'Version' | |
Environment: | |
- Name: AUTOSCALE | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
- Name: AUTOSCALE_EXTRA | |
Value: !Ref 'AutoscaleExtra' | |
- Name: AWS_REGION | |
Value: !Ref 'AWS::Region' | |
- Name: BUILD_CLUSTER | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
- Name: CLIENT_ID | |
Value: !Ref 'ClientId' | |
- Name: CLOUDFORMATION_TOPIC | |
Value: !Ref 'CloudformationTopic' | |
- Name: CLUSTER | |
Value: !Ref 'Cluster' | |
- Name: CUSTOM_TOPIC | |
Value: !GetAtt 'CustomTopic.Arn' | |
- Name: DYNAMO_BUILDS | |
Value: !Ref 'DynamoBuilds' | |
- Name: DYNAMO_RELEASES | |
Value: !Ref 'DynamoReleases' | |
- Name: ENCRYPTION_KEY | |
Value: !Ref 'EncryptionKey' | |
- Name: HTTP_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: HTTPS_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: INTERNAL | |
Value: !Ref 'Internal' | |
- Name: LOG_GROUP | |
Value: !Ref 'LogGroup' | |
- Name: NOTIFICATION_HOST | |
Value: !GetAtt 'Balancer.DNSName' | |
- Name: NOTIFICATION_TOPIC | |
Value: !Ref 'NotificationTopic' | |
- Name: ON_DEMAND_MIN_COUNT | |
Value: !Ref 'OnDemandMinCount' | |
- Name: PASSWORD | |
Value: !Ref 'Password' | |
- Name: PRIVATE | |
Value: !Ref 'Private' | |
- Name: PROVIDER | |
Value: aws | |
- Name: RACK | |
Value: !Ref 'AWS::StackName' | |
- Name: RELEASE | |
Value: !Ref 'Version' | |
- Name: ROLLBAR_TOKEN | |
Value: f67f25b8a9024d5690f997bd86bf14b0 | |
- Name: SECURITY_GROUP | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
- Name: SEGMENT_WRITE_KEY | |
Value: KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i | |
- Name: SPOT_INSTANCES | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
- Name: SETTINGS_BUCKET | |
Value: !Ref 'Settings' | |
- Name: STACK_ID | |
Value: !Ref 'AWS::StackId' | |
- Name: SUBNETS | |
Value: !Sub | |
- ${Subnet0},${Subnet1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
- Name: VPC | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
- Name: VPCCIDR | |
Value: !Ref 'VPCCIDR' | |
Image: !Sub 'convox/rack:${Version}' | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-group: !Ref 'LogGroup' | |
awslogs-stream-prefix: service | |
Memory: '64' | |
MountPoints: | |
- SourceVolume: docker | |
ContainerPath: /var/run/docker.sock | |
Name: monitor | |
Family: !Sub '${AWS::StackName}-monitor' | |
TaskRoleArn: !GetAtt 'ApiRole.Arn' | |
Volumes: | |
- Name: docker | |
Host: | |
SourcePath: /var/run/docker.sock | |
ApiWebTasks: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
ContainerDefinitions: | |
- Command: | |
- bin/web | |
Cpu: '128' | |
DockerLabels: | |
convox.release: !Ref 'Version' | |
Environment: | |
- Name: AUTOSCALE | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
- Name: AWS_REGION | |
Value: !Ref 'AWS::Region' | |
- Name: BUILD_CLUSTER | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
- Name: CLIENT_ID | |
Value: !Ref 'ClientId' | |
- Name: CLOUDFORMATION_TOPIC | |
Value: !Ref 'CloudformationTopic' | |
- Name: CLUSTER | |
Value: !Ref 'Cluster' | |
- Name: CUSTOM_TOPIC | |
Value: !GetAtt 'CustomTopic.Arn' | |
- Name: DYNAMO_BUILDS | |
Value: !Ref 'DynamoBuilds' | |
- Name: DYNAMO_RELEASES | |
Value: !Ref 'DynamoReleases' | |
- Name: ENCRYPTION_KEY | |
Value: !Ref 'EncryptionKey' | |
- Name: FARGATE | |
Value: !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Fargate | |
- Name: HTTP_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: HTTPS_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: INTERNAL | |
Value: !Ref 'Internal' | |
- Name: LOG_GROUP | |
Value: !Ref 'LogGroup' | |
- Name: NOTIFICATION_HOST | |
Value: !GetAtt 'Balancer.DNSName' | |
- Name: NOTIFICATION_TOPIC | |
Value: !Ref 'NotificationTopic' | |
- Name: ON_DEMAND_MIN_COUNT | |
Value: !Ref 'OnDemandMinCount' | |
- Name: PASSWORD | |
Value: !Ref 'Password' | |
- Name: PRIVATE | |
Value: !Ref 'Private' | |
- Name: PROVIDER | |
Value: aws | |
- Name: RACK | |
Value: !Ref 'AWS::StackName' | |
- Name: RELEASE | |
Value: !Ref 'Version' | |
- Name: ROLLBAR_TOKEN | |
Value: f67f25b8a9024d5690f997bd86bf14b0 | |
- Name: SECURITY_GROUP | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
- Name: SEGMENT_WRITE_KEY | |
Value: KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i | |
- Name: SPOT_INSTANCES | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
- Name: SETTINGS_BUCKET | |
Value: !Ref 'Settings' | |
- Name: STACK_ID | |
Value: !Ref 'AWS::StackId' | |
- Name: SUBNETS | |
Value: !Sub | |
- ${Subnet0},${Subnet1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
- Name: SUBNETS_PRIVATE | |
Value: !If | |
- Private | |
- !Sub | |
- ${SubnetPrivate0},${SubnetPrivate1},${Param1} | |
- Param1: !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
- Name: VPC | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
- Name: VPCCIDR | |
Value: !Ref 'VPCCIDR' | |
Image: !Sub 'convox/rack:${Version}' | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-group: !Ref 'LogGroup' | |
awslogs-stream-prefix: service | |
MemoryReservation: !Ref 'ApiMemory' | |
MountPoints: | |
- SourceVolume: docker | |
ContainerPath: /var/run/docker.sock | |
Name: web | |
PortMappings: !If | |
- PrivateApi | |
- - HostPort: '3100' | |
ContainerPort: '5442' | |
Protocol: tcp | |
- HostPort: '3101' | |
ContainerPort: '5443' | |
Protocol: tcp | |
- - HostPort: '3000' | |
ContainerPort: '5442' | |
Protocol: tcp | |
- HostPort: '3001' | |
ContainerPort: '5443' | |
Protocol: tcp | |
Family: !Sub '${AWS::StackName}-web' | |
TaskRoleArn: !GetAtt 'ApiRole.Arn' | |
Volumes: | |
- Name: docker | |
Host: | |
SourcePath: /var/run/docker.sock | |
DynamoBuilds: | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: !Sub '${AWS::StackName}-builds' | |
AttributeDefinitions: | |
- AttributeName: id | |
AttributeType: S | |
- AttributeName: app | |
AttributeType: S | |
- AttributeName: created | |
AttributeType: S | |
KeySchema: | |
- AttributeName: id | |
KeyType: HASH | |
GlobalSecondaryIndexes: | |
- IndexName: app.created | |
KeySchema: | |
- AttributeName: app | |
KeyType: HASH | |
- AttributeName: created | |
KeyType: RANGE | |
Projection: | |
ProjectionType: ALL | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
DynamoReleases: | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: !Sub '${AWS::StackName}-releases' | |
AttributeDefinitions: | |
- AttributeName: id | |
AttributeType: S | |
- AttributeName: app | |
AttributeType: S | |
- AttributeName: created | |
AttributeType: S | |
KeySchema: | |
- AttributeName: id | |
KeyType: HASH | |
GlobalSecondaryIndexes: | |
- IndexName: app.created | |
KeySchema: | |
- AttributeName: app | |
KeyType: HASH | |
- AttributeName: created | |
KeyType: RANGE | |
Projection: | |
ProjectionType: ALL | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
Logs: | |
Type: AWS::S3::Bucket | |
DeletionPolicy: Retain | |
Properties: | |
AccessControl: LogDeliveryWrite | |
Tags: | |
- Key: System | |
Value: convox | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
LogsPolicy: | |
Type: AWS::S3::BucketPolicy | |
Properties: | |
Bucket: !Ref 'Logs' | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Sid: ELB log delivery service | |
Effect: Allow | |
Principal: | |
AWS: !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- ELBAccountId | |
Action: s3:PutObject | |
Resource: !Sub 'arn:aws:s3:::${Logs}/*' | |
Settings: | |
Type: AWS::S3::Bucket | |
DependsOn: LogsPolicy | |
DeletionPolicy: Retain | |
Properties: | |
AccessControl: Private | |
LoggingConfiguration: | |
DestinationBucketName: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
LogFilePrefix: !Sub 'convox/logs/${AWS::StackName}/s3' | |
Tags: | |
- Key: System | |
Value: convox | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: '2010-09-09' | |
Conditions: | |
Autoscale: !Equals | |
- !Ref 'Autoscale' | |
- 'Yes' | |
BlankAmi: !Equals | |
- !Ref 'Ami' | |
- '' | |
BlankBuildImage: !Equals | |
- !Ref 'BuildImage' | |
- '' | |
BlankExistingVpc: !Equals | |
- !Ref 'ExistingVpc' | |
- '' | |
BlankExistingVpcAndThirdAvailabilityZone: !And | |
- !Condition 'BlankExistingVpc' | |
- !Condition 'ThirdAvailabilityZone' | |
BlankInstanceBootCommand: !Equals | |
- !Ref 'InstanceBootCommand' | |
- '' | |
BlankInstanceRunCommand: !Equals | |
- !Ref 'InstanceRunCommand' | |
- '' | |
BlankInstanceSecurityGroup: !Equals | |
- !Ref 'InstanceSecurityGroup' | |
- '' | |
BlankInternetGateway: !Equals | |
- !Ref 'InternetGateway' | |
- '' | |
BlankKey: !Equals | |
- !Ref 'Key' | |
- '' | |
BlankLogBucket: !Equals | |
- !Ref 'LogBucket' | |
- '' | |
DedicatedBuilder: !Not | |
- !Equals | |
- !Ref 'BuildInstance' | |
- '' | |
Development: !Equals | |
- !Ref 'Development' | |
- 'Yes' | |
EncryptEbs: !Equals | |
- !Ref 'EncryptEbs' | |
- 'Yes' | |
ExistingVpc: !Not | |
- !Equals | |
- !Ref 'ExistingVpc' | |
- '' | |
ExistingVpcAndBlankInternetGateway: !And | |
- !Condition 'ExistingVpc' | |
- !Condition 'BlankInternetGateway' | |
ExistingVpcAndInternetGateway: !And | |
- !Condition 'ExistingVpc' | |
- !Condition 'InternetGateway' | |
HttpProxy: !Not | |
- !Equals | |
- !Ref 'HttpProxy' | |
- '' | |
Internal: !Equals | |
- !Ref 'Internal' | |
- 'Yes' | |
InternetGateway: !Not | |
- !Equals | |
- !Ref 'InternetGateway' | |
- '' | |
NotExistingVpcAndBlankInternetGateway: !Not | |
- !Condition 'ExistingVpcAndBlankInternetGateway' | |
Private: !Equals | |
- !Ref 'Private' | |
- 'Yes' | |
PrivateAndThirdAvailabilityZone: !And | |
- !Condition 'Private' | |
- !Condition 'ThirdAvailabilityZone' | |
PrivateApi: !Equals | |
- !Ref 'PrivateApi' | |
- 'Yes' | |
RegionHasEFS: !Equals | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- EFS | |
- 'Yes' | |
RegionHasEFSAndThirdAvailabilityZone: !And | |
- !Condition 'RegionHasEFS' | |
- !Condition 'ThirdAvailabilityZone' | |
SpotInstances: !Not | |
- !Equals | |
- !Ref 'SpotInstanceBid' | |
- '' | |
ThirdAvailabilityZone: !And | |
- !Equals | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- ThirdAvailabilityZone | |
- 'Yes' | |
- !Equals | |
- !Ref 'MaxAvailabilityZones' | |
- '3' | |
ThirdAvailabilityZoneAndNotExistingVpcAndBlankInternetGateway: !And | |
- !Condition 'ThirdAvailabilityZone' | |
- !Condition 'NotExistingVpcAndBlankInternetGateway' | |
Mappings: | |
RegionConfig: | |
ap-northeast-1: | |
Ami: ami-bb5f13dd | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '582318560864' | |
Fargate: 'No' | |
ap-northeast-2: | |
Ami: ami-3b19b455 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '600734575887' | |
Fargate: 'No' | |
ap-south-1: | |
Ami: ami-9e91cff1 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '718504428378' | |
Fargate: 'No' | |
ap-southeast-1: | |
Ami: ami-f88ade84 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '114774131450' | |
Fargate: 'No' | |
ap-southeast-2: | |
Ami: ami-a677b6c4 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '783225319266' | |
Fargate: 'No' | |
ca-central-1: | |
Ami: ami-db48cfbf | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '985666609251' | |
Fargate: 'No' | |
eu-central-1: | |
Ami: ami-3b7d1354 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '054676820928' | |
Fargate: 'No' | |
eu-west-1: | |
Ami: ami-64c4871d | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '156460612806' | |
Fargate: 'No' | |
eu-west-2: | |
Ami: ami-25f51242 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '652711504416' | |
Fargate: 'No' | |
eu-west-3: | |
Ami: ami-0356e07e | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '009996457667' | |
Fargate: 'No' | |
sa-east-1: | |
Ami: ami-da2c66b6 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '507241528517' | |
Fargate: 'No' | |
us-east-1: | |
Ami: ami-cad827b7 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '127311923021' | |
Fargate: 'Yes' | |
us-east-2: | |
Ami: ami-ef64528a | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '033677994240' | |
Fargate: 'No' | |
us-west-1: | |
Ami: ami-29b8b249 | |
EFS: 'No' | |
ThirdAvailabilityZone: 'No' | |
ELBAccountId: '027434742980' | |
Fargate: 'No' | |
us-west-2: | |
Ami: ami-baa236c2 | |
EFS: 'Yes' | |
ThirdAvailabilityZone: 'Yes' | |
ELBAccountId: '797873946194' | |
Fargate: 'No' | |
Outputs: | |
Autoscale: | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
AutoscaleExtra: | |
Value: !Ref 'AutoscaleExtra' | |
AutoscalingGroup: | |
Value: !Ref 'Instances' | |
AwsRegion: | |
Value: !Ref 'AWS::Region' | |
BuildAutoscalingGroup: | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildInstances' | |
- !Ref 'Instances' | |
BuildCluster: | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
CloudformationTopic: | |
Value: !Ref 'CloudformationTopic' | |
Cluster: | |
Export: | |
Name: !Sub '${AWS::StackName}:Cluster' | |
Value: !Ref 'Cluster' | |
CustomTopic: | |
Value: !GetAtt 'CustomTopic.Arn' | |
Dashboard: | |
Value: !GetAtt 'Balancer.DNSName' | |
Domain: | |
Export: | |
Name: !Sub '${AWS::StackName}:Domain' | |
Value: !GetAtt 'Router.DNSName' | |
DomainInternal: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:DomainInternal' | |
Value: !GetAtt 'RouterInternal.DNSName' | |
DynamoBuilds: | |
Value: !Ref 'DynamoBuilds' | |
DynamoReleases: | |
Value: !Ref 'DynamoReleases' | |
EncryptionKey: | |
Export: | |
Name: !Sub '${AWS::StackName}:EncryptionKey' | |
Value: !Ref 'EncryptionKey' | |
Endpoint: | |
Value: !Join | |
- . | |
- - rack | |
- !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- convox.site | |
Fargate: | |
Value: !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Fargate | |
Gateway: | |
Condition: BlankExistingVpc | |
Value: !Ref 'Gateway' | |
GatewayAttachment: | |
Condition: BlankExistingVpc | |
Value: !Ref 'GatewayAttachment' | |
HostedZone: | |
Export: | |
Name: !Sub '${AWS::StackName}:HostedZone' | |
Value: !Ref 'HostedZone' | |
InstancesRole: | |
Value: !GetAtt 'InstancesRole.Arn' | |
Internal: | |
Value: !Ref 'Internal' | |
LogBucket: | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
LogGroup: | |
Value: !Ref 'LogGroup' | |
NatGateways: | |
Value: !If | |
- Private | |
- !Join | |
- ',' | |
- - !Ref 'Nat0' | |
- !Ref 'Nat1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Nat2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
NatIPs: | |
Value: !If | |
- Private | |
- !Join | |
- ',' | |
- - !Ref 'NatAddress0' | |
- !Ref 'NatAddress1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'NatAddress2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
NotificationHost: | |
Value: !GetAtt 'Balancer.DNSName' | |
NotificationTopic: | |
Value: !Ref 'NotificationTopic' | |
OnDemandMinCount: | |
Value: !Ref 'OnDemandMinCount' | |
Password: | |
Condition: Development | |
Value: !Ref 'Password' | |
Private: | |
Value: !Ref 'Private' | |
Provider: | |
Condition: Development | |
Value: aws | |
Rack: | |
Value: !Ref 'AWS::StackName' | |
Release: | |
Value: !Ref 'Version' | |
RouterCertificate: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterCertificate' | |
Value: !Ref 'RouterApiCertificate' | |
RouterHost: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterHost' | |
Value: !Join | |
- . | |
- - !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- convox.site | |
RouterListener80: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterListener80' | |
Value: !Ref 'RouterListener80' | |
RouterListener443: | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterListener443' | |
Value: !Ref 'RouterListener443' | |
RouterInternalHost: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterInternalHost' | |
Value: !Join | |
- . | |
- - !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
- convox.site | |
RouterInternalListener80: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterInternalListener80' | |
Value: !Ref 'RouterInternalListener80' | |
RouterInternalListener443: | |
Condition: Internal | |
Export: | |
Name: !Sub '${AWS::StackName}:RouterInternalListener443' | |
Value: !Ref 'RouterInternalListener443' | |
RouteTablePublic: | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Value: !Ref 'Routes' | |
RouteTablesPrivate: | |
Value: !If | |
- Private | |
- !Join | |
- ',' | |
- - !Ref 'RouteTablePrivate0' | |
- !Ref 'RouteTablePrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'RouteTablePrivate2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
SecurityGroup: | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
ServiceRole: | |
Export: | |
Name: !Sub '${AWS::StackName}:ServiceRole' | |
Value: !GetAtt 'ServiceRole.Arn' | |
SettingsBucket: | |
Value: !Ref 'Settings' | |
SpotInstances: | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
Subnets: | |
Value: !Join | |
- ',' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Subnet0: | |
Export: | |
Name: !Sub '${AWS::StackName}:Subnet0' | |
Value: !Ref 'Subnet0' | |
Subnet1: | |
Export: | |
Name: !Sub '${AWS::StackName}:Subnet1' | |
Value: !Ref 'Subnet1' | |
Subnet2: | |
Condition: ThirdAvailabilityZone | |
Export: | |
Name: !Sub '${AWS::StackName}:Subnet2' | |
Value: !Ref 'Subnet2' | |
SubnetsPrivate: | |
Value: !If | |
- Private | |
- !Join | |
- ',' | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
StackId: | |
Value: !Ref 'AWS::StackId' | |
Vpc: | |
Export: | |
Name: !Sub '${AWS::StackName}:Vpc' | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Vpccidr: | |
Export: | |
Name: !Sub '${AWS::StackName}:VpcCidr' | |
Value: !Ref 'VPCCIDR' | |
Parameters: | |
Ami: | |
Type: String | |
Description: 'Amazon Machine Image: http://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_container_instance.html' | |
Default: '' | |
ApiCount: | |
Type: String | |
Description: The number of api web processes to run | |
Default: '2' | |
ApiMemory: | |
Type: String | |
Description: How much memory should be reserved by the api web process | |
Default: '256' | |
Autoscale: | |
Type: String | |
Description: Autoscale rack instances | |
Default: 'Yes' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
AutoscaleExtra: | |
Type: Number | |
Description: The number of instances of extra capacity that autoscale should keep | |
running | |
Default: '1' | |
BuildCpu: | |
Type: String | |
Description: How much cpu should be reserved by the builder | |
Default: '0' | |
BuildImage: | |
Type: String | |
Description: Override the default builder image | |
Default: '' | |
BuildInstance: | |
Type: String | |
Description: Instance type for a dedicated build cluster | |
Default: '' | |
BuildMemory: | |
Type: String | |
Description: How much memory should be reserved by the builder | |
Default: '1000' | |
BuildVolumeSize: | |
Type: Number | |
Description: Default build disk size in GB | |
Default: '200' | |
ClientId: | |
Type: String | |
Description: Anonymous identifier | |
Default: '' | |
ContainerDisk: | |
Type: Number | |
Description: Default container disk size in GB | |
Default: '10' | |
Development: | |
Type: String | |
Description: Development mode | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
EncryptEbs: | |
Type: String | |
Description: Enable encryption at rest for EBS volumes | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
Encryption: | |
Type: String | |
Description: Encrypt secrets with KMS | |
Default: 'Yes' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
ExistingVpc: | |
Description: Existing VPC ID (if blank a VPC will be created) | |
Type: String | |
Default: '' | |
HttpProxy: | |
Description: Connect using an outbound HTTP proxy (for network-restricted Racks) | |
Type: String | |
Default: '' | |
Internal: | |
Type: String | |
Description: Support applications that are only accessible inside the VPC | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
InstanceBootCommand: | |
Type: String | |
Description: A single line of shell script to run as CloudInit command early during | |
instance boot. | |
Default: '' | |
InstanceRunCommand: | |
Type: String | |
Description: A single line of shell script to run as CloudInit command late during | |
instance boot. | |
Default: '' | |
InstanceCount: | |
Default: '3' | |
Description: The number of instances in the runtime cluster | |
MinValue: '3' | |
Type: Number | |
InstanceType: | |
Default: t2.small | |
Description: The type of the instances in the runtime cluster | |
Type: String | |
InstanceUpdateBatchSize: | |
Default: '1' | |
Description: The number of instances to update in a batch | |
MinValue: '1' | |
Type: Number | |
InstanceSecurityGroup: | |
Default: '' | |
Description: The security group to assign to the ECS instances. If blank, convox | |
will create a security group open to all IPs in your VPC | |
Type: String | |
InternetGateway: | |
Description: The InternetGatway to route to if an Existing VPC is specified | |
Type: String | |
Default: '' | |
Key: | |
Default: '' | |
Description: SSH key name for access to cluster instances | |
Type: String | |
LogBucket: | |
Default: '' | |
Description: Bucket to receive S3 logs | |
Type: String | |
MaxAvailabilityZones: | |
Type: Number | |
Default: '3' | |
AllowedValues: | |
- '2' | |
- '3' | |
OnDemandMinCount: | |
Default: '3' | |
Description: The minimum number of on-demand instances in the runtime cluster | |
Type: Number | |
Password: | |
Description: (REQUIRED) API HTTP password | |
Type: String | |
MinLength: '1' | |
MaxLength: '50' | |
NoEcho: true | |
Private: | |
Type: String | |
Description: Create non publicly routable resources | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
PrivateApi: | |
Type: String | |
Description: Put Rack API Load Balancer in private network | |
Default: 'No' | |
AllowedValues: | |
- 'Yes' | |
- 'No' | |
SpotInstanceBid: | |
Default: '' | |
Description: Bid price for spot instances | |
Type: String | |
Subnet0CIDR: | |
Default: 10.0.1.0/24 | |
Description: Public Subnet 0 CIDR Block | |
Type: String | |
Subnet1CIDR: | |
Default: 10.0.2.0/24 | |
Description: Public Subnet 1 CIDR Block | |
Type: String | |
Subnet2CIDR: | |
Default: 10.0.3.0/24 | |
Description: Public Subnet 2 CIDR Block | |
Type: String | |
SubnetPrivate0CIDR: | |
Default: 10.0.4.0/24 | |
Description: Private Subnet 0 CIDR Block | |
Type: String | |
SubnetPrivate1CIDR: | |
Default: 10.0.5.0/24 | |
Description: Private Subnet 1 CIDR Block | |
Type: String | |
SubnetPrivate2CIDR: | |
Default: 10.0.6.0/24 | |
Description: Private Subnet 2 CIDR Block | |
Type: String | |
SwapSize: | |
Type: Number | |
Description: Default swap volume size in GB | |
Default: '5' | |
RootSize: | |
Type: Number | |
Description: Default root disk size in GB | |
Default: '8' | |
Version: | |
Description: (REQUIRED) Convox release version | |
MinLength: '1' | |
Type: String | |
VolumeSize: | |
Type: Number | |
Description: Default disk size in GB | |
Default: '50' | |
VPCCIDR: | |
Default: 10.0.0.0/16 | |
Description: VPC CIDR Block | |
Type: String | |
Tenancy: | |
Type: String | |
Description: Dedicated Hardware | |
Default: default | |
AllowedValues: | |
- default | |
- dedicated | |
Resources: | |
AvailabilityZones: | |
Type: Custom::EC2AvailabilityZones | |
Properties: | |
ServiceToken: !GetAtt 'CustomTopic.Arn' | |
Vpc: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
EncryptionKey: | |
Type: Custom::KMSKey | |
Properties: | |
ServiceToken: !GetAtt 'CustomTopic.Arn' | |
Description: Convox Master Encryption | |
KeyUsage: ENCRYPT_DECRYPT | |
EncryptionKeyAlias: | |
Type: AWS::KMS::Alias | |
Properties: | |
AliasName: !Join | |
- '' | |
- - alias/convox- | |
- !Ref 'AWS::StackName' | |
TargetKeyId: !Ref 'EncryptionKey' | |
LogGroup: | |
Type: AWS::Logs::LogGroup | |
CustomTopicRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- lambda.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: Administrator | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: '*' | |
Resource: '*' | |
- Effect: Deny | |
Action: s3:DeleteObject | |
Resource: '*' | |
NotificationTopic: | |
Type: AWS::SNS::Topic | |
Properties: | |
TopicName: !Join | |
- '' | |
- - !Ref 'AWS::StackName' | |
- -notifications | |
CustomTopic: | |
Type: AWS::Lambda::Function | |
Properties: | |
Code: | |
S3Bucket: !Join | |
- '-' | |
- - convox | |
- !Ref 'AWS::Region' | |
S3Key: !Join | |
- '' | |
- - release/ | |
- !Ref 'Version' | |
- /lambda/formation.zip | |
Description: Convox handler for custom resources | |
Handler: index.external | |
MemorySize: '128' | |
Role: !GetAtt 'CustomTopicRole.Arn' | |
Runtime: nodejs4.3 | |
Timeout: '300' | |
Vpc: | |
Type: AWS::EC2::VPC | |
Condition: BlankExistingVpc | |
Properties: | |
CidrBlock: !Ref 'VPCCIDR' | |
EnableDnsSupport: 'true' | |
EnableDnsHostnames: 'true' | |
InstanceTenancy: !Ref 'Tenancy' | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
Gateway: | |
Type: AWS::EC2::InternetGateway | |
Condition: BlankExistingVpc | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
GatewayAttachment: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Condition: BlankExistingVpc | |
Properties: | |
InternetGatewayId: !Ref 'Gateway' | |
VpcId: !Ref 'Vpc' | |
ExistingGatewayAttachment: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Condition: ExistingVpcAndInternetGateway | |
DeletionPolicy: Retain | |
Properties: | |
InternetGatewayId: !Ref 'InternetGateway' | |
VpcId: !Ref 'ExistingVpc' | |
Nat0: | |
Condition: Private | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt 'NatAddress0.AllocationId' | |
SubnetId: !Ref 'Subnet0' | |
Nat1: | |
Condition: Private | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt 'NatAddress1.AllocationId' | |
SubnetId: !Ref 'Subnet1' | |
Nat2: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::NatGateway | |
Properties: | |
AllocationId: !GetAtt 'NatAddress2.AllocationId' | |
SubnetId: !Ref 'Subnet2' | |
NatAddress0: | |
Condition: Private | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
NatAddress1: | |
Condition: Private | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
NatAddress2: | |
Condition: Private | |
Type: AWS::EC2::EIP | |
Properties: | |
Domain: vpc | |
SecureEnvironmentRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs-tasks.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: SecureEnvironmentPolicy | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
Effect: Allow | |
Action: | |
- kms:Decrypt | |
Resource: | |
- !Ref 'EncryptionKey' | |
Subnet0: | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join | |
- ' ' | |
- - !Ref 'AWS::StackName' | |
- public | |
- '0' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone0' | |
CidrBlock: !Ref 'Subnet0CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Subnet1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join | |
- ' ' | |
- - !Ref 'AWS::StackName' | |
- public | |
- '1' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone1' | |
CidrBlock: !Ref 'Subnet1CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Subnet2: | |
Condition: ThirdAvailabilityZone | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join | |
- ' ' | |
- - !Ref 'AWS::StackName' | |
- public | |
- '2' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone2' | |
CidrBlock: !Ref 'Subnet2CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
SubnetPrivate0: | |
Condition: Private | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join | |
- ' ' | |
- - !Ref 'AWS::StackName' | |
- private | |
- '0' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone0' | |
CidrBlock: !Ref 'SubnetPrivate0CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
SubnetPrivate1: | |
Condition: Private | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join | |
- ' ' | |
- - !Ref 'AWS::StackName' | |
- private | |
- '1' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone1' | |
CidrBlock: !Ref 'SubnetPrivate1CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
SubnetPrivate2: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::Subnet | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Join | |
- ' ' | |
- - !Ref 'AWS::StackName' | |
- private | |
- '2' | |
AvailabilityZone: !GetAtt 'AvailabilityZones.AvailabilityZone2' | |
CidrBlock: !Ref 'SubnetPrivate2CIDR' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Routes: | |
Type: AWS::EC2::RouteTable | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Properties: | |
Tags: | |
- Key: GatewayAttachment | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'GatewayAttachment' | |
- existing | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteDefault: | |
Type: AWS::EC2::Route | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Properties: | |
DestinationCidrBlock: '0.0.0.0/0' | |
GatewayId: !If | |
- ExistingVpcAndInternetGateway | |
- !Ref 'InternetGateway' | |
- !Ref 'Gateway' | |
RouteTableId: !Ref 'Routes' | |
RouteTablePrivate0: | |
Condition: Private | |
DependsOn: | |
- Nat0 | |
Type: AWS::EC2::RouteTable | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteTablePrivate1: | |
Condition: Private | |
DependsOn: | |
- Nat1 | |
Type: AWS::EC2::RouteTable | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteTablePrivate2: | |
Condition: PrivateAndThirdAvailabilityZone | |
DependsOn: | |
- Nat2 | |
Type: AWS::EC2::RouteTable | |
Properties: | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouteDefaultPrivate0: | |
Condition: Private | |
Type: AWS::EC2::Route | |
Properties: | |
DestinationCidrBlock: '0.0.0.0/0' | |
NatGatewayId: !Ref 'Nat0' | |
RouteTableId: !Ref 'RouteTablePrivate0' | |
RouteDefaultPrivate1: | |
Condition: Private | |
Type: AWS::EC2::Route | |
Properties: | |
DestinationCidrBlock: '0.0.0.0/0' | |
NatGatewayId: !Ref 'Nat1' | |
RouteTableId: !Ref 'RouteTablePrivate1' | |
RouteDefaultPrivate2: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::Route | |
Properties: | |
DestinationCidrBlock: '0.0.0.0/0' | |
NatGatewayId: !Ref 'Nat2' | |
RouteTableId: !Ref 'RouteTablePrivate2' | |
Subnet0Routes: | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'Subnet0' | |
RouteTableId: !Ref 'Routes' | |
Subnet1Routes: | |
Condition: NotExistingVpcAndBlankInternetGateway | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'Subnet1' | |
RouteTableId: !Ref 'Routes' | |
Subnet2Routes: | |
Condition: ThirdAvailabilityZoneAndNotExistingVpcAndBlankInternetGateway | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'Subnet2' | |
RouteTableId: !Ref 'Routes' | |
SubnetPrivate0Routes: | |
Condition: Private | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'SubnetPrivate0' | |
RouteTableId: !Ref 'RouteTablePrivate0' | |
SubnetPrivate1Routes: | |
Condition: Private | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'SubnetPrivate1' | |
RouteTableId: !Ref 'RouteTablePrivate1' | |
SubnetPrivate2Routes: | |
Condition: PrivateAndThirdAvailabilityZone | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref 'SubnetPrivate2' | |
RouteTableId: !Ref 'RouteTablePrivate2' | |
HostedZone: | |
Type: AWS::Route53::HostedZone | |
Properties: | |
Name: !Sub '${AWS::StackName}.convox' | |
VPCs: | |
- VPCId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
VPCRegion: !Ref 'AWS::Region' | |
RecordSetRack: | |
Type: AWS::Route53::RecordSet | |
Properties: | |
HostedZoneId: !Ref 'HostedZone' | |
Name: !Sub 'rack.${AWS::StackName}.convox.' | |
Type: CNAME | |
TTL: '3600' | |
ResourceRecords: | |
- !GetAtt 'Balancer.DNSName' | |
InstancesSecurity: | |
DependsOn: ApiRole | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} instances' | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: '0' | |
ToPort: '65535' | |
CidrIp: !Ref 'VPCCIDR' | |
- IpProtocol: udp | |
FromPort: '0' | |
ToPort: '65535' | |
CidrIp: !Ref 'VPCCIDR' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-instances' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
InstancesRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ec2.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Version: '2012-10-17' | |
Path: /convox/ | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role | |
- arn:aws:iam::aws:policy/AutoScalingFullAccess | |
InstancesProfile: | |
DependsOn: ApiRole | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Path: /convox/ | |
Roles: | |
- !Ref 'InstancesRole' | |
BuildCluster: | |
Condition: DedicatedBuilder | |
Type: AWS::ECS::Cluster | |
BuildLaunchConfiguration: | |
Condition: DedicatedBuilder | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
AssociatePublicIpAddress: !If | |
- Private | |
- false | |
- true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: !Ref 'RootSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdb | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'SwapSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdcz | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'BuildVolumeSize' | |
VolumeType: gp2 | |
IamInstanceProfile: !Ref 'InstancesProfile' | |
ImageId: !If | |
- BlankAmi | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Ami | |
- !Ref 'Ami' | |
InstanceMonitoring: true | |
InstanceType: !Ref 'BuildInstance' | |
KeyName: !If | |
- BlankKey | |
- !Ref 'AWS::NoValue' | |
- !Ref 'Key' | |
PlacementTenancy: !Ref 'Tenancy' | |
SecurityGroups: | |
- !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
UserData: !Base64 | |
Fn::Join: | |
- '' | |
- - "#cloud-config\n" | |
- "repo_upgrade_exclude:\n" | |
- " - kernel*\n" | |
- "packages:\n" | |
- " - aws-cfn-bootstrap\n" | |
- "mounts:\n" | |
- " - ['/dev/xvdb', 'none', 'swap', 'sw', '0', '0']\n" | |
- "bootcmd:\n" | |
- " - mkswap /dev/xvdb\n" | |
- " - swapon /dev/xvdb\n" | |
- " - [ cloud-init-per, instance, docker_storage_setup, /usr/bin/docker-storage-setup\ | |
\ ]\n" | |
- ' - export http_proxy=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo http_proxy=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export https_proxy=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo https_proxy=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export HTTPS_PROXY=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo HTTPS_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- " - export NO_PROXY=169.254.169.254\n" | |
- " - echo NO_PROXY=169.254.169.254 >> /etc/environment\n" | |
- !If | |
- HttpProxy | |
- !Join | |
- '' | |
- - ' - echo "proxy=' | |
- !Ref 'HttpProxy' | |
- "/\" >> /etc/yum.conf\n" | |
- !Ref 'AWS::NoValue' | |
- ' - echo ECS_CLUSTER=' | |
- !Ref 'BuildCluster' | |
- " >> /etc/ecs/ecs.config\n" | |
- " - echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config\n" | |
- " - echo 'ECS_INSTANCE_ATTRIBUTES={\"asg\":\"build\"}' >> /etc/ecs/ecs.config\n" | |
- ' - echo HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/ecs/ecs.config\n" | |
- " - echo NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock\ | |
\ >> /etc/ecs/ecs.config\n" | |
- " - head -n -1 /etc/sysconfig/docker >> /etc/sysconfig/docker-tmp\n" | |
- " - mv /etc/sysconfig/docker-tmp /etc/sysconfig/docker\n" | |
- " - echo 'OPTIONS=\"--default-ulimit nofile=1024000:1024000\"' >> /etc/sysconfig/docker\n" | |
- !Join | |
- '' | |
- - ' - echo ''OPTIONS="${OPTIONS} --storage-opt dm.basesize=' | |
- !Ref 'ContainerDisk' | |
- "G\"' >> /etc/sysconfig/docker\n" | |
- " - echo 'OPTIONS=\"${OPTIONS} --log-opt max-file=2 --log-opt max-size=50m\ | |
\ --host=unix:///var/run/docker.sock --host=0.0.0.0:2376\"' >> /etc/sysconfig/docker\n" | |
- " - echo 'ECS_ENGINE_AUTH_DATA={\"index.docker.io\":{\"username\"\ | |
:\"\",\"password\":\"\",\"email\":\"\"}' >> /etc/ecs/ecs.config\n" | |
- !If | |
- HttpProxy | |
- !Join | |
- '' | |
- - ' - echo "export HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- "/\" >> /etc/sysconfig/docker\n" | |
- !Ref 'AWS::NoValue' | |
- " - echo -e '/var/log/docker {\\n rotate 7\\n daily\\n nocompress\\\ | |
n copytruncate\\n}' >> /etc/logrotate.d/docker\n" | |
- !If | |
- BlankInstanceBootCommand | |
- !Ref 'AWS::NoValue' | |
- !Join | |
- '' | |
- - ' - ' | |
- !Ref 'InstanceBootCommand' | |
- "\n" | |
- "runcmd:\n" | |
- !If | |
- BlankInstanceRunCommand | |
- !Ref 'AWS::NoValue' | |
- !Join | |
- '' | |
- - ' - ' | |
- !Ref 'InstanceRunCommand' | |
- "\n" | |
- ' - /opt/aws/bin/cfn-signal --http-proxy "' | |
- !Ref 'HttpProxy' | |
- '" --stack ' | |
- !Ref 'AWS::StackName' | |
- ' --region ' | |
- !Ref 'AWS::Region' | |
- " --resource BuildInstances\n" | |
BuildInstances: | |
Condition: DedicatedBuilder | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
LaunchConfigurationName: !Ref 'BuildLaunchConfiguration' | |
VPCZoneIdentifier: !If | |
- Private | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Cooldown: 5 | |
DesiredCapacity: '1' | |
HealthCheckType: EC2 | |
HealthCheckGracePeriod: '120' | |
MinSize: '1' | |
MaxSize: '2' | |
MetricsCollection: | |
- Granularity: 1Minute | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
PropagateAtLaunch: false | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MaxBatchSize: !Ref 'InstanceUpdateBatchSize' | |
MinInstancesInService: '1' | |
PauseTime: PT15M | |
SuspendProcesses: | |
- ScheduledActions | |
WaitOnResourceSignals: 'true' | |
LaunchConfiguration: | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
AssociatePublicIpAddress: !If | |
- Private | |
- false | |
- true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: !Ref 'RootSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdb | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'SwapSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdcz | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'VolumeSize' | |
VolumeType: gp2 | |
IamInstanceProfile: !Ref 'InstancesProfile' | |
ImageId: !If | |
- BlankAmi | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Ami | |
- !Ref 'Ami' | |
InstanceMonitoring: true | |
InstanceType: !Ref 'InstanceType' | |
KeyName: !If | |
- BlankKey | |
- !Ref 'AWS::NoValue' | |
- !Ref 'Key' | |
PlacementTenancy: !Ref 'Tenancy' | |
SecurityGroups: | |
- !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
UserData: !Base64 | |
Fn::Join: | |
- '' | |
- - "#cloud-config\n" | |
- "repo_upgrade_exclude:\n" | |
- " - kernel*\n" | |
- "packages:\n" | |
- " - aws-cfn-bootstrap\n" | |
- "mounts:\n" | |
- " - ['/dev/xvdb', 'none', 'swap', 'sw', '0', '0']\n" | |
- "bootcmd:\n" | |
- " - mkswap /dev/xvdb\n" | |
- " - swapon /dev/xvdb\n" | |
- ' - export http_proxy=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo http_proxy=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export https_proxy=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo https_proxy=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export HTTPS_PROXY=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo HTTPS_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- " - export NO_PROXY=169.254.169.254\n" | |
- " - echo NO_PROXY=169.254.169.254 >> /etc/environment\n" | |
- !If | |
- HttpProxy | |
- !Join | |
- '' | |
- - ' - echo "proxy=' | |
- !Ref 'HttpProxy' | |
- "/\" >> /etc/yum.conf\n" | |
- !Ref 'AWS::NoValue' | |
- " - until yum install -y aws-cli nfs-utils; do echo \"Waiting for network\"\ | |
; done;\n" | |
- " - mkdir /volumes\n" | |
- !If | |
- RegionHasEFS | |
- !Join | |
- '' | |
- - ' - while true; do mount -t nfs -o nfsvers=4.1 $(curl -s --noproxy | |
169.254.169.254 http://169.254.169.254/latest/meta-data/placement/availability-zone).' | |
- !Ref 'VolumeFilesystem' | |
- .efs. | |
- !Ref 'AWS::Region' | |
- ".amazonaws.com:/ /volumes && break; sleep 5; done\n" | |
- '' | |
- " - [ cloud-init-per, instance, docker_storage_setup, /usr/bin/docker-storage-setup\ | |
\ ]\n" | |
- ' - echo ECS_CLUSTER=' | |
- !Ref 'Cluster' | |
- " >> /etc/ecs/ecs.config\n" | |
- " - echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config\n" | |
- " - echo 'ECS_INSTANCE_ATTRIBUTES={\"asg\":\"primary\"}' >> /etc/ecs/ecs.config\n" | |
- ' - echo HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/ecs/ecs.config\n" | |
- " - echo NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock\ | |
\ >> /etc/ecs/ecs.config\n" | |
- " - head -n -1 /etc/sysconfig/docker >> /etc/sysconfig/docker-tmp\n" | |
- " - mv /etc/sysconfig/docker-tmp /etc/sysconfig/docker\n" | |
- " - echo 'OPTIONS=\"--default-ulimit nofile=1024000:1024000\"' >> /etc/sysconfig/docker\n" | |
- !Join | |
- '' | |
- - ' - echo ''OPTIONS="${OPTIONS} --storage-opt dm.basesize=' | |
- !Ref 'ContainerDisk' | |
- "G\"' >> /etc/sysconfig/docker\n" | |
- " - echo 'OPTIONS=\"${OPTIONS} --log-opt max-file=2 --log-opt max-size=50m\ | |
\ --host=unix:///var/run/docker.sock --host=0.0.0.0:2376\"' >> /etc/sysconfig/docker\n" | |
- " - echo 'ECS_ENGINE_AUTH_DATA={\"index.docker.io\":{\"username\"\ | |
:\"\",\"password\":\"\",\"email\":\"\"}' >> /etc/ecs/ecs.config\n" | |
- !If | |
- HttpProxy | |
- !Join | |
- '' | |
- - ' - echo "export HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- "/\" >> /etc/sysconfig/docker\n" | |
- !Ref 'AWS::NoValue' | |
- " - echo -e '/var/log/docker {\\n rotate 7\\n daily\\n nocompress\\\ | |
n copytruncate\\n}' >> /etc/logrotate.d/docker\n" | |
- !If | |
- BlankInstanceBootCommand | |
- !Ref 'AWS::NoValue' | |
- !Join | |
- '' | |
- - ' - ' | |
- !Ref 'InstanceBootCommand' | |
- "\n" | |
- "runcmd:\n" | |
- !If | |
- BlankInstanceRunCommand | |
- !Ref 'AWS::NoValue' | |
- !Join | |
- '' | |
- - ' - ' | |
- !Ref 'InstanceRunCommand' | |
- "\n" | |
- " - export INSTANCE_ID=$(curl -s --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id)\n" | |
- ' - export ASG_NAME=$(env $(cat /etc/environment) /usr/bin/aws autoscaling | |
describe-auto-scaling-instances --instance-ids=$INSTANCE_ID --region ' | |
- !Ref 'AWS::Region' | |
- " --output text --query 'AutoScalingInstances[0].AutoScalingGroupName')\n" | |
- ' - export LIFECYCLE_HOOK=$(env $(cat /etc/environment) /usr/bin/aws | |
autoscaling describe-lifecycle-hooks --auto-scaling-group-name $ASG_NAME | |
--region ' | |
- !Ref 'AWS::Region' | |
- ' --output text --query "LifecycleHooks[?contains(LifecycleHookName, | |
''' | |
- !Ref 'AWS::StackName' | |
- "-InstancesLifecycleLaunching') == \\`true\\`].LifecycleHookName | [0]\"\ | |
)\n" | |
- ' - env $(cat /etc/environment) /usr/bin/aws autoscaling complete-lifecycle-action | |
--region ' | |
- !Ref 'AWS::Region' | |
- " --instance-id $INSTANCE_ID --lifecycle-hook-name $LIFECYCLE_HOOK --auto-scaling-group-name\ | |
\ $ASG_NAME --lifecycle-action-result CONTINUE\n" | |
- ' - env $(cat /etc/environment) /opt/aws/bin/cfn-signal --http-proxy | |
"' | |
- !Ref 'HttpProxy' | |
- '" --stack ' | |
- !Ref 'AWS::StackName' | |
- ' --region ' | |
- !Ref 'AWS::Region' | |
- " --resource Instances\n" | |
Instances: | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
LaunchConfigurationName: !Ref 'LaunchConfiguration' | |
VPCZoneIdentifier: !If | |
- Private | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Cooldown: 5 | |
DesiredCapacity: !If | |
- SpotInstances | |
- !Ref 'AWS::NoValue' | |
- !Ref 'InstanceCount' | |
HealthCheckType: EC2 | |
HealthCheckGracePeriod: '120' | |
MinSize: !If | |
- SpotInstances | |
- !Ref 'OnDemandMinCount' | |
- !Ref 'InstanceCount' | |
MaxSize: '1000' | |
MetricsCollection: | |
- Granularity: 1Minute | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
PropagateAtLaunch: false | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MaxBatchSize: !Ref 'InstanceUpdateBatchSize' | |
MinInstancesInService: !If | |
- SpotInstances | |
- !Ref 'OnDemandMinCount' | |
- !Ref 'InstanceCount' | |
PauseTime: PT15M | |
SuspendProcesses: | |
- ScheduledActions | |
WaitOnResourceSignals: 'true' | |
InstancesLifecycleLaunching: | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'Instances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '600' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
InstancesLifecycleTerminating: | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'Instances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '300' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
InstancesLifecycleRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- autoscaling.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: InstancesLifecycleRole | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- sns:Publish | |
Resource: !Ref 'InstancesLifecycleTopic' | |
InstancesLifecycleTopic: | |
Type: AWS::SNS::Topic | |
Properties: | |
Subscription: | |
- Endpoint: !GetAtt 'InstancesLifecycleHandler.Arn' | |
Protocol: lambda | |
TopicName: !Join | |
- '' | |
- - !Ref 'AWS::StackName' | |
- -lifecycle | |
InstancesLifecycleHandler: | |
Type: AWS::Lambda::Function | |
Properties: | |
Code: | |
S3Bucket: !Join | |
- '-' | |
- - convox | |
- !Ref 'AWS::Region' | |
S3Key: !Join | |
- '' | |
- - release/ | |
- !Ref 'Version' | |
- /lambda/lifecycle.zip | |
Description: !Join | |
- '' | |
- - '{"Cluster": "' | |
- !Ref 'Cluster' | |
- '", "Rack": "' | |
- !Ref 'AWS::StackName' | |
- '"}' | |
Handler: index.external | |
MemorySize: '128' | |
Role: !GetAtt 'InstancesLifecycleHandlerRole.Arn' | |
Runtime: nodejs4.3 | |
Timeout: '300' | |
InstancesLifecycleHandlerPermission: | |
Type: AWS::Lambda::Permission | |
Properties: | |
FunctionName: !GetAtt 'InstancesLifecycleHandler.Arn' | |
Action: lambda:InvokeFunction | |
Principal: sns.amazonaws.com | |
SourceArn: !Ref 'InstancesLifecycleTopic' | |
InstancesLifecycleHandlerRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- lambda.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Path: /convox/ | |
Policies: | |
- PolicyName: InstancesLifecycleHandlerRole | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- autoscaling:CompleteLifecycleAction | |
- ecs:DeregisterContainerInstance | |
- ecs:DescribeContainerInstances | |
- ecs:DescribeServices | |
- ecs:DescribeTasks | |
- ecs:ListContainerInstances | |
- ecs:ListServices | |
- ecs:ListTasks | |
- ecs:StopTask | |
- ecs:UpdateContainerInstancesState | |
- lambda:GetFunction | |
- logs:CreateLogGroup | |
- logs:CreateLogStream | |
- logs:PutLogEvents | |
Resource: '*' | |
SpotLaunchConfiguration: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::LaunchConfiguration | |
Properties: | |
AssociatePublicIpAddress: !If | |
- Private | |
- false | |
- true | |
BlockDeviceMappings: | |
- DeviceName: /dev/xvda | |
Ebs: | |
VolumeSize: !Ref 'RootSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdb | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'SwapSize' | |
VolumeType: gp2 | |
- DeviceName: /dev/xvdcz | |
Ebs: | |
Encrypted: !If | |
- EncryptEbs | |
- 'true' | |
- !Ref 'AWS::NoValue' | |
VolumeSize: !Ref 'VolumeSize' | |
VolumeType: gp2 | |
IamInstanceProfile: !Ref 'InstancesProfile' | |
ImageId: !If | |
- BlankAmi | |
- !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Ami | |
- !Ref 'Ami' | |
InstanceMonitoring: true | |
InstanceType: !Ref 'InstanceType' | |
KeyName: !If | |
- BlankKey | |
- !Ref 'AWS::NoValue' | |
- !Ref 'Key' | |
SecurityGroups: | |
- !Ref 'InstancesSecurity' | |
SpotPrice: !Ref 'SpotInstanceBid' | |
UserData: !Base64 | |
Fn::Join: | |
- '' | |
- - "#cloud-config\n" | |
- "repo_upgrade_exclude:\n" | |
- " - kernel*\n" | |
- "packages:\n" | |
- " - aws-cfn-bootstrap\n" | |
- "mounts:\n" | |
- " - ['/dev/xvdb', 'none', 'swap', 'sw', '0', '0']\n" | |
- "bootcmd:\n" | |
- " - mkswap /dev/xvdb\n" | |
- " - swapon /dev/xvdb\n" | |
- ' - export http_proxy=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo http_proxy=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export https_proxy=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo https_proxy=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- ' - export HTTPS_PROXY=' | |
- !Ref 'HttpProxy' | |
- "\n" | |
- ' - echo HTTPS_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/environment\n" | |
- " - export NO_PROXY=169.254.169.254\n" | |
- " - echo NO_PROXY=169.254.169.254 >> /etc/environment\n" | |
- !If | |
- HttpProxy | |
- !Join | |
- '' | |
- - ' - echo "proxy=' | |
- !Ref 'HttpProxy' | |
- "/\" >> /etc/yum.conf\n" | |
- !Ref 'AWS::NoValue' | |
- " - until yum install -y aws-cli nfs-utils; do echo \"Waiting for network\"\ | |
; done;\n" | |
- " - mkdir /volumes\n" | |
- !If | |
- RegionHasEFS | |
- !Join | |
- '' | |
- - ' - while true; do mount -t nfs -o nfsvers=4.1 $(curl -s --noproxy | |
169.254.169.254 http://169.254.169.254/latest/meta-data/placement/availability-zone).' | |
- !Ref 'VolumeFilesystem' | |
- .efs. | |
- !Ref 'AWS::Region' | |
- ".amazonaws.com:/ /volumes && break; sleep 5; done\n" | |
- '' | |
- " - [ cloud-init-per, instance, docker_storage_setup, /usr/bin/docker-storage-setup\ | |
\ ]\n" | |
- ' - echo ECS_CLUSTER=' | |
- !Ref 'Cluster' | |
- " >> /etc/ecs/ecs.config\n" | |
- " - echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config\n" | |
- " - echo 'ECS_INSTANCE_ATTRIBUTES={\"asg\":\"spot\"}' >> /etc/ecs/ecs.config\n" | |
- ' - echo HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- " >> /etc/ecs/ecs.config\n" | |
- " - echo NO_PROXY=169.254.169.254,169.254.170.2,/var/run/docker.sock\ | |
\ >> /etc/ecs/ecs.config\n" | |
- " - head -n -1 /etc/sysconfig/docker >> /etc/sysconfig/docker-tmp\n" | |
- " - mv /etc/sysconfig/docker-tmp /etc/sysconfig/docker\n" | |
- " - echo 'OPTIONS=\"--default-ulimit nofile=1024000:1024000\"' >> /etc/sysconfig/docker\n" | |
- !Join | |
- '' | |
- - ' - echo ''OPTIONS="${OPTIONS} --storage-opt dm.basesize=' | |
- !Ref 'ContainerDisk' | |
- "G\"' >> /etc/sysconfig/docker\n" | |
- " - echo 'OPTIONS=\"${OPTIONS} --log-opt max-file=2 --log-opt max-size=50m\ | |
\ --host=unix:///var/run/docker.sock --host=0.0.0.0:2376\"' >> /etc/sysconfig/docker\n" | |
- " - echo 'ECS_ENGINE_AUTH_DATA={\"index.docker.io\":{\"username\"\ | |
:\"\",\"password\":\"\",\"email\":\"\"}' >> /etc/ecs/ecs.config\n" | |
- !If | |
- HttpProxy | |
- !Join | |
- '' | |
- - ' - echo "export HTTP_PROXY=' | |
- !Ref 'HttpProxy' | |
- "/\" >> /etc/sysconfig/docker\n" | |
- !Ref 'AWS::NoValue' | |
- " - echo -e '/var/log/docker {\\n rotate 7\\n daily\\n nocompress\\\ | |
n copytruncate\\n}' >> /etc/logrotate.d/docker\n" | |
- !If | |
- BlankInstanceBootCommand | |
- !Ref 'AWS::NoValue' | |
- !Join | |
- '' | |
- - ' - ' | |
- !Ref 'InstanceBootCommand' | |
- "\n" | |
- "runcmd:\n" | |
- !If | |
- BlankInstanceRunCommand | |
- !Ref 'AWS::NoValue' | |
- !Join | |
- '' | |
- - ' - ' | |
- !Ref 'InstanceRunCommand' | |
- "\n" | |
- " - export INSTANCE_ID=$(curl -s --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id)\n" | |
- ' - export ASG_NAME=$(env $(cat /etc/environment) /usr/bin/aws autoscaling | |
describe-auto-scaling-instances --instance-ids=$INSTANCE_ID --region ' | |
- !Ref 'AWS::Region' | |
- " --output text --query 'AutoScalingInstances[0].AutoScalingGroupName')\n" | |
- ' - export LIFECYCLE_HOOK=$(env $(cat /etc/environment) /usr/bin/aws | |
autoscaling describe-lifecycle-hooks --auto-scaling-group-name $ASG_NAME | |
--region ' | |
- !Ref 'AWS::Region' | |
- ' --output text --query "LifecycleHooks[?contains(LifecycleHookName, | |
''' | |
- !Ref 'AWS::StackName' | |
- "-SpotInstancesLifecycleLaunching') == \\`true\\`].LifecycleHookName\ | |
\ | [0]\")\n" | |
- ' - env $(cat /etc/environment) /usr/bin/aws autoscaling complete-lifecycle-action | |
--region ' | |
- !Ref 'AWS::Region' | |
- " --instance-id $INSTANCE_ID --lifecycle-hook-name $LIFECYCLE_HOOK --auto-scaling-group-name\ | |
\ $ASG_NAME --lifecycle-action-result CONTINUE\n" | |
- ' - env $(cat /etc/environment) /opt/aws/bin/cfn-signal --http-proxy | |
"' | |
- !Ref 'HttpProxy' | |
- '" --stack ' | |
- !Ref 'AWS::StackName' | |
- ' --region ' | |
- !Ref 'AWS::Region' | |
- " --resource SpotInstances\n" | |
SpotInstances: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::AutoScalingGroup | |
Properties: | |
LaunchConfigurationName: !Ref 'SpotLaunchConfiguration' | |
VPCZoneIdentifier: !If | |
- Private | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Cooldown: 5 | |
HealthCheckType: EC2 | |
HealthCheckGracePeriod: '120' | |
MinSize: '0' | |
MaxSize: '1000' | |
MetricsCollection: | |
- Granularity: 1Minute | |
Tags: | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
PropagateAtLaunch: true | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
PropagateAtLaunch: false | |
- Key: InstanceCount | |
Value: !Ref 'InstanceCount' | |
PropagateAtLaunch: false | |
UpdatePolicy: | |
AutoScalingRollingUpdate: | |
MaxBatchSize: !Ref 'InstanceUpdateBatchSize' | |
MinInstancesInService: '0' | |
PauseTime: PT15M | |
SuspendProcesses: | |
- ScheduledActions | |
WaitOnResourceSignals: 'true' | |
SpotInstancesLifecycleLaunching: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'SpotInstances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '600' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
SpotInstancesLifecycleTerminating: | |
Condition: SpotInstances | |
Type: AWS::AutoScaling::LifecycleHook | |
Properties: | |
AutoScalingGroupName: !Ref 'SpotInstances' | |
DefaultResult: CONTINUE | |
HeartbeatTimeout: '300' | |
LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING | |
NotificationTargetARN: !Ref 'InstancesLifecycleTopic' | |
RoleARN: !GetAtt 'InstancesLifecycleRole.Arn' | |
VolumeFilesystem: | |
Type: AWS::EFS::FileSystem | |
Condition: RegionHasEFS | |
Properties: | |
FileSystemTags: | |
- Key: Name | |
Value: !Join | |
- '-' | |
- - !Ref 'AWS::StackName' | |
- shared-volumes | |
VolumeSecurity: | |
DependsOn: ApiRole | |
Type: AWS::EC2::SecurityGroup | |
Condition: RegionHasEFS | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} volumes' | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: '2049' | |
ToPort: '2049' | |
CidrIp: !Ref 'VPCCIDR' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-volumes' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
VolumeTarget0: | |
Type: AWS::EFS::MountTarget | |
Condition: RegionHasEFS | |
Properties: | |
FileSystemId: !Ref 'VolumeFilesystem' | |
SubnetId: !If | |
- Private | |
- !Ref 'SubnetPrivate0' | |
- !Ref 'Subnet0' | |
SecurityGroups: | |
- !Ref 'VolumeSecurity' | |
VolumeTarget1: | |
Type: AWS::EFS::MountTarget | |
Condition: RegionHasEFS | |
Properties: | |
FileSystemId: !Ref 'VolumeFilesystem' | |
SubnetId: !If | |
- Private | |
- !Ref 'SubnetPrivate1' | |
- !Ref 'Subnet1' | |
SecurityGroups: | |
- !Ref 'VolumeSecurity' | |
VolumeTarget2: | |
Type: AWS::EFS::MountTarget | |
Condition: RegionHasEFSAndThirdAvailabilityZone | |
Properties: | |
FileSystemId: !Ref 'VolumeFilesystem' | |
SubnetId: !If | |
- Private | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'Subnet2' | |
SecurityGroups: | |
- !Ref 'VolumeSecurity' | |
AccountEvents: | |
Type: AWS::SQS::Queue | |
AccountEventsPolicy: | |
Type: AWS::SQS::QueuePolicy | |
Properties: | |
Queues: | |
- !Ref 'AccountEvents' | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
AWS: '*' | |
Action: sqs:SendMessage | |
Resource: !GetAtt 'AccountEvents.Arn' | |
Condition: | |
ArnEquals: | |
aws:SourceArn: !GetAtt 'AccountEventsRule.Arn' | |
AccountEventsRule: | |
Type: AWS::Events::Rule | |
Properties: | |
Description: Specified event changes | |
EventPattern: | |
account: | |
- !Ref 'AWS::AccountId' | |
source: | |
- aws.ecs | |
detail-type: | |
- ECS Task State Change | |
detail: | |
clusterArn: | |
- !Sub 'arn:aws:ecs:${AWS::Region}:${AWS::AccountId}:cluster/${Cluster}' | |
State: ENABLED | |
Targets: | |
- Arn: !GetAtt 'AccountEvents.Arn' | |
Id: Events | |
CloudformationEvents: | |
Type: AWS::SQS::Queue | |
CloudformationEventsPolicy: | |
Type: AWS::SQS::QueuePolicy | |
Properties: | |
Queues: | |
- !Ref 'CloudformationEvents' | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Principal: | |
AWS: '*' | |
Action: sqs:SendMessage | |
Resource: !GetAtt 'CloudformationEvents.Arn' | |
Condition: | |
ArnEquals: | |
aws:SourceArn: !Ref 'CloudformationTopic' | |
CloudformationTopic: | |
Type: AWS::SNS::Topic | |
Properties: | |
DisplayName: !Sub '${AWS::StackName}-events' | |
Subscription: | |
- Protocol: sqs | |
Endpoint: !GetAtt 'CloudformationEvents.Arn' | |
Router: | |
DependsOn: | |
- ApiRole | |
- LogsPolicy | |
Type: AWS::ElasticLoadBalancingV2::LoadBalancer | |
Properties: | |
LoadBalancerAttributes: | |
- Key: access_logs.s3.enabled | |
Value: 'true' | |
- Key: access_logs.s3.bucket | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
- Key: access_logs.s3.prefix | |
Value: !Sub 'convox/logs/${AWS::StackName}/alb' | |
- Key: idle_timeout.timeout_seconds | |
Value: '3600' | |
Subnets: | |
- !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
SecurityGroups: | |
- !Ref 'RouterSecurity' | |
RouterSecurity: | |
Type: AWS::EC2::SecurityGroup | |
DependsOn: ApiRole | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} router' | |
SecurityGroupIngress: | |
- CidrIp: '0.0.0.0/0' | |
IpProtocol: tcp | |
FromPort: '0' | |
ToPort: '65535' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-router' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouterListener80: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Properties: | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterApiTargetGroup' | |
LoadBalancerArn: !Ref 'Router' | |
Port: '80' | |
Protocol: HTTP | |
RouterListener443: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Properties: | |
Certificates: | |
- CertificateArn: !Ref 'RouterApiCertificate' | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterApiTargetGroup' | |
LoadBalancerArn: !Ref 'Router' | |
Port: '443' | |
Protocol: HTTPS | |
RouterApiCertificate: | |
Type: AWS::CertificateManager::Certificate | |
DependsOn: RouterApiTargetGroup | |
Properties: | |
DomainName: !Join | |
- . | |
- - '*' | |
- !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- convox.site | |
DomainValidationOptions: | |
- DomainName: !Join | |
- . | |
- - '*' | |
- !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'Router.DNSName' | |
- convox.site | |
ValidationDomain: convox.site | |
RouterApiTargetGroup: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
DependsOn: Router | |
Properties: | |
HealthCheckIntervalSeconds: '5' | |
HealthCheckTimeoutSeconds: '3' | |
UnhealthyThresholdCount: '2' | |
HealthCheckPath: /check | |
Port: '5443' | |
Protocol: HTTPS | |
TargetGroupAttributes: | |
- Key: deregistration_delay.timeout_seconds | |
Value: '30' | |
- Key: stickiness.enabled | |
Value: 'true' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouterInternal: | |
Type: AWS::ElasticLoadBalancingV2::LoadBalancer | |
Condition: Internal | |
DependsOn: | |
- ApiRole | |
- LogsPolicy | |
Properties: | |
LoadBalancerAttributes: | |
- Key: access_logs.s3.enabled | |
Value: 'true' | |
- Key: access_logs.s3.bucket | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
- Key: access_logs.s3.prefix | |
Value: !Sub 'convox/logs/${AWS::StackName}/alb' | |
- Key: idle_timeout.timeout_seconds | |
Value: '3600' | |
Name: !Sub '${AWS::StackName}-rti' | |
Scheme: internal | |
Subnets: | |
- !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
SecurityGroups: | |
- !Ref 'RouterSecurity' | |
RouterInternalSecurity: | |
Type: AWS::EC2::SecurityGroup | |
Condition: Internal | |
DependsOn: ApiRole | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} internal router' | |
SecurityGroupIngress: | |
- CidrIp: !Ref 'VPCCIDR' | |
IpProtocol: tcp | |
FromPort: '0' | |
ToPort: '65535' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-router-internal' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
RouterInternalListener80: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Condition: Internal | |
Properties: | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterInternalApiTargetGroup' | |
LoadBalancerArn: !Ref 'RouterInternal' | |
Port: '80' | |
Protocol: HTTP | |
RouterInternalListener443: | |
Type: AWS::ElasticLoadBalancingV2::Listener | |
Condition: Internal | |
Properties: | |
Certificates: | |
- CertificateArn: !Ref 'RouterInternalCertificate' | |
DefaultActions: | |
- Type: forward | |
TargetGroupArn: !Ref 'RouterInternalApiTargetGroup' | |
LoadBalancerArn: !Ref 'RouterInternal' | |
Port: '443' | |
Protocol: HTTPS | |
RouterInternalCertificate: | |
Type: AWS::CertificateManager::Certificate | |
Condition: Internal | |
DependsOn: RouterInternalApiTargetGroup | |
Properties: | |
DomainName: !Join | |
- . | |
- - '*' | |
- !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
- convox.site | |
DomainValidationOptions: | |
- DomainName: !Join | |
- . | |
- - '*' | |
- !Select | |
- 0 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
- !Select | |
- 1 | |
- !Split | |
- . | |
- !GetAtt 'RouterInternal.DNSName' | |
- convox.site | |
ValidationDomain: convox.site | |
RouterInternalApiTargetGroup: | |
Type: AWS::ElasticLoadBalancingV2::TargetGroup | |
Condition: Internal | |
DependsOn: RouterInternal | |
Properties: | |
HealthCheckIntervalSeconds: '5' | |
HealthCheckTimeoutSeconds: '3' | |
UnhealthyThresholdCount: '2' | |
HealthCheckPath: /check | |
Port: '5443' | |
Protocol: HTTPS | |
TargetGroupAttributes: | |
- Key: deregistration_delay.timeout_seconds | |
Value: '30' | |
- Key: stickiness.enabled | |
Value: 'true' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Balancer: | |
Type: AWS::ElasticLoadBalancing::LoadBalancer | |
Properties: | |
ConnectionDrainingPolicy: | |
Enabled: true | |
Timeout: 60 | |
ConnectionSettings: | |
IdleTimeout: 3600 | |
CrossZone: true | |
HealthCheck: | |
HealthyThreshold: '2' | |
Interval: 5 | |
Target: !If | |
- PrivateApi | |
- HTTPS:3101/check | |
- HTTPS:3001/check | |
Timeout: 3 | |
UnhealthyThreshold: '2' | |
LBCookieStickinessPolicy: | |
- PolicyName: affinity | |
Listeners: !If | |
- PrivateApi | |
- - Protocol: TCP | |
LoadBalancerPort: '80' | |
InstanceProtocol: TCP | |
InstancePort: '3100' | |
- Protocol: TCP | |
LoadBalancerPort: '443' | |
InstanceProtocol: TCP | |
InstancePort: '3101' | |
- - Protocol: TCP | |
LoadBalancerPort: '80' | |
InstanceProtocol: TCP | |
InstancePort: '3000' | |
- Protocol: TCP | |
LoadBalancerPort: '443' | |
InstanceProtocol: TCP | |
InstancePort: '3001' | |
LoadBalancerName: !If | |
- PrivateApi | |
- !Join | |
- '-' | |
- - !Ref 'AWS::StackName' | |
- i | |
- !Ref 'AWS::StackName' | |
Scheme: !If | |
- PrivateApi | |
- internal | |
- !Ref 'AWS::NoValue' | |
SecurityGroups: | |
- !Ref 'BalancerSecurity' | |
Subnets: !If | |
- PrivateApi | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
Tags: | |
- Key: GatewayAttachment | |
Value: !If | |
- ExistingVpc | |
- existing | |
- !Ref 'GatewayAttachment' | |
- Key: Name | |
Value: !Ref 'AWS::StackName' | |
BalancerSecurity: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: !Sub '${AWS::StackName} balancer' | |
SecurityGroupIngress: | |
- CidrIp: !If | |
- PrivateApi | |
- !Ref 'VPCCIDR' | |
- '0.0.0.0/0' | |
IpProtocol: tcp | |
FromPort: '80' | |
ToPort: '80' | |
- CidrIp: !If | |
- PrivateApi | |
- !Ref 'VPCCIDR' | |
- '0.0.0.0/0' | |
IpProtocol: tcp | |
FromPort: '443' | |
ToPort: '443' | |
Tags: | |
- Key: Name | |
Value: !Sub '${AWS::StackName}-balancer' | |
VpcId: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
Cluster: | |
Type: AWS::ECS::Cluster | |
ServiceRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Version: '2012-10-17' | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole | |
Path: /convox/ | |
ApiRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- ecs-tasks.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
Version: '2012-10-17' | |
ManagedPolicyArns: | |
- arn:aws:iam::aws:policy/PowerUserAccess | |
Path: /convox/ | |
Policies: | |
- PolicyName: iam-convox | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Effect: Allow | |
Action: | |
- iam:* | |
Resource: | |
- arn:aws:iam::*:instance-profile/convox/* | |
- arn:aws:iam::*:policy/convox/* | |
- arn:aws:iam::*:role/convox/* | |
- arn:aws:iam::*:user/convox/* | |
- Effect: Allow | |
Action: | |
- iam:DeleteServerCertificate | |
- iam:GetServerCertificate | |
- iam:ListServerCertificates | |
- iam:PassRole | |
- iam:UploadServerCertificate | |
Resource: | |
- '*' | |
ApiMonitorService: | |
Type: AWS::ECS::Service | |
DependsOn: | |
- Instances | |
Properties: | |
Cluster: !Ref 'Cluster' | |
DeploymentConfiguration: | |
MinimumHealthyPercent: '100' | |
MaximumPercent: '200' | |
DesiredCount: '1' | |
PlacementConstraints: | |
- Type: memberOf | |
Expression: attribute:asg == primary | |
TaskDefinition: !Ref 'ApiMonitorTasks' | |
ApiWebService: | |
Type: AWS::ECS::Service | |
DependsOn: | |
- Instances | |
Properties: | |
Cluster: !Ref 'Cluster' | |
DeploymentConfiguration: | |
MinimumHealthyPercent: '50' | |
MaximumPercent: '200' | |
DesiredCount: !Ref 'ApiCount' | |
LoadBalancers: | |
- ContainerName: web | |
ContainerPort: '5443' | |
LoadBalancerName: !Ref 'Balancer' | |
Role: !GetAtt 'ServiceRole.Arn' | |
TaskDefinition: !Ref 'ApiWebTasks' | |
ApiBuildTasks: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
ContainerDefinitions: | |
- Cpu: !Ref 'BuildCpu' | |
DockerLabels: | |
convox.release: !Ref 'Version' | |
Environment: | |
- Name: AUTOSCALE | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
- Name: AWS_REGION | |
Value: !Ref 'AWS::Region' | |
- Name: BUILD_CLUSTER | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
- Name: CLIENT_ID | |
Value: !Ref 'ClientId' | |
- Name: CLOUDFORMATION_TOPIC | |
Value: !Ref 'CloudformationTopic' | |
- Name: CLUSTER | |
Value: !Ref 'Cluster' | |
- Name: CUSTOM_TOPIC | |
Value: !GetAtt 'CustomTopic.Arn' | |
- Name: DYNAMO_BUILDS | |
Value: !Ref 'DynamoBuilds' | |
- Name: DYNAMO_RELEASES | |
Value: !Ref 'DynamoReleases' | |
- Name: ENCRYPTION_KEY | |
Value: !Ref 'EncryptionKey' | |
- Name: HTTP_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: HTTPS_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: INTERNAL | |
Value: !Ref 'Internal' | |
- Name: LOG_BUCKET | |
Value: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
- Name: LOG_GROUP | |
Value: !Ref 'LogGroup' | |
- Name: NOTIFICATION_HOST | |
Value: !GetAtt 'Balancer.DNSName' | |
- Name: NOTIFICATION_TOPIC | |
Value: !Ref 'NotificationTopic' | |
- Name: ON_DEMAND_MIN_COUNT | |
Value: !Ref 'OnDemandMinCount' | |
- Name: PASSWORD | |
Value: !Ref 'Password' | |
- Name: PRIVATE | |
Value: !Ref 'Private' | |
- Name: PROVIDER | |
Value: aws | |
- Name: RACK | |
Value: !Ref 'AWS::StackName' | |
- Name: RELEASE | |
Value: !Ref 'Version' | |
- Name: ROLLBAR_TOKEN | |
Value: f67f25b8a9024d5690f997bd86bf14b0 | |
- Name: SECURITY_GROUP | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
- Name: SEGMENT_WRITE_KEY | |
Value: KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i | |
- Name: SETTINGS_BUCKET | |
Value: !Ref 'Settings' | |
- Name: SPOT_INSTANCES | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
- Name: STACK_ID | |
Value: !Ref 'AWS::StackId' | |
- Name: SUBNETS | |
Value: !Join | |
- ',' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
- Name: VPC | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
- Name: VPCCIDR | |
Value: !Ref 'VPCCIDR' | |
Image: !If | |
- BlankBuildImage | |
- !Sub 'convox/rack:${Version}' | |
- !Ref 'BuildImage' | |
Memory: !Ref 'BuildMemory' | |
MountPoints: | |
- SourceVolume: config | |
ContainerPath: /etc/sysconfig/docker | |
- SourceVolume: docker | |
ContainerPath: /var/run/docker.sock | |
Name: build | |
Family: !Sub '${AWS::StackName}-build' | |
TaskRoleArn: !GetAtt 'ApiRole.Arn' | |
Volumes: | |
- Name: config | |
Host: | |
SourcePath: /etc/sysconfig/docker | |
- Name: docker | |
Host: | |
SourcePath: /var/run/docker.sock | |
ApiMonitorTasks: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
ContainerDefinitions: | |
- Command: | |
- bin/monitor | |
Cpu: '64' | |
DockerLabels: | |
convox.release: !Ref 'Version' | |
Environment: | |
- Name: AUTOSCALE | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
- Name: AUTOSCALE_EXTRA | |
Value: !Ref 'AutoscaleExtra' | |
- Name: AWS_REGION | |
Value: !Ref 'AWS::Region' | |
- Name: BUILD_CLUSTER | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
- Name: CLIENT_ID | |
Value: !Ref 'ClientId' | |
- Name: CLOUDFORMATION_TOPIC | |
Value: !Ref 'CloudformationTopic' | |
- Name: CLUSTER | |
Value: !Ref 'Cluster' | |
- Name: CUSTOM_TOPIC | |
Value: !GetAtt 'CustomTopic.Arn' | |
- Name: DYNAMO_BUILDS | |
Value: !Ref 'DynamoBuilds' | |
- Name: DYNAMO_RELEASES | |
Value: !Ref 'DynamoReleases' | |
- Name: ENCRYPTION_KEY | |
Value: !Ref 'EncryptionKey' | |
- Name: HTTP_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: HTTPS_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: INTERNAL | |
Value: !Ref 'Internal' | |
- Name: LOG_GROUP | |
Value: !Ref 'LogGroup' | |
- Name: NOTIFICATION_HOST | |
Value: !GetAtt 'Balancer.DNSName' | |
- Name: NOTIFICATION_TOPIC | |
Value: !Ref 'NotificationTopic' | |
- Name: ON_DEMAND_MIN_COUNT | |
Value: !Ref 'OnDemandMinCount' | |
- Name: PASSWORD | |
Value: !Ref 'Password' | |
- Name: PRIVATE | |
Value: !Ref 'Private' | |
- Name: PROVIDER | |
Value: aws | |
- Name: RACK | |
Value: !Ref 'AWS::StackName' | |
- Name: RELEASE | |
Value: !Ref 'Version' | |
- Name: ROLLBAR_TOKEN | |
Value: f67f25b8a9024d5690f997bd86bf14b0 | |
- Name: SECURITY_GROUP | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
- Name: SEGMENT_WRITE_KEY | |
Value: KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i | |
- Name: SPOT_INSTANCES | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
- Name: SETTINGS_BUCKET | |
Value: !Ref 'Settings' | |
- Name: STACK_ID | |
Value: !Ref 'AWS::StackId' | |
- Name: SUBNETS | |
Value: !Join | |
- ',' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
- Name: VPC | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
- Name: VPCCIDR | |
Value: !Ref 'VPCCIDR' | |
Image: !Sub 'convox/rack:${Version}' | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-group: !Ref 'LogGroup' | |
awslogs-stream-prefix: service | |
Memory: '64' | |
MountPoints: | |
- SourceVolume: docker | |
ContainerPath: /var/run/docker.sock | |
Name: monitor | |
Family: !Sub '${AWS::StackName}-monitor' | |
TaskRoleArn: !GetAtt 'ApiRole.Arn' | |
Volumes: | |
- Name: docker | |
Host: | |
SourcePath: /var/run/docker.sock | |
ApiWebTasks: | |
Type: AWS::ECS::TaskDefinition | |
Properties: | |
ContainerDefinitions: | |
- Command: | |
- bin/web | |
Cpu: '128' | |
DockerLabels: | |
convox.release: !Ref 'Version' | |
Environment: | |
- Name: AUTOSCALE | |
Value: !If | |
- Autoscale | |
- 'true' | |
- 'false' | |
- Name: AWS_REGION | |
Value: !Ref 'AWS::Region' | |
- Name: BUILD_CLUSTER | |
Value: !If | |
- DedicatedBuilder | |
- !Ref 'BuildCluster' | |
- !Ref 'Cluster' | |
- Name: CLIENT_ID | |
Value: !Ref 'ClientId' | |
- Name: CLOUDFORMATION_TOPIC | |
Value: !Ref 'CloudformationTopic' | |
- Name: CLUSTER | |
Value: !Ref 'Cluster' | |
- Name: CUSTOM_TOPIC | |
Value: !GetAtt 'CustomTopic.Arn' | |
- Name: DYNAMO_BUILDS | |
Value: !Ref 'DynamoBuilds' | |
- Name: DYNAMO_RELEASES | |
Value: !Ref 'DynamoReleases' | |
- Name: ENCRYPTION_KEY | |
Value: !Ref 'EncryptionKey' | |
- Name: FARGATE | |
Value: !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- Fargate | |
- Name: HTTP_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: HTTPS_PROXY | |
Value: !Ref 'HttpProxy' | |
- Name: INTERNAL | |
Value: !Ref 'Internal' | |
- Name: LOG_GROUP | |
Value: !Ref 'LogGroup' | |
- Name: NOTIFICATION_HOST | |
Value: !GetAtt 'Balancer.DNSName' | |
- Name: NOTIFICATION_TOPIC | |
Value: !Ref 'NotificationTopic' | |
- Name: ON_DEMAND_MIN_COUNT | |
Value: !Ref 'OnDemandMinCount' | |
- Name: PASSWORD | |
Value: !Ref 'Password' | |
- Name: PRIVATE | |
Value: !Ref 'Private' | |
- Name: PROVIDER | |
Value: aws | |
- Name: RACK | |
Value: !Ref 'AWS::StackName' | |
- Name: RELEASE | |
Value: !Ref 'Version' | |
- Name: ROLLBAR_TOKEN | |
Value: f67f25b8a9024d5690f997bd86bf14b0 | |
- Name: SECURITY_GROUP | |
Value: !If | |
- BlankInstanceSecurityGroup | |
- !Ref 'InstancesSecurity' | |
- !Ref 'InstanceSecurityGroup' | |
- Name: SEGMENT_WRITE_KEY | |
Value: KLvwCXo6qcTmQHLpF69DEwGf9zh7lt9i | |
- Name: SPOT_INSTANCES | |
Value: !If | |
- SpotInstances | |
- 'true' | |
- 'false' | |
- Name: SETTINGS_BUCKET | |
Value: !Ref 'Settings' | |
- Name: STACK_ID | |
Value: !Ref 'AWS::StackId' | |
- Name: SUBNETS | |
Value: !Join | |
- ',' | |
- - !Ref 'Subnet0' | |
- !Ref 'Subnet1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'Subnet2' | |
- !Ref 'AWS::NoValue' | |
- Name: SUBNETS_PRIVATE | |
Value: !If | |
- Private | |
- !Join | |
- ',' | |
- - !Ref 'SubnetPrivate0' | |
- !Ref 'SubnetPrivate1' | |
- !If | |
- ThirdAvailabilityZone | |
- !Ref 'SubnetPrivate2' | |
- !Ref 'AWS::NoValue' | |
- '' | |
- Name: VPC | |
Value: !If | |
- BlankExistingVpc | |
- !Ref 'Vpc' | |
- !Ref 'ExistingVpc' | |
- Name: VPCCIDR | |
Value: !Ref 'VPCCIDR' | |
Image: !Sub 'convox/rack:${Version}' | |
LogConfiguration: | |
LogDriver: awslogs | |
Options: | |
awslogs-region: !Ref 'AWS::Region' | |
awslogs-group: !Ref 'LogGroup' | |
awslogs-stream-prefix: service | |
MemoryReservation: !Ref 'ApiMemory' | |
MountPoints: | |
- SourceVolume: docker | |
ContainerPath: /var/run/docker.sock | |
Name: web | |
PortMappings: !If | |
- PrivateApi | |
- - HostPort: '3100' | |
ContainerPort: '5442' | |
Protocol: tcp | |
- HostPort: '3101' | |
ContainerPort: '5443' | |
Protocol: tcp | |
- - HostPort: '3000' | |
ContainerPort: '5442' | |
Protocol: tcp | |
- HostPort: '3001' | |
ContainerPort: '5443' | |
Protocol: tcp | |
Family: !Sub '${AWS::StackName}-web' | |
TaskRoleArn: !GetAtt 'ApiRole.Arn' | |
Volumes: | |
- Name: docker | |
Host: | |
SourcePath: /var/run/docker.sock | |
DynamoBuilds: | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: !Join | |
- '-' | |
- - !Ref 'AWS::StackName' | |
- builds | |
AttributeDefinitions: | |
- AttributeName: id | |
AttributeType: S | |
- AttributeName: app | |
AttributeType: S | |
- AttributeName: created | |
AttributeType: S | |
KeySchema: | |
- AttributeName: id | |
KeyType: HASH | |
GlobalSecondaryIndexes: | |
- IndexName: app.created | |
KeySchema: | |
- AttributeName: app | |
KeyType: HASH | |
- AttributeName: created | |
KeyType: RANGE | |
Projection: | |
ProjectionType: ALL | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
DynamoReleases: | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: !Join | |
- '-' | |
- - !Ref 'AWS::StackName' | |
- releases | |
AttributeDefinitions: | |
- AttributeName: id | |
AttributeType: S | |
- AttributeName: app | |
AttributeType: S | |
- AttributeName: created | |
AttributeType: S | |
KeySchema: | |
- AttributeName: id | |
KeyType: HASH | |
GlobalSecondaryIndexes: | |
- IndexName: app.created | |
KeySchema: | |
- AttributeName: app | |
KeyType: HASH | |
- AttributeName: created | |
KeyType: RANGE | |
Projection: | |
ProjectionType: ALL | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
ProvisionedThroughput: | |
ReadCapacityUnits: '5' | |
WriteCapacityUnits: '5' | |
Logs: | |
Type: AWS::S3::Bucket | |
DeletionPolicy: Retain | |
Properties: | |
AccessControl: LogDeliveryWrite | |
Tags: | |
- Key: System | |
Value: convox | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' | |
LogsPolicy: | |
Type: AWS::S3::BucketPolicy | |
Properties: | |
Bucket: !Ref 'Logs' | |
PolicyDocument: | |
Version: '2012-10-17' | |
Statement: | |
- Sid: ELB log delivery service | |
Effect: Allow | |
Principal: | |
AWS: !FindInMap | |
- RegionConfig | |
- !Ref 'AWS::Region' | |
- ELBAccountId | |
Action: s3:PutObject | |
Resource: !Sub 'arn:aws:s3:::${Logs}/*' | |
Settings: | |
Type: AWS::S3::Bucket | |
DependsOn: LogsPolicy | |
DeletionPolicy: Retain | |
Properties: | |
AccessControl: Private | |
LoggingConfiguration: | |
DestinationBucketName: !If | |
- BlankLogBucket | |
- !Ref 'Logs' | |
- !Ref 'LogBucket' | |
LogFilePrefix: !Sub 'convox/logs/${AWS::StackName}/s3' | |
Tags: | |
- Key: System | |
Value: convox | |
- Key: Rack | |
Value: !Ref 'AWS::StackName' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment