Permalink
1131 lines (1082 sloc) 34.4 KB
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Example ECS cluster for Empire",
"Metadata": {
"AWS::CloudFormation::Interface": {
"ParameterGroups": [
{
"Label": { "default": "Empire" },
"Parameters": ["LaunchEmpire", "EmpireVersion", "EventsBackend", "RunLogsBackend", "Scheduler"]
},
{
"Label": { "default": "GitHub Authentication" },
"Parameters": ["GitHubClientId", "GitHubClientSecret", "GitHubOrganization", "GitHubTeamId"]
},
{
"Label": { "default": "Docker" },
"Parameters": ["DockerUser", "DockerPass", "DockerEmail", "DockerRegistry"]
},
{
"Label": { "default": "Cluster" },
"Parameters": ["DesiredCapacity", "AmiId", "AvailabilityZones", "InstanceType", "KeyName"]
}
],
"ParameterLabels": {
"KeyName": { "default": "SSH key name" },
"LaunchEmpire": { "default": "Launch" },
"EmpireVersion": { "default": "Daemon version" },
"EventsBackend": { "default": "Send events to" },
"RunLogsBackend": { "default": "Send interactive run logs to" },
"Scheduler": { "default": "Backend to use to run applications" },
"GitHubClientId": { "default": "Client ID" },
"GitHubClientSecret": { "default": "Client Secret" },
"GitHubOrganization": { "default": "Organization" },
"GitHubTeamId": { "default": "Team ID" },
"DockerUser": { "default": "Username" },
"DockerPass": { "default": "Password" },
"DockerEmail": { "default": "Email" },
"DockerRegistry": { "default": "Registry" },
"DesiredCapacity": { "default": "Cluster size" },
"AmiId": { "default": "ECS optimized AMI id" },
"AvailabilityZones": { "default": "Availability zones" },
"InstanceType": { "default": "Instance type" }
}
}
},
"Parameters": {
"InstanceType": {
"Type": "String",
"Default": "t2.small",
"AllowedValues": [ "t2.small","t2.medium","m3.medium","m3.large","m3.xlarge","m3.2xlarge","c4.large","c4.xlarge","c4.2xlarge","c4.4xlarge","c4.8xlarge","c3.large","c3.xlarge","c3.2xlarge","c3.4xlarge","c3.8xlarge","r3.large","r3.xlarge","r3.2xlarge","r3.4xlarge","r3.8xlarge","i2.xlarge","i2.2xlarge","i2.4xlarge","i2.8xlarge" ],
"ConstraintDescription": "must be a valid EC2 instance type."
},
"EmpireVersion": {
"Type": "String",
"Default": "master",
"Description": "Docker tag to specify the version of Empire to run. This can be any git branch or sha."
},
"Scheduler": {
"Type": "String",
"Default": "cloudformation",
"Description": "The scheduling backend to use to run applications. The default is to run applications with ECS.",
"AllowedValues": ["cloudformation"]
},
"AmiId" : {
"Type": "AWS::EC2::Image::Id",
"Description": "The AMI id of the AMI to run the instances with. This defaults to the official ECS ami.",
"Default": "ami-275ffe31"
},
"KeyName": {
"Type": "String",
"Description": "The name of the key pair to use if you want to allow SSH access to hosts."
},
"EventsBackend": {
"Type": "String",
"AllowedValues": ["sns", "none"],
"Description": "The backend to use to publish Empire events to. Set this to SNS to create an SNS topic and publish events there.",
"Default": "sns"
},
"RunLogsBackend": {
"Type": "String",
"AllowedValues": ["cloudwatch", "stdout"],
"Description": "The backend used to store logs from interactive runs.",
"Default": "cloudwatch"
},
"DockerRegistry": {
"Type": "String",
"Description": "The URL of the Docker registry to pull private images from.",
"Default": "https://index.docker.io/v1/"
},
"DockerUser": {
"Type": "String",
"Description": "Username of a Docker registry user to pull images from private repositories.",
"Default": ""
},
"DockerPass": {
"Type": "String",
"Description": "Password of a Docker registry user to pull images from private repositories.",
"Default": "",
"NoEcho": true
},
"DockerEmail": {
"Type": "String",
"Description": "Email of a Docker registry user to pull images from private repositories.",
"Default": ""
},
"DesiredCapacity": {
"Type": "String",
"Description": "The number of EC2 instances to run in the ECS cluster.",
"Default": "3"
},
"AvailabilityZones": {
"Type": "List<AWS::EC2::AvailabilityZone::Name>",
"Description": "Comma delimited list of availability zones. MAX 2",
"Default": "us-east-1a,us-east-1b"
},
"LaunchEmpire": {
"Type": "String",
"Default": "true",
"AllowedValues": ["false", "true"],
"Description": "If true, then launch Empire & Postgres as ECS services. Note that this is NOT a production grade stack, this is only meant to serve as an easy way to try out Empire. If you want to take Empire into production, read the docs on Production Best Practices http://empire.readthedocs.io/en/latest/production_best_practices/."
},
"GitHubClientId": {
"Type": "String",
"Default": "",
"Description": "The oauth client id to use with the GitHub authentication backend."
},
"GitHubClientSecret": {
"Type": "String",
"Default": "",
"Description": "The oauth client secret to use with the GitHub authentication backend."
},
"GitHubOrganization": {
"Type": "String",
"Default": "",
"Description": "If set, this will ensure that all users are a member of this GitHub organization."
},
"GitHubTeamId": {
"Type": "String",
"Default": "",
"Description": "If set, this will ensure that all users are a member of this GitHub team."
}
},
"Conditions": {
"HasKeyName": {"Fn::Not": [{"Fn::Equals": ["", { "Ref": "KeyName" }]}]},
"DemoMode": {"Fn::Equals": [{"Ref": "LaunchEmpire"}, "true"]},
"DevMode": {"Fn::Not": [{"Condition": "DemoMode"}]},
"SNSEvents": {"Fn::Equals": [{"Ref": "EventsBackend"}, "sns"]},
"CloudWatchLogs": {"Fn::Equals": [{"Ref": "RunLogsBackend"}, "cloudwatch"]}
},
"Resources": {
"Vpc": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.0.0.0/16",
"EnableDnsSupport": "true",
"EnableDnsHostnames": "true"
}
},
"PubSubnetAz1" : {
"Type": "AWS::EC2::Subnet",
"DependsOn": "AttachGateway",
"Properties": {
"VpcId": { "Ref" : "Vpc" },
"CidrBlock": "10.0.0.0/24",
"AvailabilityZone": {
"Fn::Select": ["0", { "Ref": "AvailabilityZones" }]
}
}
},
"PubSubnetAz2" : {
"Type": "AWS::EC2::Subnet",
"DependsOn": "AttachGateway",
"Properties": {
"VpcId": { "Ref" : "Vpc" },
"CidrBlock": "10.0.1.0/24",
"AvailabilityZone": {
"Fn::Select": ["1", { "Ref": "AvailabilityZones" }]
}
}
},
"InternetGateway": {
"Type": "AWS::EC2::InternetGateway"
},
"AttachGateway": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": { "Ref": "Vpc" },
"InternetGatewayId": { "Ref": "InternetGateway" }
}
},
"RouteViaIgw" : {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": { "Ref": "Vpc" }
}
},
"PublicRouteViaIgw": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": { "Ref": "RouteViaIgw" },
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": { "Ref": "InternetGateway" }
}
},
"PubSubnet1RouteTableAssociation": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": { "Ref": "PubSubnetAz1" },
"RouteTableId": { "Ref": "RouteViaIgw" }
}
},
"PubSubnet2RouteTableAssociation": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": { "Ref": "PubSubnetAz2" },
"RouteTableId": { "Ref": "RouteViaIgw" }
}
},
"InternalDomain": {
"Type": "AWS::Route53::HostedZone",
"Properties": {
"HostedZoneConfig": {
"Comment": "Hosted zone for internal Empire services."
},
"Name": "empire.",
"VPCs": [
{
"VPCId": { "Ref": "Vpc" },
"VPCRegion": { "Ref": "AWS::Region" }
}
]
}
},
"DHCPOptions": {
"Type" : "AWS::EC2::DHCPOptions",
"Properties": {
"DomainName": "empire",
"DomainNameServers": [ "AmazonProvidedDNS" ]
}
},
"VPCDHCPOptionsAssociation": {
"Type" : "AWS::EC2::VPCDHCPOptionsAssociation",
"Properties": {
"DhcpOptionsId": { "Ref": "DHCPOptions" },
"VpcId": { "Ref": "Vpc" }
}
},
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Container Instance Allowed Ports",
"VpcId": { "Ref": "Vpc" },
"SecurityGroupIngress": [
{
"IpProtocol": "tcp", "FromPort": "1", "ToPort": "65535",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"InternalLoadBalancerSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Internal Load Balancer Allowed Ports",
"VpcId": { "Ref": "Vpc" },
"SecurityGroupIngress": [
{
"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"ExternalLoadBalancerSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "External Load Balancer Allowed Ports",
"VpcId": { "Ref": "Vpc" },
"SecurityGroupIngress": [
{
"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80",
"CidrIp": "0.0.0.0/0"
},
{
"IpProtocol": "tcp", "FromPort": "443", "ToPort": "443",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"LoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Condition": "DemoMode",
"DependsOn": "AttachGateway",
"Properties": {
"SecurityGroups": [
{ "Ref": "InstanceSecurityGroup" }
],
"Subnets": [
{ "Ref": "PubSubnetAz1" },
{ "Ref": "PubSubnetAz2" }
],
"CrossZone": "true",
"Listeners": [
{
"LoadBalancerPort": "80",
"InstancePort": "8080",
"Protocol": "TCP"
}
],
"HealthCheck": {
"Target": "HTTP:8080/health",
"HealthyThreshold": "10",
"UnhealthyThreshold": "2",
"Interval": "30",
"Timeout": "5"
},
"ConnectionSettings": {
"IdleTimeout": 3600
}
}
},
"InstanceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"Path": "/",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [ "ec2.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
}
]
}
}
},
"TemplateBucket": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Delete",
"Properties": {
"AccessControl": "Private"
}
},
"ECSAgentPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "ecs",
"Roles": [ { "Ref": "InstanceRole" } ],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Poll",
"ecs:RegisterContainerInstance",
"ecs:StartTelemetrySession",
"ecs:Submit*",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": ["*"]
}
]
}
}
},
"DockerPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "docker-cloudwatch-logs",
"Roles": [ { "Ref": "InstanceRole" } ],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
{ "Fn::Join": ["", ["arn:aws:logs:*:*:log-group:", { "Ref": "ApplicationLogGroup" }, ":log-stream:*"]] },
{ "Fn::Join": ["", ["arn:aws:logs:*:*:log-group:", { "Ref": "DaemonLogGroup" }, ":log-stream:*"]] },
{ "Fn::Join": ["", ["arn:aws:logs:*:*:log-group:", { "Ref": "PostgresLogGroup" }, ":log-stream:*"]] }
]
}
]
}
}
},
"EmpireRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"Path": "/",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [ "ecs-tasks.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
}
]
}
}
},
"EmpirePolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "empire",
"Roles": [ { "Ref": "EmpireRole" } ],
"Groups": [ { "Ref": "Group" } ],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"lambda:CreateFunction",
"lambda:DeleteFunction",
"lambda:UpdateFunctionCode",
"lambda:GetFunctionConfiguration",
"lambda:AddPermission",
"lambda:RemovePermission"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"events:PutRule",
"events:DeleteRule",
"events:DescribeRule",
"events:EnableRule",
"events:DisableRule",
"events:PutTargets",
"events:RemoveTargets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:ChangeMessageVisibility"
],
"Resource": { "Fn::GetAtt": ["CustomResourcesQueue", "Arn"] }
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": { "Ref": "CustomResourcesTopic" }
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": { "Ref": "EventsTopic" }
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:PutObjectVersionAcl",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetObjectAcl",
"s3:GetObjectVersionAcl"
],
"Resource": { "Fn::Join": ["", ["arn:aws:s3:::", { "Ref": "TemplateBucket" }, "/*"]] }
},
{
"Effect": "Allow",
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack",
"cloudformation:ListStackResources",
"cloudformation:DescribeStackResource",
"cloudformation:DescribeStacks",
"cloudformation:ValidateTemplate"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"ecs:CreateService",
"ecs:DeleteService",
"ecs:DeregisterTaskDefinition",
"ecs:Describe*",
"ecs:List*",
"ecs:RegisterTaskDefinition",
"ecs:RunTask",
"ecs:StartTask",
"ecs:StopTask",
"ecs:SubmitTaskStateChange",
"ecs:UpdateService"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:*"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups"
],
"Resource": ["*"]
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZonesByName",
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets",
"route53:ListHostedZones",
"route53:GetHostedZone"
],
"Resource": { "Fn::Join": ["", ["arn:aws:route53:::hostedzone/", { "Ref": "InternalDomain" }]] }
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"route53:GetChange*"
],
"Resource": "arn:aws:route53:::change/*"
}
]
}
}
},
"ServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"Path": "/",
"AssumeRolePolicyDocument": {
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ecs.amazonaws.com",
"events.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Action": [ "sts:AssumeRole" ]
}
]
}
}
},
"ServiceRolePolicies": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "ecsServiceRole",
"Roles": [ { "Ref": "ServiceRole" } ],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"elasticloadbalancing:*",
"ecs:*",
"iam:ListInstanceProfiles",
"iam:ListRoles",
"iam:PassRole",
"route53:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecs:RunTask"
],
"Resource": "*",
"Condition": {
"ArnEquals": {
"ecs:cluster": { "Fn::Join": ["", ["arn:aws:ecs:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":cluster/", { "Ref": "Cluster" }]] }
}
}
}
]
}
}
},
"InstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ { "Ref": "InstanceRole" } ]
}
},
"LaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"DependsOn": "Cluster",
"Properties": {
"ImageId": { "Ref": "AmiId" },
"InstanceType": { "Ref": "InstanceType" },
"AssociatePublicIpAddress": true,
"IamInstanceProfile": { "Ref": "InstanceProfile" },
"KeyName": { "Fn::If": ["HasKeyName", { "Ref": "KeyName" }, { "Ref": "AWS::NoValue" }] },
"SecurityGroups": [
{ "Ref": "InstanceSecurityGroup" }
],
"UserData": {
"Fn::Base64": {
"Fn::Join": [
"",
[
"#!/bin/bash\n",
"echo ECS_CLUSTER=", { "Ref": "Cluster" }, " >> /etc/ecs/ecs.config\n",
"echo ECS_ENGINE_AUTH_TYPE=dockercfg >> /etc/ecs/ecs.config\n",
"echo ECS_ENGINE_AUTH_DATA=\"{\\\"", { "Ref": "DockerRegistry" }, "\\\":{\\\"auth\\\":\\\"", { "Fn::Base64": { "Fn::Join": [ ":", [ { "Ref": "DockerUser" }, { "Ref": "DockerPass" } ] ] } }, "\\\",\\\"email\\\":\\\"", { "Ref": "DockerEmail" }, "\\\"}}\" >> /etc/ecs/ecs.config\n",
"echo \"{\\\"", { "Ref": "DockerRegistry" }, "\\\":{\\\"auth\\\":\\\"", { "Fn::Base64": { "Fn::Join": [ ":", [ { "Ref": "DockerUser" }, { "Ref": "DockerPass" } ] ] } }, "\\\",\\\"email\\\":\\\"", { "Ref": "DockerEmail" }, "\\\"}}\" >> /home/ec2-user/.dockercfg\n"
]
]
}
}
}
},
"AutoScalingGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"UpdatePolicy": {
"AutoScalingRollingUpdate": {
"MinInstancesInService": "1",
"MaxBatchSize": "2",
"WaitOnResourceSignals": "true",
"PauseTime": "PT2M"
}
},
"Properties": {
"AvailabilityZones": { "Ref": "AvailabilityZones" },
"VPCZoneIdentifier": [{ "Fn::Join" : [",", [ { "Ref" : "PubSubnetAz1" }, { "Ref" : "PubSubnetAz2" } ] ] }],
"LaunchConfigurationName": { "Ref": "LaunchConfiguration" },
"MinSize": "1",
"MaxSize": { "Ref": "DesiredCapacity" },
"DesiredCapacity": { "Ref": "DesiredCapacity" },
"Tags": [
{
"Key": "Name",
"Value": "Empire minion",
"PropagateAtLaunch": "true"
}
]
}
},
"Group": {
"Type": "AWS::IAM::Group"
},
"User": {
"Type": "AWS::IAM::User",
"Properties": {
"Groups": [ { "Ref": "Group" } ]
}
},
"AccessKey": {
"Type": "AWS::IAM::AccessKey",
"Properties": {
"Status": "Active",
"UserName": { "Ref": "User" }
}
},
"Cluster": {
"Type": "AWS::ECS::Cluster"
},
"DBSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Condition": "DemoMode",
"Properties": {
"GroupDescription": "Security group for RDS DB Instance.",
"VpcId": { "Ref" : "Vpc" },
"SecurityGroupIngress": [
{
"IpProtocol": "tcp", "FromPort": "5432", "ToPort": "5432",
"SourceSecurityGroupId": { "Ref": "InstanceSecurityGroup" }
}
]
}
},
"DBSubnetGroup": {
"Type" : "AWS::RDS::DBSubnetGroup",
"Condition": "DemoMode",
"Properties" : {
"DBSubnetGroupDescription": "Subnet group for Empire db",
"SubnetIds" : [{ "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" }]
}
},
"DB": {
"Type": "AWS::RDS::DBInstance",
"Condition": "DemoMode",
"Properties": {
"DBName": "empire",
"Engine": "postgres",
"EngineVersion": "9.5.2",
"MasterUsername": "empire",
"MasterUserPassword": "epoo9mohNg",
"DBInstanceClass": "db.t2.micro",
"DBSubnetGroupName": { "Ref": "DBSubnetGroup" },
"AllocatedStorage": 5,
"VPCSecurityGroups": [ { "Fn::GetAtt": [ "DBSecurityGroup", "GroupId" ] } ]
},
"DeletionPolicy": "Delete"
},
"TaskDefinition": {
"Type": "AWS::ECS::TaskDefinition",
"Condition": "DemoMode",
"Properties": {
"TaskRoleArn": { "Fn::GetAtt": ["EmpireRole", "Arn"] },
"ContainerDefinitions": [
{
"Name": "empire",
"Image": { "Fn::Join": [":", ["remind101/empire", { "Ref": "EmpireVersion" }]] },
"Cpu": 256,
"Memory": 256,
"EntryPoint": [],
"LogConfiguration": {
"LogDriver": "awslogs",
"Options": {
"awslogs-region": { "Ref": "AWS::Region" },
"awslogs-group": { "Ref": "DaemonLogGroup" }
}
},
"Environment": [
{
"Name": "AWS_REGION",
"Value": { "Ref": "AWS::Region" }
},
{
"Name": "EMPIRE_SCHEDULER",
"Value": { "Ref": "Scheduler" }
},
{
"Name": "EMPIRE_ENVIRONMENT",
"Value": "demo"
},
{
"Name": "EMPIRE_DATABASE_URL",
"Value": { "Fn::Join": ["", ["postgres://empire:epoo9mohNg@", { "Fn::GetAtt": ["DB", "Endpoint.Address"] }, ":", { "Fn::GetAtt": ["DB", "Endpoint.Port"] } , "/empire"]] }
},
{
"Name": "EMPIRE_S3_TEMPLATE_BUCKET",
"Value": { "Ref": "TemplateBucket" }
},
{
"Name": "EMPIRE_ECS_CLUSTER",
"Value": { "Ref": "Cluster" }
},
{
"Name": "EMPIRE_ELB_VPC_ID",
"Value": { "Ref": "Vpc" }
},
{
"Name": "EMPIRE_ELB_SG_PRIVATE",
"Value": { "Ref": "InternalLoadBalancerSecurityGroup" }
},
{
"Name": "EMPIRE_ELB_SG_PUBLIC",
"Value": { "Ref": "ExternalLoadBalancerSecurityGroup" }
},
{
"Name": "EMPIRE_ROUTE53_INTERNAL_ZONE_ID",
"Value": { "Ref": "InternalDomain" }
},
{
"Name": "EMPIRE_EC2_SUBNETS_PRIVATE",
"Value": { "Fn::Join": [ ",", [{ "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" }] ] }
},
{
"Name": "EMPIRE_ECS_SERVICE_ROLE",
"Value": { "Ref": "ServiceRole" }
},
{
"Name": "EMPIRE_EC2_SUBNETS_PUBLIC",
"Value": { "Fn::Join": [ ",", [{ "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" }] ] }
},
{
"Name": "EMPIRE_EVENTS_BACKEND",
"Value": "sns"
},
{
"Name": "EMPIRE_SNS_TOPIC",
"Value": { "Ref": "EventsTopic" }
},
{
"Name": "EMPIRE_RUN_LOGS_BACKEND",
"Value": { "Ref": "RunLogsBackend" }
},
{
"Name": "EMPIRE_CLOUDWATCH_LOG_GROUP",
"Value": { "Ref": "ApplicationLogGroup" }
},
{
"Name": "EMPIRE_ECS_LOG_DRIVER",
"Value": "awslogs"
},
{
"Name": "EMPIRE_ECS_LOG_OPT",
"Value": { "Fn::Join": [",", [
{ "Fn::Join": ["=", ["awslogs-region", { "Ref": "AWS::Region" }]] },
{ "Fn::Join": ["=", ["awslogs-group", { "Ref": "ApplicationLogGroup" }]] }
]] }
},
{
"Name": "EMPIRE_CUSTOM_RESOURCES_TOPIC",
"Value": { "Ref": "CustomResourcesTopic" }
},
{
"Name": "EMPIRE_CUSTOM_RESOURCES_QUEUE",
"Value": { "Ref": "CustomResourcesQueue" }
},
{
"Name": "EMPIRE_GITHUB_CLIENT_ID",
"Value": { "Ref": "GitHubClientId" }
},
{
"Name": "EMPIRE_GITHUB_CLIENT_SECRET",
"Value": { "Ref": "GitHubClientSecret" }
},
{
"Name": "EMPIRE_GITHUB_ORGANIZATION",
"Value": { "Ref": "GitHubOrganization" }
},
{
"Name": "EMPIRE_GITHUB_TEAM_ID",
"Value": { "Ref": "GitHubTeamId" }
},
{
"Name": "EMPIRE_X_SHOW_ATTACHED",
"Value": "true"
},
{
"Name": "EMPIRE_SERVER_REAL_IP",
"Value": "X-Forwarded-For"
}
],
"Command": ["server", "-automigrate=true"],
"PortMappings": [
{
"HostPort": 8080,
"ContainerPort": 8080
}
],
"VolumesFrom": [],
"MountPoints": [
{
"SourceVolume": "dockerSocket",
"ContainerPath": "/var/run/docker.sock",
"ReadOnly": false
},
{
"SourceVolume": "dockerCfg",
"ContainerPath": "/root/.dockercfg",
"ReadOnly": false
}
],
"Essential": true
}
],
"Volumes": [
{
"Name": "dockerSocket",
"Host": {
"SourcePath": "/var/run/docker.sock"
}
},
{
"Name": "dockerCfg",
"Host": {
"SourcePath": "/home/ec2-user/.dockercfg"
}
}
]
}
},
"Service": {
"Type" : "AWS::ECS::Service",
"Condition": "DemoMode",
"DependsOn": ["Cluster","ServiceRole","ServiceRolePolicies"],
"Properties" : {
"Cluster" : { "Ref": "Cluster" },
"DesiredCount" : 1,
"LoadBalancers" : [
{
"ContainerName": "empire",
"ContainerPort": 8080,
"LoadBalancerName": { "Ref": "LoadBalancer" }
}
],
"Role" : { "Ref": "ServiceRole" },
"TaskDefinition" : { "Ref": "TaskDefinition" }
}
},
"EventsTopic": {
"Type": "AWS::SNS::Topic",
"Condition": "SNSEvents",
"Properties": {
"DisplayName": "Empire Events"
}
},
"ApplicationLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Condition": "CloudWatchLogs",
"Properties": {
"RetentionInDays": 7
}
},
"PostgresLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Condition": "CloudWatchLogs",
"Properties": {
"RetentionInDays": 7
}
},
"DaemonLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Condition": "CloudWatchLogs",
"Properties": {
"RetentionInDays": 7
}
},
"CustomResourcesTopic": {
"Type": "AWS::SNS::Topic",
"Properties": {
"DisplayName": "Empire Custom Resources",
"Subscription": [
{
"Protocol": "sqs",
"Endpoint": { "Fn::GetAtt": ["CustomResourcesQueue", "Arn"] }
}
]
}
},
"CustomResourcesQueue": {
"Type": "AWS::SQS::Queue"
},
"CustomResourcesQueuePolicy": {
"Type": "AWS::SQS::QueuePolicy",
"Properties": {
"Queues": [{ "Ref": "CustomResourcesQueue" }],
"PolicyDocument": {
"Version": "2012-10-17",
"Id": "CustomResourcesQueuePolicy",
"Statement": [
{
"Sid": "AllowCustomResourcesTopicToSendMessages",
"Effect": "Allow",
"Principal": "*",
"Action": ["sqs:SendMessage"],
"Resource": "*",
"Condition": {
"ArnEquals": {
"aws:SourceArn": { "Ref": "CustomResourcesTopic" }
}
}
}
]
}
}
}
},
"Outputs": {
"Subnets": {
"Description": "The subnets created",
"Value": { "Fn::Join": [ ",", [{ "Ref": "PubSubnetAz1" }, { "Ref": "PubSubnetAz2" }] ] }
},
"ELBName": {
"Description": "The name of the ELB for the Empire controller",
"Value": { "Ref": "LoadBalancer" },
"Condition": "DemoMode"
},
"Cluster": {
"Description": "Name of the ECS Cluster",
"Value": { "Ref": "Cluster" }
},
"ServiceRole": {
"Description": "Role to assume when creating an ECS service with an ELB attached",
"Value": { "Ref": "ServiceRole" }
},
"AccessKeyId": {
"Description": "Access key that can be used for a development instance of Empire",
"Value": { "Ref": "AccessKey" }
},
"SecretAccessKey": {
"Description": "Access key that can be used for a development instance of Empire",
"Value": { "Fn::GetAtt": [ "AccessKey", "SecretAccessKey" ] }
},
"VPC": {
"Description": "The id of the VPC",
"Value": { "Ref": "Vpc" }
},
"ELBDNSName": {
"Description": "The DNS name of the ELB for the Empire controller",
"Value": { "Fn::GetAtt": [ "LoadBalancer", "DNSName" ] },
"Condition": "DemoMode"
},
"InternalELBSG": {
"Description": "The Internal ELB Security Group",
"Value": { "Ref": "InternalLoadBalancerSecurityGroup" }
},
"ExternalELBSG": {
"Description": "The External ELB Security Group",
"Value": { "Ref": "ExternalLoadBalancerSecurityGroup" }
},
"InternalZoneID": {
"Description": "The zone ID for the internal hosted zone.",
"Value": { "Ref": "InternalDomain" }
},
"TemplateBucket": {
"Description": "The s3 bucket where stack templates will be stored",
"Value": { "Ref": "TemplateBucket" }
},
"CustomResourcesTopic": {
"Description": "The ARN of the SNS topic to use as the ServiceToken for custom CloudFormation resources.",
"Value": { "Ref": "CustomResourcesTopic" }
},
"CustomResourcesQueue": {
"Description": "The queue that Empire will listen on to provision custom CloudFormation resources.",
"Value": { "Ref": "CustomResourcesQueue" }
}
}
}