Created
March 15, 2018 19:43
-
-
Save mwarkentin/4c5748b585d63a74080df98daac05313 to your computer and use it in GitHub Desktop.
Convox yml conversion
This file contains hidden or 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 hidden or 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