From b3ee2880d98eb73f458586af96fbadb876df5b87 Mon Sep 17 00:00:00 2001 From: Cedric Ziel Date: Mon, 11 May 2020 13:42:08 +0200 Subject: [PATCH] Add cluster descriptor * add template for instana-agent --- aws-ecs-ec2/cluster.yaml | 571 ++++++++++++++++++++++++++++++++ aws-ecs-ec2/services-agent.yaml | 120 +++++++ 2 files changed, 691 insertions(+) create mode 100644 aws-ecs-ec2/cluster.yaml create mode 100644 aws-ecs-ec2/services-agent.yaml diff --git a/aws-ecs-ec2/cluster.yaml b/aws-ecs-ec2/cluster.yaml new file mode 100644 index 0000000..9b1f59f --- /dev/null +++ b/aws-ecs-ec2/cluster.yaml @@ -0,0 +1,571 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: A stack for deploying containerized applications onto a cluster of EC2 + hosts using Elastic Container Service. This stack runs containers on + hosts that are in a private VPC subnet. Outbound network traffic from the + hosts must go out through a NAT gateway. There are two load balancers, one + inside the public subnet, which can be used to send traffic to the + containers in the private subnet, and one in the private subnet, which can + be used for private internal traffic between internal services. +Parameters: + DesiredCapacity: + Type: Number + Default: '3' + Description: Number of EC2 instances to launch in your ECS cluster. + MaxSize: + Type: Number + Default: '6' + Description: Maximum number of EC2 instances that can be launched in your ECS cluster. + ECSAMI: + Description: AMI ID + Type: AWS::SSM::Parameter::Value + Default: /aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id + InstanceType: + Description: EC2 instance type + Type: String + Default: c4.xlarge + AllowedValues: [t2.micro, t2.small, t2.medium, t2.large, m3.medium, m3.large, + m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, + 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: Please choose a valid instance type. +Mappings: + # Hard values for the subnet masks. These masks define + # the range of internal IP addresses that can be assigned. + # The VPC can have all IP's from 10.0.0.0 to 10.0.255.255 + # There are four subnets which cover the ranges: + # + # 10.0.0.0 - 10.0.0.255 + # 10.0.1.0 - 10.0.1.255 + # 10.0.2.0 - 10.0.2.255 + # 10.0.3.0 - 10.0.3.255 + # + # If you need more IP addresses (perhaps you have so many + # instances that you run out) then you can customize these + # ranges to add more + SubnetConfig: + VPC: + CIDR: '10.0.0.0/16' + PublicOne: + CIDR: '10.0.0.0/24' + PublicTwo: + CIDR: '10.0.1.0/24' + PrivateOne: + CIDR: '10.0.2.0/24' + PrivateTwo: + CIDR: '10.0.3.0/24' +Resources: + # VPC in which containers will be networked. + # It has two public subnets, and two private subnets. + # We distribute the subnets across the first two available subnets + # for the region, for high availability. + VPC: + Type: AWS::EC2::VPC + Properties: + EnableDnsSupport: true + EnableDnsHostnames: true + CidrBlock: !FindInMap ['SubnetConfig', 'VPC', 'CIDR'] + + # Two public subnets, where containers can have public IP addresses + PublicSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicOne', 'CIDR'] + MapPublicIpOnLaunch: true + PublicSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PublicTwo', 'CIDR'] + MapPublicIpOnLaunch: true + + # Two private subnets where containers will only have private + # IP addresses, and will only be reachable by other members of the + # VPC + PrivateSubnetOne: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 0 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateOne', 'CIDR'] + PrivateSubnetTwo: + Type: AWS::EC2::Subnet + Properties: + AvailabilityZone: + Fn::Select: + - 1 + - Fn::GetAZs: {Ref: 'AWS::Region'} + VpcId: !Ref 'VPC' + CidrBlock: !FindInMap ['SubnetConfig', 'PrivateTwo', 'CIDR'] + + # Setup networking resources for the public subnets. Containers + # in the public subnets have public IP addresses and the routing table + # sends network traffic via the internet gateway. + InternetGateway: + Type: AWS::EC2::InternetGateway + GatewayAttachement: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref 'VPC' + InternetGatewayId: !Ref 'InternetGateway' + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachement + Properties: + RouteTableId: !Ref 'PublicRouteTable' + DestinationCidrBlock: '0.0.0.0/0' + GatewayId: !Ref 'InternetGateway' + PublicSubnetOneRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetOne + RouteTableId: !Ref PublicRouteTable + PublicSubnetTwoRouteTableAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnetTwo + RouteTableId: !Ref PublicRouteTable + + # Setup networking resources for the private subnets. Containers + # in these subnets have only private IP addresses, and must use a NAT + # gateway to talk to the internet. We launch two NAT gateways, one for + # each private subnet. + NatGatewayOneAttachment: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + NatGatewayTwoAttachment: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachement + Properties: + Domain: vpc + NatGatewayOne: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatGatewayOneAttachment.AllocationId + SubnetId: !Ref PublicSubnetOne + NatGatewayTwo: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatGatewayTwoAttachment.AllocationId + SubnetId: !Ref PublicSubnetTwo + PrivateRouteTableOne: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + PrivateRouteOne: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTableOne + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGatewayOne + PrivateRouteTableOneAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTableOne + SubnetId: !Ref PrivateSubnetOne + PrivateRouteTableTwo: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref 'VPC' + PrivateRouteTwo: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTableTwo + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGatewayTwo + PrivateRouteTableTwoAssociation: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + RouteTableId: !Ref PrivateRouteTableTwo + SubnetId: !Ref PrivateSubnetTwo + + # OPTIONAL: VPC Endpoint for DynamoDB + # If a container needs to access DynamoDB this allows a container in the private subnet + # to talk to DynamoDB directly without needing to go via the NAT gateway. This reduces + # the amount of bandwidth through the gateway, meaning that the gateway is free to serve + # your other traffic. + DynamoDBEndpoint: + Type: AWS::EC2::VPCEndpoint + Properties: + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: "*" + Principal: "*" + Resource: "*" + RouteTableIds: + - !Ref 'PrivateRouteTableOne' + - !Ref 'PrivateRouteTableTwo' + ServiceName: !Join [ "", [ "com.amazonaws.", { "Ref": "AWS::Region" }, ".dynamodb" ] ] + VpcId: !Ref 'VPC' + + # ECS Resources + ECSCluster: + Type: AWS::ECS::Cluster + + # A security group for the EC2 hosts that will run the containers. + # Two rules, allowing network traffic from a public facing load + # balancer and from other hosts in the security group. + # + # Remove any of the following ingress rules that are not needed. + # If you want to make direct requests to a container using its + # public IP address you'll need to add a security group rule + # to allow traffic from all IP addresses. + EcsHostSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Access to the ECS hosts that run containers + VpcId: !Ref 'VPC' + EcsSecurityGroupIngressFromPublicALB: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Ingress from the public ALB + GroupId: !Ref 'EcsHostSecurityGroup' + IpProtocol: -1 + SourceSecurityGroupId: !Ref 'PublicLoadBalancerSG' + EcsSecurityGroupIngressFromPrivateALB: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Ingress from the private ALB + GroupId: !Ref 'EcsHostSecurityGroup' + IpProtocol: -1 + SourceSecurityGroupId: !Ref 'PrivateLoadBalancerSG' + EcsSecurityGroupIngressFromSelf: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Ingress from other containers in the same security group + GroupId: !Ref 'EcsHostSecurityGroup' + IpProtocol: -1 + SourceSecurityGroupId: !Ref 'EcsHostSecurityGroup' + + # Autoscaling group. This launches the actual EC2 instances that will register + # themselves as members of the cluster, and run the docker containers. + ECSAutoScalingGroup: + Type: AWS::AutoScaling::AutoScalingGroup + Properties: + VPCZoneIdentifier: + - !Ref PrivateSubnetOne + - !Ref PrivateSubnetTwo + LaunchConfigurationName: !Ref 'ContainerInstances' + MinSize: '1' + MaxSize: !Ref 'MaxSize' + DesiredCapacity: !Ref 'DesiredCapacity' + CreationPolicy: + ResourceSignal: + Timeout: PT15M + UpdatePolicy: + AutoScalingReplacingUpdate: + WillReplace: 'true' + ContainerInstances: + Type: AWS::AutoScaling::LaunchConfiguration + Properties: + ImageId: !Ref 'ECSAMI' + SecurityGroups: [!Ref 'EcsHostSecurityGroup'] + InstanceType: !Ref 'InstanceType' + IamInstanceProfile: !Ref 'EC2InstanceProfile' + UserData: + Fn::Base64: !Sub | + #!/bin/bash -xe + echo ECS_CLUSTER=${ECSCluster} >> /etc/ecs/ecs.config + yum install -y aws-cfn-bootstrap curl + /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region} + AutoscalingRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: [application-autoscaling.amazonaws.com] + Action: ['sts:AssumeRole'] + Path: / + Policies: + - PolicyName: service-autoscaling + PolicyDocument: + Statement: + - Effect: Allow + Action: + - 'application-autoscaling:*' + - 'cloudwatch:DescribeAlarms' + - 'cloudwatch:PutMetricAlarm' + - 'ecs:DescribeServices' + - 'ecs:UpdateService' + Resource: '*' + EC2InstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + Path: / + Roles: [!Ref 'EC2Role'] + + # Role for the EC2 hosts. This allows the ECS agent on the EC2 hosts + # to communciate with the ECS control plane, as well as download the docker + # images from ECR to run on your host. + EC2Role: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: [ec2.amazonaws.com] + Action: ['sts:AssumeRole'] + Path: / + Policies: + - PolicyName: ecs-service + PolicyDocument: + Statement: + - Effect: Allow + Action: + - 'ecs:CreateCluster' + - 'ecs:DeregisterContainerInstance' + - 'ecs:DiscoverPollEndpoint' + - 'ecs:Poll' + - 'ecs:RegisterContainerInstance' + - 'ecs:StartTelemetrySession' + - 'ecs:Submit*' + - 'logs:CreateLogStream' + - 'logs:PutLogEvents' + - 'ecr:GetAuthorizationToken' + - 'ecr:BatchGetImage' + - 'ecr:GetDownloadUrlForLayer' + Resource: '*' + + # Load balancers for getting traffic to containers. + # This sample template creates two load balancers: + # + # - One public load balancer, hosted in public subnets that is accessible + # to the public, and is intended to route traffic to one or more public + # facing services. + # - One private load balancer, hosted in private subnets, that only + # accepts traffic from other containers in the cluster, and is + # intended for private services that should not be accessed directly + # by the public. + + # A public facing load balancer, this is used for accepting traffic from the public + # internet and directing it to public facing microservices + PublicLoadBalancerSG: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Access to the public facing load balancer + VpcId: !Ref 'VPC' + SecurityGroupIngress: + # Allow access to ALB from anywhere on the internet + - CidrIp: 0.0.0.0/0 + IpProtocol: -1 + PublicLoadBalancer: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + Scheme: internet-facing + LoadBalancerAttributes: + - Key: idle_timeout.timeout_seconds + Value: '30' + Subnets: + # The load balancer is placed into the public subnets, so that traffic + # from the internet can reach the load balancer directly via the internet gateway + - !Ref PublicSubnetOne + - !Ref PublicSubnetTwo + SecurityGroups: [!Ref 'PublicLoadBalancerSG'] + # A dummy target group is used to setup the ALB to just drop traffic + # initially, before any real service target groups have been added. + DummyTargetGroupPublic: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckIntervalSeconds: 6 + HealthCheckPath: / + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 5 + HealthyThresholdCount: 2 + Name: !Join ['-', [!Ref 'AWS::StackName', 'drop-1']] + Port: 80 + Protocol: HTTP + UnhealthyThresholdCount: 2 + VpcId: !Ref 'VPC' + PublicLoadBalancerListener: + Type: AWS::ElasticLoadBalancingV2::Listener + DependsOn: + - PublicLoadBalancer + Properties: + DefaultActions: + - TargetGroupArn: !Ref 'DummyTargetGroupPublic' + Type: 'forward' + LoadBalancerArn: !Ref 'PublicLoadBalancer' + Port: 80 + Protocol: HTTP + + # An internal load balancer, this would be used for a service that is not + # directly accessible to the public, but instead should only receive traffic + # from your other services. + PrivateLoadBalancerSG: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Access to the internal load balancer + VpcId: !Ref 'VPC' + PrivateLoadBalancerIngressFromECS: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Only accept traffic from a container in the container host security group + GroupId: !Ref 'PrivateLoadBalancerSG' + IpProtocol: -1 + SourceSecurityGroupId: !Ref 'EcsHostSecurityGroup' + PrivateLoadBalancer: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + Scheme: internal + LoadBalancerAttributes: + - Key: idle_timeout.timeout_seconds + Value: '30' + Subnets: + # This load balancer is put into the private subnet, so that there is no + # route for the public to even be able to access the private load balancer. + - !Ref PrivateSubnetOne + - !Ref PrivateSubnetTwo + SecurityGroups: [!Ref 'PrivateLoadBalancerSG'] + # This dummy target group is used to setup the ALB to just drop traffic + # initially, before any real service target groups have been added. + DummyTargetGroupPrivate: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckIntervalSeconds: 6 + HealthCheckPath: / + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 5 + HealthyThresholdCount: 2 + Name: !Join ['-', [!Ref 'AWS::StackName', 'drop-2']] + Port: 80 + Protocol: HTTP + UnhealthyThresholdCount: 2 + VpcId: !Ref 'VPC' + PrivateLoadBalancerListener: + Type: AWS::ElasticLoadBalancingV2::Listener + DependsOn: + - PrivateLoadBalancer + Properties: + DefaultActions: + - TargetGroupArn: !Ref 'DummyTargetGroupPrivate' + Type: 'forward' + LoadBalancerArn: !Ref 'PrivateLoadBalancer' + Port: 80 + Protocol: HTTP + + # This is an IAM role which authorizes ECS to manage resources on your + # account on your behalf, such as updating your load balancer with the + # details of where your containers are, so that traffic can reach your + # containers. + ECSRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Statement: + - Effect: Allow + Principal: + Service: [ecs.amazonaws.com] + Action: ['sts:AssumeRole'] + Path: / + Policies: + - PolicyName: ecs-service + PolicyDocument: + Statement: + - Effect: Allow + Action: + # Rules which allow ECS to attach network interfaces to instances + # on your behalf in order for awsvpc networking mode to work right + - 'ec2:AttachNetworkInterface' + - 'ec2:CreateNetworkInterface' + - 'ec2:CreateNetworkInterfacePermission' + - 'ec2:DeleteNetworkInterface' + - 'ec2:DeleteNetworkInterfacePermission' + - 'ec2:Describe*' + - 'ec2:DetachNetworkInterface' + + # Rules which allow ECS to update load balancers on your behalf + # with the information sabout how to send traffic to your containers + - 'elasticloadbalancing:DeregisterInstancesFromLoadBalancer' + - 'elasticloadbalancing:DeregisterTargets' + - 'elasticloadbalancing:Describe*' + - 'elasticloadbalancing:RegisterInstancesWithLoadBalancer' + - 'elasticloadbalancing:RegisterTargets' + Resource: '*' + +# These are the values output by the CloudFormation template. Be careful +# about changing any of them, because of them are exported with specific +# names so that the other task related CF templates can use them. +Outputs: + ClusterName: + Description: The name of the ECS cluster + Value: !Ref 'ECSCluster' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ClusterName' ] ] + InternalUrl: + Description: The url of the internal load balancer + Value: !Join ['', ['http://', !GetAtt 'PrivateLoadBalancer.DNSName']] + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'InternalUrl' ] ] + ExternalUrl: + Description: The url of the external load balancer + Value: !Join ['', ['http://', !GetAtt 'PublicLoadBalancer.DNSName']] + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ExternalUrl' ] ] + ECSRole: + Description: The ARN of the ECS role + Value: !GetAtt 'ECSRole.Arn' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'ECSRole' ] ] + PublicListener: + Description: The ARN of the public load balancer's Listener + Value: !Ref PublicLoadBalancerListener + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicListener' ] ] + PrivateListener: + Description: The ARN of the public load balancer's Listener + Value: !Ref PrivateLoadBalancerListener + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateListener' ] ] + VPCId: + Description: The ID of the VPC that this stack is deployed in + Value: !Ref 'VPC' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'VPCId' ] ] + PublicSubnetOne: + Description: Public subnet one + Value: !Ref 'PublicSubnetOne' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetOne' ] ] + PublicSubnetTwo: + Description: Public subnet two + Value: !Ref 'PublicSubnetTwo' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PublicSubnetTwo' ] ] + PrivateSubnetOne: + Description: Private subnet one + Value: !Ref 'PrivateSubnetOne' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateSubnetOne' ] ] + PrivateSubnetTwo: + Description: Private subnet two + Value: !Ref 'PrivateSubnetTwo' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'PrivateSubnetTwo' ] ] + EcsHostSecurityGroup: + Description: A security group used to allow containers to receive traffic + Value: !Ref 'EcsHostSecurityGroup' + Export: + Name: !Join [ ':', [ !Ref 'AWS::StackName', 'EcsHostSecurityGroup' ] ] diff --git a/aws-ecs-ec2/services-agent.yaml b/aws-ecs-ec2/services-agent.yaml new file mode 100644 index 0000000..e65ea46 --- /dev/null +++ b/aws-ecs-ec2/services-agent.yaml @@ -0,0 +1,120 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Deploy the instana agent on ECS as a daemon service +Parameters: + StackName: + Type: String + Default: production + Description: The name of the parent cluster stack that you created. Necessary + to locate and reference resources created by that stack. + ServiceName: + Type: String + Default: instana-agent + Description: A name for the service + ImageUrl: + Type: String + Default: instana/agent + Description: The url of a docker image that contains the application process that + will handle the traffic for this service + ContainerCpu: + Type: Number + Default: 1024 + Description: How much CPU to give the container. 1024 is 1 CPU + ContainerMemory: + Type: Number + Default: 2048 + Description: How much memory in megabytes to give the container + Role: + Type: String + Default: "" + Description: (Optional) An IAM role to give the service's containers if the code within needs to + access other AWS resources like S3 buckets, DynamoDB tables, etc + InstanaAgentKey: + Type: String + InstanaAgentEndpoint: + Type: String + Default: "ingress-red-saas.instana.io" + InstanaAgentEndpointPort: + Type: Number + Default: '443' + +Conditions: + HasCustomRole: !Not [ !Equals [!Ref 'Role', ''] ] + +Resources: + + # The task definition. This is a simple metadata description of what + # container to run, and what resource requirements it has. + TaskDefinition: + Type: AWS::ECS::TaskDefinition + Properties: + Family: !Ref 'ServiceName' + Cpu: !Ref 'ContainerCpu' + Memory: !Ref 'ContainerMemory' + TaskRoleArn: + Fn::If: + - 'HasCustomRole' + - !Ref 'Role' + - !Ref "AWS::NoValue" + NetworkMode: host + IpcMode: host + PidMode: host + Volumes: + - Host: + SourcePath: "/var/run" + Name: "host-var-run" + - Host: + SourcePath: "/run" + Name: "host-run" + - Host: + SourcePath: "/dev" + Name: "host-dev" + - Host: + SourcePath: "/sys" + Name: "host-sys" + - Host: + SourcePath: "/var/log" + Name: "host-var-log" + ContainerDefinitions: + - Name: !Ref 'ServiceName' + Cpu: !Ref 'ContainerCpu' + Memory: !Ref 'ContainerMemory' + Image: !Ref 'ImageUrl' + Privileged: true + MountPoints: + - ContainerPath: /var/run + SourceVolume: "host-var-run" + ReadOnly: false + - ContainerPath: /run + SourceVolume: "host-run" + ReadOnly: false + - ContainerPath: /dev + SourceVolume: "host-dev" + ReadOnly: false + - ContainerPath: /sys + SourceVolume: "host-sys" + ReadOnly: false + - ContainerPath: /var/log + SourceVolume: "host-var-log" + ReadOnly: false + Environment: + - Name: INSTANA_ZONE + Value: !Ref 'StackName' + - Name: INSTANA_AGENT_ENDPOINT + Value: !Ref 'InstanaAgentEndpoint' + - Name: INSTANA_AGENT_ENDPOINT_PORT + Value: !Ref 'InstanaAgentEndpointPort' + - Name: INSTANA_AGENT_KEY + Value: !Ref 'InstanaAgentKey' + + # The service. The service is a resource which allows you to run multiple + # copies of a type of task, and gather up their logs and metrics, as well + # as monitor the number of running tasks and replace any that have crashed + Service: + Type: AWS::ECS::Service + Properties: + ServiceName: !Ref 'ServiceName' + Cluster: + Fn::ImportValue: + !Join [':', [!Ref 'StackName', 'ClusterName']] + TaskDefinition: !Ref 'TaskDefinition' + SchedulingStrategy: DAEMON