Add docker hub credentials and lifecycle for ECR (#27)
* Add credentials for docker hub * Add lifecycle policy
This commit is contained in:
+11
-5
@@ -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 \
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"rulePriority": 1,
|
||||||
|
"description": "Only keep 8 images",
|
||||||
|
"selection": {
|
||||||
|
"tagStatus": "any",
|
||||||
|
"countType": "imageCountMoreThan",
|
||||||
|
"countNumber": 8
|
||||||
|
},
|
||||||
|
"action": { "type": "expire" }
|
||||||
|
}]
|
||||||
|
}
|
||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user