Add docker hub credentials and lifecycle for ECR (#27)

* Add credentials for docker hub

* Add lifecycle policy
This commit is contained in:
Niklas Fondberg
2020-10-09 12:33:57 +02:00
committed by GitHub
parent ba0952fb30
commit 486119aab1
3 changed files with 73 additions and 32 deletions
+11 -5
View File
@@ -1,11 +1,11 @@
## ##
# Example: # Example:
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=staging STACK_NAME=api # make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=staging
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=production STACK_NAME=api # make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=production
# #
# # make update-stack ENVIRONMENT_NAME=staging STACK_NAME=api # # make update-stack ENVIRONMENT_NAME=staging
## ##
STACK_NAME=api
GITHUB_REPO := api2 GITHUB_REPO := api2
GITHUB_USER := Photowall GITHUB_USER := Photowall
# HOSTED_ZONE=photowall.com default in the template # HOSTED_ZONE=photowall.com default in the template
@@ -54,6 +54,12 @@ check-create-initial-ecr-image:
echo ""; \ echo ""; \
fi fi
set-repository-lifecycle-policy:
@echo Setting lifecycle policy for repo $(STACK_NAME)-$(ENVIRONMENT_NAME)
@aws ecr put-lifecycle-policy \
--repository-name $(STACK_NAME)-$(ENVIRONMENT_NAME) \
--lifecycle-policy-text "file://ecr-lifecycle-policy.json"
check-create-variables-set: check-create-variables-set:
$(call checkdef,STACK_NAME) $(call checkdef,STACK_NAME)
$(call checkdef,ENVIRONMENT_NAME) $(call checkdef,ENVIRONMENT_NAME)
@@ -77,7 +83,7 @@ create-stack: check-create-variables-set check-create-initial-ecr-image
ParameterKey="MemorySize",ParameterValue="$(MEMORY_SIZE)" \ ParameterKey="MemorySize",ParameterValue="$(MEMORY_SIZE)" \
ParameterKey="BernardSQSPolicy",ParameterValue="$(BERNARD_SQS_POLICY)" ParameterKey="BernardSQSPolicy",ParameterValue="$(BERNARD_SQS_POLICY)"
update-stack: update-stack: set-repository-lifecycle-policy
$(call checkdef,STACK_NAME) $(call checkdef,STACK_NAME)
$(call checkdef,ENVIRONMENT_NAME) $(call checkdef,ENVIRONMENT_NAME)
aws cloudformation update-stack --stack-name $(STACK_NAME)-$(ENVIRONMENT_NAME) --template-body file://ecs-service.yaml \ aws cloudformation update-stack --stack-name $(STACK_NAME)-$(ENVIRONMENT_NAME) --template-body file://ecs-service.yaml \
+13
View File
@@ -0,0 +1,13 @@
{
"rules": [
{
"rulePriority": 1,
"description": "Only keep 8 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 8
},
"action": { "type": "expire" }
}]
}
+49 -27
View File
@@ -94,7 +94,7 @@ Resources:
Cluster: Cluster:
Type: AWS::ECS::Cluster Type: AWS::ECS::Cluster
Properties: Properties:
ClusterName: !Join ['', [!Ref 'AWS::StackName', Cluster]] ClusterName: !Join ["", [!Ref "AWS::StackName", Cluster]]
TaskDefinition: TaskDefinition:
Type: AWS::ECS::TaskDefinition Type: AWS::ECS::TaskDefinition
@@ -102,7 +102,7 @@ Resources:
DependsOn: LogGroup DependsOn: LogGroup
Properties: Properties:
# Name of the task definition. Subsequent versions of the task definition are grouped together under this name. # Name of the task definition. Subsequent versions of the task definition are grouped together under this name.
Family: !Join ['', [!Ref 'AWS::StackName', TaskDefinition]] Family: !Join ["", [!Ref "AWS::StackName", TaskDefinition]]
# awsvpc is required for Fargate # awsvpc is required for Fargate
NetworkMode: awsvpc NetworkMode: awsvpc
RequiresCompatibilities: RequiresCompatibilities:
@@ -125,9 +125,12 @@ Resources:
- ContainerPort: !Ref ContainerPort - ContainerPort: !Ref ContainerPort
# Define which parameters should be fetched # Define which parameters should be fetched
Secrets: Secrets:
- { Name: "SQLALCHEMY_DATABASE_URI", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/SQLALCHEMY_DATABASE_URI" } - Name: "SQLALCHEMY_DATABASE_URI"
- { Name: "API_KEYS", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/API2_API_KEYS" } ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/SQLALCHEMY_DATABASE_URI"
- { Name: "BERNARD_QUEUE_URL", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/BERNARD_QUEUE_URL" } - Name: "API_KEYS"
ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/API2_API_KEYS"
- Name: "BERNARD_QUEUE_URL"
ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/BERNARD_QUEUE_URL"
# Send logs to CloudWatch Logs # Send logs to CloudWatch Logs
LogConfiguration: LogConfiguration:
LogDriver: awslogs LogDriver: awslogs
@@ -140,49 +143,49 @@ Resources:
ExecutionRole: ExecutionRole:
Type: AWS::IAM::Role Type: AWS::IAM::Role
Properties: Properties:
RoleName: !Join ['', [!Ref 'AWS::StackName', ExecutionRole]] RoleName: !Join ["", [!Ref "AWS::StackName", ExecutionRole]]
AssumeRolePolicyDocument: AssumeRolePolicyDocument:
Statement: Statement:
- Effect: Allow - Effect: Allow
Principal: Principal:
Service: ecs-tasks.amazonaws.com Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole' Action: "sts:AssumeRole"
ManagedPolicyArns: ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy' - "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
- arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
# A role for the containers # A role for the containers
TaskRole: TaskRole:
Type: AWS::IAM::Role Type: AWS::IAM::Role
Properties: Properties:
RoleName: !Join ['', [!Ref 'AWS::StackName', TaskRole]] RoleName: !Join ["", [!Ref "AWS::StackName", TaskRole]]
AssumeRolePolicyDocument: AssumeRolePolicyDocument:
Statement: Statement:
- Effect: Allow - Effect: Allow
Principal: Principal:
Service: ecs-tasks.amazonaws.com Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole' Action: "sts:AssumeRole"
ManagedPolicyArns: ManagedPolicyArns:
- !Ref BernardSQSPolicy - !Ref BernardSQSPolicy
# A role needed for auto scaling # A role needed for auto scaling
AutoScalingRole: AutoScalingRole:
Type: AWS::IAM::Role Type: AWS::IAM::Role
Properties: Properties:
RoleName: !Join ['', [!Ref 'AWS::StackName', AutoScalingRole]] RoleName: !Join ["", [!Ref "AWS::StackName", AutoScalingRole]]
AssumeRolePolicyDocument: AssumeRolePolicyDocument:
Statement: Statement:
- Effect: Allow - Effect: Allow
Principal: Principal:
Service: ecs-tasks.amazonaws.com Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole' Action: "sts:AssumeRole"
ManagedPolicyArns: ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole' - "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole"
ContainerSecurityGroup: ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup Type: AWS::EC2::SecurityGroup
Properties: Properties:
GroupDescription: !Join ['', [!Ref 'AWS::StackName', ContainerSecurityGroup]] GroupDescription:
!Join ["", [!Ref "AWS::StackName", ContainerSecurityGroup]]
VpcId: !Ref VPC VpcId: !Ref VPC
SecurityGroupIngress: SecurityGroupIngress:
- IpProtocol: tcp - IpProtocol: tcp
@@ -193,7 +196,8 @@ Resources:
LoadBalancerSecurityGroup: LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup Type: AWS::EC2::SecurityGroup
Properties: Properties:
GroupDescription: !Join ['', [!Ref 'AWS::StackName', LoadBalancerSecurityGroup]] GroupDescription:
!Join ["", [!Ref "AWS::StackName", LoadBalancerSecurityGroup]]
VpcId: !Ref VPC VpcId: !Ref VPC
SecurityGroupIngress: SecurityGroupIngress:
- IpProtocol: tcp - IpProtocol: tcp
@@ -241,7 +245,7 @@ Resources:
HealthCheckTimeoutSeconds: 5 HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2 UnhealthyThresholdCount: 2
HealthyThresholdCount: 2 HealthyThresholdCount: 2
Name: !Join ['', [!Ref 'AWS::StackName', TargetGroup]] Name: !Join ["", [!Ref "AWS::StackName", TargetGroup]]
Port: !Ref ContainerPort Port: !Ref ContainerPort
Protocol: HTTP Protocol: HTTP
TargetGroupAttributes: TargetGroupAttributes:
@@ -269,7 +273,7 @@ Resources:
# this is the default, but is specified here in case it needs to be changed # this is the default, but is specified here in case it needs to be changed
- Key: idle_timeout.timeout_seconds - Key: idle_timeout.timeout_seconds
Value: 60 Value: 60
Name: !Join ['', [!Ref 'AWS::StackName', LoadBalancer]] Name: !Join ["", [!Ref "AWS::StackName", LoadBalancer]]
# "internal" is also an option # "internal" is also an option
Scheme: internet-facing Scheme: internet-facing
SecurityGroups: SecurityGroups:
@@ -281,8 +285,8 @@ Resources:
DNSRecord: DNSRecord:
Type: AWS::Route53::RecordSet Type: AWS::Route53::RecordSet
Properties: Properties:
HostedZoneName: !Join ['', [!Ref HostedZoneName, .]] HostedZoneName: !Join ["", [!Ref HostedZoneName, .]]
Name: !Join ['', [!Ref Subdomain, ., !Ref HostedZoneName, .]] Name: !Join ["", [!Ref Subdomain, ., !Ref HostedZoneName, .]]
Type: A Type: A
AliasTarget: AliasTarget:
DNSName: !GetAtt LoadBalancer.DNSName DNSName: !GetAtt LoadBalancer.DNSName
@@ -291,14 +295,14 @@ Resources:
LogGroup: LogGroup:
Type: AWS::Logs::LogGroup Type: AWS::Logs::LogGroup
Properties: Properties:
LogGroupName: !Join ['', [/ecs/, !Ref 'AWS::StackName', TaskDefinition]] LogGroupName: !Join ["", [/ecs/, !Ref "AWS::StackName", TaskDefinition]]
AutoScalingTarget: AutoScalingTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties: Properties:
MinCapacity: !Ref MinContainers MinCapacity: !Ref MinContainers
MaxCapacity: !Ref MaxContainers MaxCapacity: !Ref MaxContainers
ResourceId: !Join ['/', [service, !Ref Cluster, !GetAtt Service.Name]] ResourceId: !Join ["/", [service, !Ref Cluster, !GetAtt Service.Name]]
ScalableDimension: ecs:service:DesiredCount ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs ServiceNamespace: ecs
# "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that allows Application Auto Scaling to modify your scalable target." # "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that allows Application Auto Scaling to modify your scalable target."
@@ -306,7 +310,7 @@ Resources:
AutoScalingPolicy: AutoScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties: Properties:
PolicyName: !Join ['', [!Ref 'AWS::StackName', AutoScalingPolicy]] PolicyName: !Join ["", [!Ref "AWS::StackName", AutoScalingPolicy]]
PolicyType: TargetTrackingScaling PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref AutoScalingTarget ScalingTargetId: !Ref AutoScalingTarget
TargetTrackingScalingPolicyConfiguration: TargetTrackingScalingPolicyConfiguration:
@@ -357,6 +361,11 @@ Resources:
- ecr:InitiateLayerUpload - ecr:InitiateLayerUpload
- ecr:UploadLayerPart - ecr:UploadLayerPart
- ecr:CompleteLayerUpload - ecr:CompleteLayerUpload
- Resource: !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/dockerhub/*
Effect: Allow
Action:
- ssm:GetParameter
- ssm:GetParameters
CodePipelineServiceRole: CodePipelineServiceRole:
Type: AWS::IAM::Role Type: AWS::IAM::Role
@@ -407,9 +416,13 @@ Resources:
BuildSpec: | BuildSpec: |
version: 0.2 version: 0.2
phases: phases:
install:
runtime-versions:
docker: 19
pre_build: pre_build:
commands: commands:
- $(aws ecr get-login --no-include-email) - echo Logging in to Docker Hub...
- echo $DOCKERHUB_PASSWORD | docker login --username $DOCKERHUB_USERNAME --password-stdin
- TAG="$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)" - TAG="$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)"
- IMAGE_URI="${REPOSITORY_URI}:${TAG}" - IMAGE_URI="${REPOSITORY_URI}:${TAG}"
- IMAGE_LATEST_URI="${REPOSITORY_URI}:latest" - IMAGE_LATEST_URI="${REPOSITORY_URI}:latest"
@@ -419,6 +432,8 @@ Resources:
- docker tag "$IMAGE_URI" "$IMAGE_LATEST_URI" - docker tag "$IMAGE_URI" "$IMAGE_LATEST_URI"
post_build: post_build:
commands: commands:
- echo Logging in to ECR to push image
- $(aws ecr get-login --no-include-email --region eu-west-1)
- docker push "$IMAGE_URI" - docker push "$IMAGE_URI"
- docker push "$IMAGE_LATEST_URI" - docker push "$IMAGE_LATEST_URI"
- printf '[{"name":"%s","imageUri":"%s"}]' "$IMAGE_NAME" "$IMAGE_LATEST_URI" > images.json - printf '[{"name":"%s","imageUri":"%s"}]' "$IMAGE_NAME" "$IMAGE_LATEST_URI" > images.json
@@ -426,7 +441,8 @@ Resources:
files: images.json files: images.json
Environment: Environment:
ComputeType: BUILD_GENERAL1_SMALL ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/docker:17.09.0 PrivilegedMode: true
Image: aws/codebuild/standard:4.0
Type: LINUX_CONTAINER Type: LINUX_CONTAINER
EnvironmentVariables: EnvironmentVariables:
- Name: AWS_DEFAULT_REGION - Name: AWS_DEFAULT_REGION
@@ -435,6 +451,12 @@ Resources:
Value: !Ref Image Value: !Ref Image
- Name: IMAGE_NAME - Name: IMAGE_NAME
Value: !Ref AWS::StackName Value: !Ref AWS::StackName
- Name: DOCKERHUB_USERNAME
Value: /dockerhub/username
Type: PARAMETER_STORE
- Name: DOCKERHUB_PASSWORD
Value: /dockerhub/password
Type: PARAMETER_STORE
Name: !Ref AWS::StackName Name: !Ref AWS::StackName
ServiceRole: !Ref CodeBuildServiceRole ServiceRole: !Ref CodeBuildServiceRole
@@ -442,7 +464,7 @@ Resources:
Type: AWS::CodePipeline::Pipeline Type: AWS::CodePipeline::Pipeline
Properties: Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn RoleArn: !GetAtt CodePipelineServiceRole.Arn
Name: !Join ['', [!Ref 'AWS::StackName', Pipeline]] Name: !Join ["", [!Ref "AWS::StackName", Pipeline]]
ArtifactStore: ArtifactStore:
Type: S3 Type: S3
Location: !Ref ArtifactBucket Location: !Ref ArtifactBucket
@@ -498,7 +520,7 @@ Resources:
Outputs: Outputs:
Endpoint: Endpoint:
Description: Endpoint Description: Endpoint
Value: !Join ['', ['https://', !Ref DNSRecord]] Value: !Join ["", ["https://", !Ref DNSRecord]]
Service: Service:
Value: Service Value: Service
PipelineUrl: PipelineUrl: