In this lab you will configure GitLab CI/CD runners using GitLab HA Scaling Runner Vending Machine for AWS solution. You can find more about its features here. It is built using Infrastructure as Code (IaC) with AWS CloudFormation, but you can implement similar logic using any IaC solution of your choice.
There are also other ways to create GitLab runners on spot instances that we are not reviewing in this workshop: using Docker Machine, runners inside containers in a Kubernetes cluster with the worker nodes on spot instances, or in Amazon ECS with Fargate Spot.
ec2-role-trust-policy.json
.cat << EOF > ~/environment/ec2-role-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}
EOF
create-role
command.aws iam create-role \
--role-name gitlab-runner \
--assume-role-policy-document file://~/environment/ec2-role-trust-policy.json
cat << EOF > ~/environment/gitlab-runner-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EKSGetAllClusters",
"Effect": "Allow",
"Action": [
"eks:DescribeNodegroup",
"eks:ListNodegroups",
"eks:DescribeCluster",
"eks:ListClusters",
"eks:AccessKubernetesApi",
"ssm:GetParameter",
"eks:ListUpdates",
"eks:ListFargateProfiles"
],
"Resource": "*"
},
{
"Sid": "ASGSelfAccess",
"Effect": "Allow",
"Action": [
"iam:ListAccountAliases",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeLifecycle*"
],
"Resource": "*"
},
{
"Sid": "ASGLifeCycleAccess",
"Effect": "Allow",
"Action": [
"autoscaling:CompleteLifecycleAction",
"autoscaling:RecordLifecycleActionHeartbeat"
],
"Resource": "arn:aws:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/linux-docker-scaling-spotonly*"
},
{
"Sid": "AllowRunnerJobsToDoPredictiveScaling",
"Effect": "Allow",
"Action": [
"autoscaling:UpdateAutoScalingGroup"
],
"Resource": "arn:aws:autoscaling:*:*:autoScalingGroup:*:autoScalingGroupName/linux-docker-scaling-spotonly*"
},
{
"Sid": "EC2SelfAccess",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeTags"
],
"Resource": "*"
},
{
"Sid": "S3CacheBucketAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketVersioning",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::*linux-docker-scaling-spotonly*"
},
{
"Sid": "ECRAccess",
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
},
{
"Sid": "ECRAccessRepo",
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Resource": "arn:aws:ecr:*:*:*gitlab-spot-demo*"
}
]
}
EOF
aws iam put-role-policy \
--role-name gitlab-runner \
--policy-name gitlab-runner-access \
--policy-document file://~/environment/gitlab-runner-policy.json
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
--role-name gitlab-runner
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore \
--role-name gitlab-runner
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole \
--role-name gitlab-runner
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonSSMMaintenanceWindowRole \
--role-name gitlab-runner
aws iam create-instance-profile --instance-profile-name gitlab-runner
aws iam add-role-to-instance-profile \
--instance-profile-name gitlab-runner \
--role-name gitlab-runner
Note that here you are assigning permission policies as required for the demo app. In a real Production environment you should always follow the least privilege principle. You can find the best practices in AWS Blogs.
You will now get the runner configuration information from GitLab and then start the AWS CloudFormation stack deployment.
Download the CloudFormation template latest version located here.
Return to the browser tab with CloudFormation or open it again using the search box at the top.
Choose Create stack and in the dropdown choose With new resources (standard).
In the Template source field select Upload a template file, choose the GitLabElasticScalingRunner.cf.yml
file you have just downloaded above, and choose Next.
In the Stack name field enter linux-docker-scaling-spotonly
(extremely important, as this name is used in the IAM policy above).
Challenge: Investigate the parameters presented and try deploying the stack yourself. Expand the section below to see step-by-step instructions.
https://xxx.cloudfront.net
).2
.gitlab-runner
.vpc-...
) by running below command in Cloud9:echo VPC ID = $VPC
m5a.large
. For the third and fourth priority enter m5d.large
and m5n.large
respectively.true
in the dropdown.10
.40
.60
.70
.60
.0
.CREATE_COMPLETE
status, which should take approximately 5 minutes.You had to use the full template to customize the IAM role used by the runners. If your production scenario does not require this and you are fine with the default permissions, you can use one of the easy buttons (out-of-the-box scenarios) provided here to deploy the stack: this will require less parameters to customize.
linux-docker-scaling-spotonly-
) and check the Lifecycle field:You can now proceed to build your application in Building the demo app.