Is it possible to specify a CloudWatch logs retention policy in an ECS Task definition?
Couldn't find any documentation about it.
ServiceTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
ExecutionRoleArn: !GetAtt EcsTaskExecutionRole.Arn
TaskRoleArn: !GetAtt EcsTaskRole.Arn
Cpu: !Ref TaskDefinitionCpu
Memory: !Ref TaskDefinitionMemory
NetworkMode: awsvpc
ContainerDefinitions:
- Name: !Join ['-', ['container', !Ref AWS::StackName]]
Image: !Ref EcrImage
PortMappings:
- ContainerPort: !Ref Port
HostPort: !Ref Port
Protocol: tcp
Essential: true
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Join ['', ['/ecs/', !Ref AWS::StackName]]
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
awslogs-create-group: true
# Retention policy ??
Agree with other answer that there is no option to specify log retention in awslogs options
We need to create it and pass it along:
CloudwatchLogsGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: !Sub '${AWS::StackName}-ECSLogGroup'
RetentionInDays: 14
Container Definition:
ContainerTaskdefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
Family: !Ref 'AWS::StackName'
ExecutionRoleArn: !Ref ECSTaskExecutionRole
TaskRoleArn: !Ref ECSTaskExecutionRole
Cpu: '256'
Memory: 1GB
NetworkMode: awsvpc
RequiresCompatibilities:
- EC2
- FARGATE
ContainerDefinitions:
- Name: !Ref 'AWS::StackName'
Cpu: 256
Essential: 'true'
Image: !Ref Image
Memory: '1024'
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref CloudwatchLogsGroup <-- refer to log group
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: ecs
There appears to be no support for specifying the retention policy when you "auto create" the log group in the Task Definition. You could however create your log group out of band and let your Task Definition consume it (instead of auto creating it). The retention policy could be defined when you create the log group explicitly (that is, in the AWS::Logs::LogGroup definition). See here.
As with all other services that support logging to CloudWatch logs, if you want to set things like KMS encryption and log retention on the log group you have to create the log group first, with the settings you want, then configure the services to log to that log group.
Related
I am trying to deploy a new stack using CloudFormation with an ECS service using the CodeDeploy launch type to enable blue/green deployments.
In the User Guide for performing blue/green deployments via CloudFormation, they state the following:
To enable CloudFormation to perform blue/green deployments on a Stack, include the following information in its stack template:
At least one of the ECS resources that will trigger a blue/green deployment if replaced during a stack update. Currently, those resources are AWS::ECS::TaskDefinition and AWS::ECS::TaskSet.
When I exclude a AWS::ECS::TaskSet, the Stack creation fails and I receive the following error:
Transform AWS::CodeDeployBlueGreen failed with: Failed to transform template.
ECSAttributes must include TaskSets in AWS::CodeDeploy::BlueGreen Hook
If I add a AWS::ECS::TaskSet, the stack fails to create with the following error instead:
Resource handler returned message:
"Invalid request provided: Amazon ECS does not support task set management on services where deployments
are controlled by AWS CodeDeploy.
(Service: AmazonECS; Status Code: 400; Error Code: InvalidParameterException;
Request ID: 61b8c146-3ae9-4bc2-ac5c-08a11e194f06; Proxy: null)"
(RequestToken: 86a8a3a5-fe89-9939-15c2-45b08b28c3f3, HandlerErrorCode: InvalidRequest)
These are the relevant parts of my stack template:
Transform:
- AWS::CodeDeployBlueGreen
Hooks:
CodeDeployBlueGreenHook:
Type: AWS::CodeDeploy::BlueGreen
Properties:
ServiceRole: BlueGreenDeploymentRole
Applications:
- Target:
Type: AWS::ECS::Service
LogicalID: EcsService
ECSAttributes:
TaskDefinitions:
- TaskDefinitionBlue
- TaskDefinitionGreen
TaskSets:
- TaskSetBlue
- TaskSetGreen
TrafficRouting:
ProdTrafficRoute:
Type: AWS::ElasticLoadBalancingV2::Listener
LogicalID: LoadBalancerListener
TargetGroups:
- TargetGroupBlue
- TargetGroupGreen
TrafficRoutingConfig:
Type: TimeBasedLinear
TimeBasedLinear:
StepPercentage: 20
BakeTimeMins: 10
AdditionalOptions:
TerminationWaitTimeInMinutes: 60
Resources:
# IAM Role for blue/green deployments
BlueGreenDeploymentRole:
Type: AWS::IAM::Role
Properties:
RoleName: blue-green-deployment-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: codedeploy.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: BlueGreenDeploymentPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- codedeploy:Get*
- codedeploy:CreateCloudFormationDeployment
Resource: '*'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSCodeDeployRoleForECS
#########################
# Load Balancer
#########################
# Application Load Balancer
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
IpAddressType: ipv4
Name: service-alb
Scheme: internal
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
# Load Balancer Listener
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
ForwardConfig:
TargetGroups:
- TargetGroupArn: !Ref TargetGroupBlue
Weight: 1
- TargetGroupArn: !Ref TargetGroupGreen
Weight: 1
LoadBalancerArn: !Ref LoadBalancer
Port: 8080
Protocol: HTTP
# Load Balancer Target Groups
TargetGroupBlue:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${ServiceName}-blue
TargetType: ip
VpcId: !Ref Vpc
Port: 8080
Protocol: HTTP
HealthCheckPort: 8080
HealthCheckPath: /actuator/health
TargetGroupGreen:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${ServiceName}-green
TargetType: ip
VpcId: !Ref Vpc
Port: 8080
Protocol: HTTP
HealthCheckPort: 8080
HealthCheckPath: /actuator/health
#########################
# ECS
#########################
# ECS Cluster
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref ServiceName
# ECS Service
EcsService:
Type: AWS::ECS::Service
DependsOn: LoadBalancerListener
Properties:
ServiceName: !Ref ServiceName
Cluster: !Ref Cluster
TaskDefinition: !Ref TaskDefinitionBlue
DeploymentController:
Type: CODE_DEPLOY
DesiredCount: 0
LaunchType: FARGATE
LoadBalancers:
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupBlue
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupGreen
NetworkConfiguration:
AwsvpcConfiguration:
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
SchedulingStrategy: REPLICA
# Task Definitions
TaskDefinitionBlue:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Sub ${ServiceName}-container
Image: !Sub ${ImageRepository.RepositoryUri}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: payments
PortMappings:
- ContainerPort: 8080
Cpu: 256
Memory: 512
NetworkMode: awsvpc
Family: !Sub ${ServiceName}
ExecutionRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
TaskDefinitionGreen:
Type: AWS::ECS::TaskDefinition
Properties:
ContainerDefinitions:
- Name: !Sub ${ServiceName}-container
Image: !Sub ${ImageRepository.RepositoryUri}:latest
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: payments
PortMappings:
- ContainerPort: 8080
Cpu: 256
Memory: 512
NetworkMode: awsvpc
Family: !Sub ${ServiceName}
ExecutionRoleArn: !Ref TaskExecutionRole
RequiresCompatibilities:
- FARGATE
# Image Repository
ImageRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: !Sub ${ServiceName}
LifecyclePolicy:
LifecyclePolicyText: |
{
"rules": [
{
"rulePriority": 1,
"description": "Maintain at most 25 images",
"selection": {
"tagStatus": "untagged",
"countType": "imageCountMoreThan",
"countNumber": 25
},
"action": {
"type": "expire"
}
}
]
}
TaskSetBlue:
Type: AWS::ECS::TaskSet
Properties:
Cluster: !Ref Cluster
LaunchType: FARGATE
Service: !Ref EcsService
TaskDefinition: !Ref TaskDefinitionBlue
NetworkConfiguration:
AwsVpcConfiguration:
Subnets:
- !Ref SubnetOne
- !Ref SubnetTwo
SecurityGroups:
- !Ref SecurityGroup
LoadBalancers:
- ContainerName: !Sub ${ServiceName}-container
ContainerPort: 8080
TargetGroupArn: !Ref TargetGroupBlue
How can I update my template to allow for the blue/green deployment strategy via CodeDeploy?
G/B deployment using CFN is EXTERNAL, not CODE_DEPLOY. There could be many other issues with your template, but your current error relates to using wrong DeploymentController. Please study AWS docs and example:
Perform ECS blue/green deployments through CodeDeploy using AWS CloudFormation
Exactly, AWS doesn't support Blue Green deployment on EC2/ASG...!
The easiest way that I just figure out is to create the deployment group with In-Place method && Then change the deployment group configuration manually from In-place to Blue Green
Or you can use the lambda function, but is a litte bit hard to customize it
Wish this will help you
I'm have an issue hopping you can help.
I wanted to make aws ecs task but I cant find a way to auto-scale it
its stuck with 256CPU and 512Memory, and I dont want to hard code it (2G memory) because I don't need it all the time
Parameters:
SubnetIds:
Type: "List<AWS::EC2::Subnet::Id>"
Description: Select at least two subnets in your selected VPC.
Resources:
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: name
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
-
Name: "name"
Image: "**/latest"
Essential: true
logConfiguration:
logDriver: awslogs
options:
awslogs-group: /log/scheduledtasks
awslogs-region: us-east-2
awslogs-stream-prefix: log
Environment:
- Name: OP_MODE
Value: CRONJOB
Secrets:**
ExecutionRoleArn: !ImportValue TaskExecutionRole
Cpu: 256
Memory: 512
TaskSchedule1:
Type: AWS::Events::Rule
Properties:
Description: Description
Name: name
ScheduleExpression: cron(5 10 * * ? *)
State: ENABLED
Targets:
- Id: id-name
RoleArn: !ImportValue SchedulerRole
EcsParameters:
TaskDefinitionArn:
Ref: TaskDefinition
TaskCount: 1
LaunchType: FARGATE
NetworkConfiguration:
AwsVpcConfiguration:
AssignPublicIp: ENABLED
Subnets: !Split [',', !Join [',', !Ref SubnetIds]]
Input: '{"containerOverrides":[{"name":"a","environment":[{"name":"TARGET_JOB","value":"definition"}]}]}'
Arn: !ImportValue Cluster
any tip or resource will be so helpful
I'm still learning, so thank you for your help
You can't do this. This is not how autoscaling of ECS services/tasks work. You autoscale your service by launching multiple instances of the same task, not by automatically increasing/decreasing the amount of ram and cpu you have allocated.
I'm creating a ECS service in CloudFormation.
I receive no error, it just will sit at the CREATE_IN_PROGRESS on the logical ID = Service phase..
Here's my CF template (ECS cluster & some other stuff above but cut out due to relevance).
TaskDefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
Family: flink
Memory: 2048
Cpu: 512
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: flink-jobmanager
Image: ACCOUNT_ID.dkr.ecr.us-west-1.amazonaws.com/teststack-flink:latest
Essential: true
PortMappings:
- ContainerPort: 8081
HostPort: 8081
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: ecs/flink-stream
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
Command:
- jobmanager
- Name: flink-taskmanager
Image: ACCOUNT_ID.dkr.ecr.us-west-1.amazonaws.com/teststack-flink:latest
Essential: true
Command:
- taskmanager
ExecutionRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole
Volumes: []
TaskRoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole
Tags:
-
Key: EnvironmentStage
Value: !Ref EnvironmentStage
Service:
Type: 'AWS::ECS::Service'
Properties:
ServiceName: !Join ['', [!Ref EnvironmentStage, '-', !Ref 'AWS::StackName']]
Cluster: !Join ['', ['arn:aws:ecs:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':cluster/', !Ref ECSCluster]]
LaunchType: FARGATE
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 75
TaskDefinition: !Join ['', ['arn:aws:ecs:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':task-definition/', !Ref TaskDefinition]]
# TaskDefinition: !Ref TaskDefinition
DesiredCount: 1
DeploymentController:
Type: ECS
EnableECSManagedTags: true
PropagateTags: TASK_DEFINITION
SchedulingStrategy: REPLICA
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
SecurityGroups:
- !Ref FlinkSecurityGroup
Subnets:
- subnet-466da11c
- subnet-6fe65509
Tags:
-
Key: EnvironmentStage
Value: !Ref EnvironmentStage
The containers both deploy to the cluster when I set it up manually
After checking clusters -> CLUSTER_NAME -> tasks -> stopped I saw the following:
Status reason CannotStartContainerError: Error response from daemon:
failed to initialize logging driver: failed to create Cloudwatch log stream:
ResourceNotFoundException: The specified log group does not exist.
The issue was simply that I forgot to add the creating of a log group to to my CF template.. So I added this:
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub ${EnvironmentStage}-service-flink
Then modified the LogConfiguration in TaskDefinition to this:
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LogGroup
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: flink
Now the CF template works like a charm :)
I am trying to run PGAdmin4 as a docker container on AWS Fargate but for some reason the container is exiting. Cloudwatch logs were not so helpful either.
Here is my Task definiton and Service. Indentation may not be accurate after copying it here.
Task:
Type: AWS::ECS::TaskDefinition
Properties:
Family: pgadmin
Cpu: 2048
Memory: 4096
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: !Ref ECSTaskExecutionRole
ContainerDefinitions:
- Name: pgadmin
Image: dpage/pgadmin4 # From dockerhub
Cpu: 2048
Memory: 4096
PortMappings:
- ContainerPort: 80
Protocol: tcp
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: pgadmin
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: pgadmin
Environment:
- Name: PGADMIN_DEFAULT_EMAIL
Value: s-polimetla#s-polimetla.de
- Name: PGADMIN_DEFAULT_PASSWORD
Value: test1234
Service:
Type: AWS::ECS::Service
DependsOn: ListenerRule
Properties:
ServiceName: pgadmin-service
TaskDefinition: !Ref Task
Cluster: !Ref ECSCluster
LaunchType: FARGATE
DesiredCount: 1
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: ENABLED
Subnets:
- Fn::ImportValue:
!Sub ${NetworkStackName}-subnet1
- Fn::ImportValue:
!Sub ${NetworkStackName}-subnet2
SecurityGroups:
- Fn::ImportValue:
!Sub ${NetworkStackName}-container-SG
LoadBalancers:
- ContainerName: pgadmin
ContainerPort: 80
TargetGroupArn: !Ref TargetGroup
My cloudwatch logs show the following
You can find the complete template here. Please feel free to correct it if you find anything wrong with it.
I cannot figure out what went wrong from the logs. Any pointers here?
I have following cloudformation template snippet. The entire template creates the ECS fargate cluster along with all resources. but now, I am facing issues with fargate service and task definitions.
The service section of template is as follows :
Service:
Type: AWS::ECS::Service
# This dependency is needed so that the load balancer is setup correctly in time
Properties:
ServiceName: !Ref ServiceName
Cluster: !Ref Cluster
TaskDefinition: !Ref TaskDefinition
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DesiredCount: 2
# This may need to be adjusted if the container takes a while to start up
HealthCheckGracePeriodSeconds: 30
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
# change to DISABLED if you're using private subnets that have access to a NAT gateway
AssignPublicIp: ENABLED
Subnets:
- !Ref abcvmnSubnetA
- !Ref abcvmnSubnetB
SecurityGroups:
- !Ref ContainerSecurityGroup
LoadBalancers:
- ContainerName: !Ref ServiceName
ContainerPort: !Ref ContainerPort
TargetGroupArn: !Ref TargetGroup
and the task definition is as follows :
TaskDefinition:
Type: AWS::ECS::TaskDefinition
# Makes sure the log group is created before it is used.
DependsOn: LogGroup
Properties:
# Name of the task definition. Subsequent versions of the task definition are grouped together under this name.
Family: abc-taskdef-dev
# awsvpc is required for Fargate
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: 512
Memory: 1GB
# A role needed by ECS.
# "The ARN of the task execution role that containers in this task can assume. All containers in this task are granted the permissions that are specified in this role."
# "There is an optional task execution IAM role that you can specify with Fargate to allow your Fargate tasks to make API calls to Amazon ECR."
ExecutionRoleArn: arn:aws:iam::890543041640:role/ecsTaskExecutionRole
# "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that grants containers in the task permission to call AWS APIs on your behalf."
TaskRoleArn: arn:aws:iam::890543041640:role/ecsTaskExecutionRole
ContainerDefinitions:
- Name: abc-sampleappcontainer-dev
Image: 890543041640.dkr.ecr.eu-central-1.amazonaws.com/abc:latest
PortMappings:
- ContainerPort: 8080
# Send logs to CloudWatch Logs
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-region: eu-central-1
awslogs-group: /ecs/abc-taskdef-dev
awslogs-stream-prefix: ecs
I know that , fargate service and task definitions are related to each other in the cluster. but the issue is, how to make that relationship using template.
I am getting following failure event :
The container abc-service-dev does not exist in the task definition.
(Service: AmazonECS; Status Code: 400; Error Code:
InvalidParameterException; Request ID:
008417e7-126e-11e9-98cb-ef191beeddae)
not sure, where I am doing wrong.
Your line 154
- Name: abc-sampleappcontainer-dev
change to
- Name: !Ref ServiceName
instead. because you have on line 272
- ContainerName: !Ref ServiceName
The two needs to match.
Here's an example that works:
note the name 'jaeger-query'
QueryTaskDef:
Type: 'AWS::ECS::TaskDefinition'
Properties:
ContainerDefinitions:
- Command: !Ref 'AWS::NoValue'
Name: jaeger-query
Cpu: !Ref CpuReservation
Essential: 'true'
Image: !Ref QueryImageName
Memory: !Ref MemoryReservation
Environment:
- Name: SPAN_STORAGE_TYPE
Value: elasticsearch
- Name: ES_SERVER_URLS
Value: !Sub 'http://${EsHost}:9200/'
PortMappings:
- ContainerPort: 16686
- ContainerPort: 16687
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref LxDockerLog
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: !Ref 'AWS::StackName'
QueryService:
Type: 'AWS::ECS::Service'
DependsOn: AlbListenerRule
Properties:
Cluster: !Ref EcsCluster
Role: !Ref ServiceSchedulingRole
LoadBalancers:
- ContainerName: jaeger-query
ContainerPort: 16686
TargetGroupArn: !Ref AlbTargetGroup
DesiredCount: 2
TaskDefinition: !Ref QueryTaskDef
AlbListenerRule:
Type: 'AWS::ElasticLoadBalancingV2::ListenerRule'
Properties:
Actions:
- Type: forward
TargetGroupArn: !Ref AlbTargetGroup
Conditions:
- Field: host-header
Values: [!Sub '${Subdomain}.${HostedZoneName}']
ListenerArn: !Ref HttpListener
Priority: !Ref ListenerPriority
AlbTargetGroup:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
HealthCheckIntervalSeconds: '60'
HealthCheckPath: '/'
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: '30'
HealthyThresholdCount: 10
Port: 16686
Protocol: HTTP
UnhealthyThresholdCount: 10
VpcId: !Ref VpcId
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: !Ref DeregistrationDelay
Refer to here for the full template
https://github.com/Bit-Clouded/Glenlivet/blob/master/analytics/jaeger.template