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:
|
||||
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=staging STACK_NAME=api
|
||||
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=production STACK_NAME=api
|
||||
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=staging
|
||||
# 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_USER := Photowall
|
||||
# HOSTED_ZONE=photowall.com default in the template
|
||||
@@ -54,6 +54,12 @@ check-create-initial-ecr-image:
|
||||
echo ""; \
|
||||
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:
|
||||
$(call checkdef,STACK_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="BernardSQSPolicy",ParameterValue="$(BERNARD_SQS_POLICY)"
|
||||
|
||||
update-stack:
|
||||
update-stack: set-repository-lifecycle-policy
|
||||
$(call checkdef,STACK_NAME)
|
||||
$(call checkdef,ENVIRONMENT_NAME)
|
||||
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:
|
||||
Type: AWS::ECS::Cluster
|
||||
Properties:
|
||||
ClusterName: !Join ['', [!Ref 'AWS::StackName', Cluster]]
|
||||
ClusterName: !Join ["", [!Ref "AWS::StackName", Cluster]]
|
||||
|
||||
TaskDefinition:
|
||||
Type: AWS::ECS::TaskDefinition
|
||||
@@ -102,7 +102,7 @@ Resources:
|
||||
DependsOn: LogGroup
|
||||
Properties:
|
||||
# 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
|
||||
NetworkMode: awsvpc
|
||||
RequiresCompatibilities:
|
||||
@@ -125,9 +125,12 @@ Resources:
|
||||
- ContainerPort: !Ref ContainerPort
|
||||
# Define which parameters should be fetched
|
||||
Secrets:
|
||||
- { Name: "SQLALCHEMY_DATABASE_URI", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/SQLALCHEMY_DATABASE_URI" }
|
||||
- { 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" }
|
||||
- Name: "SQLALCHEMY_DATABASE_URI"
|
||||
ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/SQLALCHEMY_DATABASE_URI"
|
||||
- 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
|
||||
LogConfiguration:
|
||||
LogDriver: awslogs
|
||||
@@ -140,49 +143,49 @@ Resources:
|
||||
ExecutionRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
RoleName: !Join ['', [!Ref 'AWS::StackName', ExecutionRole]]
|
||||
RoleName: !Join ["", [!Ref "AWS::StackName", ExecutionRole]]
|
||||
AssumeRolePolicyDocument:
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: ecs-tasks.amazonaws.com
|
||||
Action: 'sts:AssumeRole'
|
||||
Action: "sts:AssumeRole"
|
||||
ManagedPolicyArns:
|
||||
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
|
||||
- "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
|
||||
- arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
|
||||
# A role for the containers
|
||||
TaskRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
RoleName: !Join ['', [!Ref 'AWS::StackName', TaskRole]]
|
||||
RoleName: !Join ["", [!Ref "AWS::StackName", TaskRole]]
|
||||
AssumeRolePolicyDocument:
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: ecs-tasks.amazonaws.com
|
||||
Action: 'sts:AssumeRole'
|
||||
Action: "sts:AssumeRole"
|
||||
ManagedPolicyArns:
|
||||
- !Ref BernardSQSPolicy
|
||||
|
||||
|
||||
# A role needed for auto scaling
|
||||
AutoScalingRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
RoleName: !Join ['', [!Ref 'AWS::StackName', AutoScalingRole]]
|
||||
RoleName: !Join ["", [!Ref "AWS::StackName", AutoScalingRole]]
|
||||
AssumeRolePolicyDocument:
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service: ecs-tasks.amazonaws.com
|
||||
Action: 'sts:AssumeRole'
|
||||
Action: "sts:AssumeRole"
|
||||
ManagedPolicyArns:
|
||||
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole'
|
||||
- "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole"
|
||||
|
||||
ContainerSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Join ['', [!Ref 'AWS::StackName', ContainerSecurityGroup]]
|
||||
GroupDescription:
|
||||
!Join ["", [!Ref "AWS::StackName", ContainerSecurityGroup]]
|
||||
VpcId: !Ref VPC
|
||||
SecurityGroupIngress:
|
||||
- IpProtocol: tcp
|
||||
@@ -193,7 +196,8 @@ Resources:
|
||||
LoadBalancerSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: !Join ['', [!Ref 'AWS::StackName', LoadBalancerSecurityGroup]]
|
||||
GroupDescription:
|
||||
!Join ["", [!Ref "AWS::StackName", LoadBalancerSecurityGroup]]
|
||||
VpcId: !Ref VPC
|
||||
SecurityGroupIngress:
|
||||
- IpProtocol: tcp
|
||||
@@ -241,7 +245,7 @@ Resources:
|
||||
HealthCheckTimeoutSeconds: 5
|
||||
UnhealthyThresholdCount: 2
|
||||
HealthyThresholdCount: 2
|
||||
Name: !Join ['', [!Ref 'AWS::StackName', TargetGroup]]
|
||||
Name: !Join ["", [!Ref "AWS::StackName", TargetGroup]]
|
||||
Port: !Ref ContainerPort
|
||||
Protocol: HTTP
|
||||
TargetGroupAttributes:
|
||||
@@ -269,7 +273,7 @@ Resources:
|
||||
# this is the default, but is specified here in case it needs to be changed
|
||||
- Key: idle_timeout.timeout_seconds
|
||||
Value: 60
|
||||
Name: !Join ['', [!Ref 'AWS::StackName', LoadBalancer]]
|
||||
Name: !Join ["", [!Ref "AWS::StackName", LoadBalancer]]
|
||||
# "internal" is also an option
|
||||
Scheme: internet-facing
|
||||
SecurityGroups:
|
||||
@@ -281,8 +285,8 @@ Resources:
|
||||
DNSRecord:
|
||||
Type: AWS::Route53::RecordSet
|
||||
Properties:
|
||||
HostedZoneName: !Join ['', [!Ref HostedZoneName, .]]
|
||||
Name: !Join ['', [!Ref Subdomain, ., !Ref HostedZoneName, .]]
|
||||
HostedZoneName: !Join ["", [!Ref HostedZoneName, .]]
|
||||
Name: !Join ["", [!Ref Subdomain, ., !Ref HostedZoneName, .]]
|
||||
Type: A
|
||||
AliasTarget:
|
||||
DNSName: !GetAtt LoadBalancer.DNSName
|
||||
@@ -291,14 +295,14 @@ Resources:
|
||||
LogGroup:
|
||||
Type: AWS::Logs::LogGroup
|
||||
Properties:
|
||||
LogGroupName: !Join ['', [/ecs/, !Ref 'AWS::StackName', TaskDefinition]]
|
||||
LogGroupName: !Join ["", [/ecs/, !Ref "AWS::StackName", TaskDefinition]]
|
||||
|
||||
AutoScalingTarget:
|
||||
Type: AWS::ApplicationAutoScaling::ScalableTarget
|
||||
Properties:
|
||||
MinCapacity: !Ref MinContainers
|
||||
MaxCapacity: !Ref MaxContainers
|
||||
ResourceId: !Join ['/', [service, !Ref Cluster, !GetAtt Service.Name]]
|
||||
ResourceId: !Join ["/", [service, !Ref Cluster, !GetAtt Service.Name]]
|
||||
ScalableDimension: ecs:service:DesiredCount
|
||||
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."
|
||||
@@ -306,7 +310,7 @@ Resources:
|
||||
AutoScalingPolicy:
|
||||
Type: AWS::ApplicationAutoScaling::ScalingPolicy
|
||||
Properties:
|
||||
PolicyName: !Join ['', [!Ref 'AWS::StackName', AutoScalingPolicy]]
|
||||
PolicyName: !Join ["", [!Ref "AWS::StackName", AutoScalingPolicy]]
|
||||
PolicyType: TargetTrackingScaling
|
||||
ScalingTargetId: !Ref AutoScalingTarget
|
||||
TargetTrackingScalingPolicyConfiguration:
|
||||
@@ -357,6 +361,11 @@ Resources:
|
||||
- ecr:InitiateLayerUpload
|
||||
- ecr:UploadLayerPart
|
||||
- ecr:CompleteLayerUpload
|
||||
- Resource: !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/dockerhub/*
|
||||
Effect: Allow
|
||||
Action:
|
||||
- ssm:GetParameter
|
||||
- ssm:GetParameters
|
||||
|
||||
CodePipelineServiceRole:
|
||||
Type: AWS::IAM::Role
|
||||
@@ -407,9 +416,13 @@ Resources:
|
||||
BuildSpec: |
|
||||
version: 0.2
|
||||
phases:
|
||||
install:
|
||||
runtime-versions:
|
||||
docker: 19
|
||||
pre_build:
|
||||
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)"
|
||||
- IMAGE_URI="${REPOSITORY_URI}:${TAG}"
|
||||
- IMAGE_LATEST_URI="${REPOSITORY_URI}:latest"
|
||||
@@ -419,6 +432,8 @@ Resources:
|
||||
- docker tag "$IMAGE_URI" "$IMAGE_LATEST_URI"
|
||||
post_build:
|
||||
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_LATEST_URI"
|
||||
- printf '[{"name":"%s","imageUri":"%s"}]' "$IMAGE_NAME" "$IMAGE_LATEST_URI" > images.json
|
||||
@@ -426,7 +441,8 @@ Resources:
|
||||
files: images.json
|
||||
Environment:
|
||||
ComputeType: BUILD_GENERAL1_SMALL
|
||||
Image: aws/codebuild/docker:17.09.0
|
||||
PrivilegedMode: true
|
||||
Image: aws/codebuild/standard:4.0
|
||||
Type: LINUX_CONTAINER
|
||||
EnvironmentVariables:
|
||||
- Name: AWS_DEFAULT_REGION
|
||||
@@ -435,6 +451,12 @@ Resources:
|
||||
Value: !Ref Image
|
||||
- Name: IMAGE_NAME
|
||||
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
|
||||
ServiceRole: !Ref CodeBuildServiceRole
|
||||
|
||||
@@ -442,7 +464,7 @@ Resources:
|
||||
Type: AWS::CodePipeline::Pipeline
|
||||
Properties:
|
||||
RoleArn: !GetAtt CodePipelineServiceRole.Arn
|
||||
Name: !Join ['', [!Ref 'AWS::StackName', Pipeline]]
|
||||
Name: !Join ["", [!Ref "AWS::StackName", Pipeline]]
|
||||
ArtifactStore:
|
||||
Type: S3
|
||||
Location: !Ref ArtifactBucket
|
||||
@@ -498,7 +520,7 @@ Resources:
|
||||
Outputs:
|
||||
Endpoint:
|
||||
Description: Endpoint
|
||||
Value: !Join ['', ['https://', !Ref DNSRecord]]
|
||||
Value: !Join ["", ["https://", !Ref DNSRecord]]
|
||||
Service:
|
||||
Value: Service
|
||||
PipelineUrl:
|
||||
|
||||
Reference in New Issue
Block a user