From d6c77f9a1cdf88feca2722ad84db755dd5cca193 Mon Sep 17 00:00:00 2001 From: Lee Brown Date: Mon, 15 Jul 2019 01:09:38 -0800 Subject: [PATCH] enable cloudfront for webapp static files --- .gitlab-ci.yml | 2 +- README.md | 202 +--------- resources/saas-starter-kit-deploy-policy.json | 131 +++++++ tools/devops/README.md | 362 +++++++++++------- 4 files changed, 361 insertions(+), 336 deletions(-) create mode 100644 resources/saas-starter-kit-deploy-policy.json diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9a6c0ea..2e1a96e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -88,7 +88,7 @@ webapp:deploy:dev: HOST_NAMES: 'www.eproc.tech,dev.eproc.tech' S3_BUCKET_PRIVATE: 'saas-starter-kit-private' S3_BUCKET_PUBLIC: 'saas-starter-kit-public' - S3_BUCKET_PUBLIC_CLOUDFRONT: 'false' + S3_BUCKET_PUBLIC_CLOUDFRONT: 'true' STATIC_FILES_S3: 'true' STATIC_FILES_IMG_RESIZE: 'true' AWS_USE_ROLE: 'true' diff --git a/README.md b/README.md index 84ae232..d757075 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,10 @@ $ docker-compose down Running `docker-compose down` will properly stop and terminate the Docker Compose session. +Note: None of the containers are setup by default with volumes and all data will be lost with `docker-compose down`. +This is specicaly important to remember regarding the postgres container. If you would like data to be persisted across +builds locally, update `docker-compose.yaml` to define a volume. + ### Re-starting a specific Go service for development @@ -417,202 +421,12 @@ Currently `.gitlab-ci.yaml` only defines jobs for the first three stages. The re so each job is dependant on the previous or run jobs for each target environment independently. A build tool called [devops](https://gitlab.com/geeks-accelerator/oss/saas-starter-kit/tree/master/tools/devops) has -been included apart of this project. Devops handles creating AWS resources and deploying your services with minimal additional -configuration. You can customizing any of the configuration in the code. While AWS is already a core part of the -saas-starter-kit, keeping the deployment in GoLang limits the scope of additional technologies required to get your +been included apart of this project. _Devops_ handles creating AWS resources and deploying your services with minimal +additional configuration. You can customizing any of the configuration in the code. While AWS is already a core part of +the saas-starter-kit, keeping the deployment in GoLang limits the scope of additional technologies required to get your project successfully up and running. If you understand Golang, then you will be a master at devops with this tool. -The project includes a Postgres database which adds an additional resource dependency when deploying the -project. It is important to know that the tasks running schema migration for the Postgres database can not run as shared -GitLab Runners since they will be outside the deployment AWS VPC. There are two options here: -1. Enable the AWS RDS database to be publicly available (not recommended). -2. Run your own GitLab runners inside the same AWS VPC and grant access for them to communicate with the database. - -This project has opted to implement option 2 and thus setting up the deployment pipeline requires a few more additional steps. - -Note that using shared runners hosted by GitLab also requires AWS credentials to be input into GitLab for configuration. - -Hosted your own GitLab runners uses AWS Roles instead of hardcoding the access key ID and secret access key in GitLab and -in other configuration files. And since this project is open-source, we wanted to avoid sharing our AWS credentials. - -If you don't have an AWS account, signup for one now and then proceed with the deployment setup. - -### Setup GitLab CI / CD - -Below outlines the basic steps to setup [Autoscaling GitLab Runner on AWS](https://docs.gitlab.com/runner/configuration/runner_autoscale_aws/). - -1. Define an [AWS IAM Role](https://console.aws.amazon.com/iam/home?region=us-west-2#/roles$new?step=type) that will be -attached to the GitLab Runner instances. The role will need permission to scale (EC2), update the cache (via S3) and -perform the project specific deployment commands. - ``` - Trusted Entity: AWS Service - Service that will use this role: EC2 - Attach permissions policies: AmazonEC2FullAccess, AmazonS3FullAccess, saas-starter-kit-deploy - Role Name: SaasStarterKitEc2RoleForGitLabRunner - Role Description: Allows GitLab runners hosted on EC2 instances to call AWS services on your behalf. - ``` - -2. Launch a new [AWS EC2 Instance](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#LaunchInstanceWizard). -`GitLab Runner` will be installed on this instance and will serve as the bastion that spawns new instances. This -instance will be a dedicated host since we need it always up and running, thus it will be the standard costs apply. - - Note: Since this machine will not run any jobs itself, it does not need to be very powerful. A t2.micro instance will be sufficient. - ``` - Amazon Machine Image (AMI): Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type - ami-0f2176987ee50226e - Instance Type: t2.micro - ``` - -3. Configure Instance Details. - - Note: Do not forget to select the IAM Role _SaasStarterKitEc2RoleForGitLabRunner_ - ``` - Number of instances: 1 - Network: default VPC - Subnet: no Preference - Auto-assign Public IP: Use subnet setting (Enable) - Placement Group: not checked/disabled - Capacity Reservation: Open - IAM Role: SaasStarterKitEc2RoleForGitLabRunner - Shutdown behavior: Stop - Enable termination project: checked/enabled - Monitoring: not checked/disabled - Tenancy: Shared - Elastic Interence: not checked/disabled - T2/T3 Unlimited: not checked/disabled - Advanced Details: none - ``` - -4. Add Storage. Increase the volume size for the root device to 100 GiB. - ``` - Volume Type | Device | Size (GiB) | Volume Type - Root | /dev/xvda | 100 | General Purpose SSD (gp2) - ``` - -5. Add Tags. - ``` - Name: gitlab-runner - ``` - -6. Configure Security Group. Create a new security group with the following details: - ``` - Name: gitlab-runner - Description: Gitlab runners for running CICD. - Rules: - Type | Protocol | Port Range | Source | Description - SSH | TCP | 22 | My IP | SSH access for setup. - ``` - -7. Review and Launch instance. Select an existing key pair or create a new one. This will be used to SSH into the - instance for additional configuration. - -8. Update the security group to reference itself. The instances need to be able to communicate between each other. - - Navigate to edit the security group and add the following two rules where `SECURITY_GROUP_ID` is replaced with the - name of the security group created in step 6. - ``` - Rules: - Type | Protocol | Port Range | Source | Description - Custom TCP | TCP | 2376 | SECURITY_GROUP_ID | Gitlab runner for Docker Machine to communicate with Docker daemon. - SSH | TCP | 22 | SECURITY_GROUP_ID | SSH access for setup. - ``` - -8. SSH into the newly created instance. - - ```bash - ssh -i ~/saas-starter-kit-uswest2-gitlabrunner.pem ec2-user@ec2-52-36-105-172.us-west-2.compute.amazonaws.com - ``` - Note: If you get the error `Permissions 0666 are too open`, then you will need to `chmod 400 FILENAME` - -9. Install GitLab Runner from the [official GitLab repository](https://docs.gitlab.com/runner/install/linux-repository.html) - ```bash - curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash - sudo yum install gitlab-runner - ``` - -10. [Install Docker Community Edition](https://docs.docker.com/install/). - ```bash - sudo yum install docker - ``` - -11. [Install Docker Machine](https://docs.docker.com/machine/install-machine/). - ```bash - base=https://github.com/docker/machine/releases/download/v0.16.0 && - curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine && - sudo install /tmp/docker-machine /usr/sbin/docker-machine - ``` - -12. [Register the runner](https://docs.gitlab.com/runner/register/index.html). - ```bash - sudo gitlab-runner register - ``` - Notes: - * When asked for gitlab-ci tags, enter `master,dev,dev-*` - * This will limit commits to the master or dev branches from triggering the pipeline to run. This includes a - wildcard for any branch named with the prefix `dev-`. - * When asked the executor type, enter `docker+machine` - * When asked for the default Docker image, enter `geeksaccelerator/docker-library:golang1.12-docker` - -13. [Configuring the GitLab Runner](https://docs.gitlab.com/runner/configuration/runner_autoscale_aws/#configuring-the-gitlab-runner) - - ```bash - sudo vim /etc/gitlab-runner/config.toml - ``` - - Update the `[runners.docker]` configuration section in `config.toml` to match the example below replacing the - obvious placeholder `XXXXX` with the relevant value. - ```yaml - [runners.docker] - tls_verify = false - image = "geeksaccelerator/docker-library:golang1.12-docker" - privileged = true - disable_entrypoint_overwrite = false - oom_kill_disable = false - disable_cache = true - volumes = ["/cache"] - shm_size = 0 - [runners.cache] - Type = "s3" - Shared = true - [runners.cache.s3] - ServerAddress = "s3.us-west-2.amazonaws.com" - BucketName = "XXXXX" - BucketLocation = "us-west-2" - [runners.machine] - IdleCount = 0 - IdleTime = 1800 - MachineDriver = "amazonec2" - MachineName = "gitlab-runner-machine-%s" - MachineOptions = [ - "amazonec2-iam-instance-profile=SaasStarterKitEc2RoleForGitLabRunner", - "amazonec2-region=us-west-2", - "amazonec2-vpc-id=XXXXX", - "amazonec2-subnet-id=XXXXX", - "amazonec2-zone=d", - "amazonec2-use-private-address=true", - "amazonec2-tags=runner-manager-name,gitlab-aws-autoscaler,gitlab,true,gitlab-runner-autoscale,true", - "amazonec2-security-group=gitlab-runner", - "amazonec2-instance-type=t2.large" - ] - ``` - - You will need use the same VPC subnet and availability zone as the instance launched in step 2. We are using AWS - region `us-west-2`. The _ServerAddress_ for S3 will need to be updated if the region is changed. For `us-east-1` the - _ServerAddress_ is `s3.amazonaws.com`. Under MachineOptions you can add anything that the [AWS Docker Machine](https://docs.docker.com/machine/drivers/aws/#options) - driver supports. - - Below are some example values for the placeholders to ensure for format of your values are correct. - ```yaml - BucketName = saas-starter-kit-usw - amazonec2-vpc-id=vpc-5f43f027 - amazonec2-subnet-id=subnet-693d3110 - amazonec2-zone=a - ``` - - Once complete, restart the runner. - ```bash - sudo gitlab-runner restart - ``` - +Refer to the [README](https://gitlab.com/geeks-accelerator/oss/saas-starter-kit/blob/master/tools/devops/README.md) for setup details. ## Development Notes diff --git a/resources/saas-starter-kit-deploy-policy.json b/resources/saas-starter-kit-deploy-policy.json new file mode 100644 index 0000000..83ff4af --- /dev/null +++ b/resources/saas-starter-kit-deploy-policy.json @@ -0,0 +1,131 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ServiceDeployPermissions", + "Effect": "Allow", + "Action": [ + "acm:ListCertificates", + "acm:RequestCertificate", + "acm:DescribeCertificate", + "cloudfront:CreateDistribution", + "ec2:DescribeSubnets", + "ec2:DescribeSecurityGroups", + "ec2:CreateSecurityGroup", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeVpcs", + "ec2:CreateVpc", + "ec2:CreateSubnet", + "ec2:DescribeVpcs", + "ec2:DescribeInternetGateways", + "ec2:CreateInternetGateway", + "ec2:CreateTags", + "ec2:CreateRouteTable", + "ec2:DescribeRouteTables", + "ec2:CreateRoute", + "ec2:AttachInternetGateway", + "ec2:DescribeAccountAttributes", + "elasticache:DescribeCacheClusters", + "elasticache:CreateCacheCluster", + "elasticache:DescribeCacheParameterGroups", + "elasticache:CreateCacheParameterGroup", + "elasticache:ModifyCacheCluster", + "elasticache:ModifyCacheParameterGroup", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:CreateTargetGroup", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "ecs:CreateCluster", + "ecs:CreateService", + "ecs:DeleteService", + "ecs:DescribeClusters", + "ecs:DescribeServices", + "ecs:UpdateService", + "ecs:RegisterTaskDefinition", + "ecs:ListTaskDefinitions", + "ecr:BatchCheckLayerAvailability", + "ecr:BatchDeleteImage", + "ecr:GetAuthorizationToken", + "ecr:DescribeImages", + "ecr:DescribeRepositories", + "ecs:DescribeTasks", + "ecr:CreateRepository", + "ecr:ListImages", + "ecs:ListTasks", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + "logs:DescribeLogGroups", + "logs:CreateLogGroup", + "lambda:ListFunctions", + "lambda:CreateFunction", + "lambda:UpdateFunctionCode", + "lambda:UpdateFunctionConfiguration", + "iam:GetRole", + "iam:PassRole", + "iam:CreateRole", + "iam:CreateServiceLinkedRole", + "iam:CreatePolicy", + "iam:PutRolePolicy", + "iam:TagRole", + "iam:AttachRolePolicy", + "iam:ListPolicies", + "iam:GetPolicyVersion", + "iam:CreatePolicyVersion", + "logs:DescribeLogGroups", + "logs:CreateLogGroup", + "logs:DescribeLogStreams", + "logs:CreateExportTask", + "logs:DescribeExportTasks", + "rds:CreateDBCluster", + "rds:CreateDBInstance", + "rds:DescribeDBClusters", + "rds:DescribeDBInstances", + "s3:CreateBucket", + "s3:DeleteObject", + "s3:DeleteObjectVersion", + "s3:GetBucketPublicAccessBlock", + "s3:GetBucketAcl", + "s3:HeadBucket", + "s3:ListObjects", + "s3:ListBucket", + "s3:GetObject", + "s3:PutLifecycleConfiguration", + "s3:PutBucketCORS", + "s3:PutBucketPolicy", + "s3:PutBucketPublicAccessBlock", + "route53:CreateHostedZone", + "route53:ChangeResourceRecordSets", + "route53:ListHostedZones", + "secretsmanager:CreateSecret", + "secretsmanager:ListSecrets", + "secretsmanager:GetSecretValue", + "secretsmanager:UpdateSecret", + "secretsmanager:RestoreSecret", + "secretsmanager:DeleteSecret", + "servicediscovery:ListNamespaces", + "servicediscovery:CreatePrivateDnsNamespace", + "servicediscovery:GetOperation", + "servicediscovery:ListServices", + "servicediscovery:CreateService", + "servicediscovery:GetService" + ], + "Resource": "*" + }, + { + "Action": "iam:CreateServiceLinkedRole", + "Effect": "Allow", + "Resource": "arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS", + "Condition": { + "StringLike": { + "iam:AWSServiceName":"rds.amazonaws.com" + } + } + } + ] +} \ No newline at end of file diff --git a/tools/devops/README.md b/tools/devops/README.md index 20c5544..540e8c3 100644 --- a/tools/devops/README.md +++ b/tools/devops/README.md @@ -1,150 +1,230 @@ +# SaaS Starter Kit -1. Create new policy `saas-starter-kit-deploy` with the following permissions. -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "ServiceDeployPermissions", - "Effect": "Allow", - "Action": [ - "acm:ListCertificates", - "acm:RequestCertificate", - "acm:DescribeCertificate", - "cloudfront:CreateDistribution", - "ec2:DescribeSubnets", - "ec2:DescribeSecurityGroups", - "ec2:CreateSecurityGroup", - "ec2:AuthorizeSecurityGroupIngress", - "ec2:DescribeNetworkInterfaces", - "ec2:DescribeVpcs", - "ec2:CreateVpc", - "ec2:CreateSubnet", - "ec2:DescribeVpcs", - "ec2:DescribeInternetGateways", - "ec2:CreateInternetGateway", - "ec2:CreateTags", - "ec2:CreateRouteTable", - "ec2:DescribeRouteTables", - "ec2:CreateRoute", - "ec2:AttachInternetGateway", - "ec2:DescribeAccountAttributes", - "elasticache:DescribeCacheClusters", - "elasticache:CreateCacheCluster", - "elasticache:DescribeCacheParameterGroups", - "elasticache:CreateCacheParameterGroup", - "elasticache:ModifyCacheCluster", - "elasticache:ModifyCacheParameterGroup", - "elasticloadbalancing:DescribeLoadBalancers", - "elasticloadbalancing:CreateLoadBalancer", - "elasticloadbalancing:CreateListener", - "elasticloadbalancing:DescribeTargetGroups", - "elasticloadbalancing:CreateTargetGroup", - "elasticloadbalancing:DescribeListeners", - "elasticloadbalancing:ModifyTargetGroupAttributes", - "ecs:CreateCluster", - "ecs:CreateService", - "ecs:DeleteService", - "ecs:DescribeClusters", - "ecs:DescribeServices", - "ecs:UpdateService", - "ecs:RegisterTaskDefinition", - "ecs:ListTaskDefinitions", - "ecr:BatchCheckLayerAvailability", - "ecr:BatchDeleteImage", - "ecr:GetAuthorizationToken", - "ecr:DescribeImages", - "ecr:DescribeRepositories", - "ecs:DescribeTasks", - "ecr:CreateRepository", - "ecr:ListImages", - "ecs:ListTasks", - "ecr:PutImage", - "ecr:InitiateLayerUpload", - "ecr:UploadLayerPart", - "ecr:CompleteLayerUpload", - "logs:DescribeLogGroups", - "logs:CreateLogGroup", - "lambda:ListFunctions", - "lambda:CreateFunction", - "lambda:UpdateFunctionCode", - "lambda:UpdateFunctionConfiguration", - "iam:GetRole", - "iam:PassRole", - "iam:CreateRole", - "iam:CreateServiceLinkedRole", - "iam:CreatePolicy", - "iam:PutRolePolicy", - "iam:TagRole", - "iam:AttachRolePolicy", - "iam:ListPolicies", - "iam:GetPolicyVersion", - "iam:CreatePolicyVersion", - "logs:DescribeLogGroups", - "logs:CreateLogGroup", - "logs:DescribeLogStreams", - "logs:CreateExportTask", - "logs:DescribeExportTasks", - "rds:CreateDBCluster", - "rds:CreateDBInstance", - "rds:DescribeDBClusters", - "rds:DescribeDBInstances", - "s3:CreateBucket", - "s3:DeleteObject", - "s3:DeleteObjectVersion", - "s3:GetBucketPublicAccessBlock", - "s3:GetBucketAcl", - "s3:HeadBucket", - "s3:ListObjects", - "s3:ListBucket", - "s3:GetObject", - "s3:PutLifecycleConfiguration", - "s3:PutBucketCORS", - "s3:PutBucketPolicy", - "s3:PutBucketPublicAccessBlock", - "route53:CreateHostedZone", - "route53:ChangeResourceRecordSets", - "route53:ListHostedZones", - "secretsmanager:CreateSecret", - "secretsmanager:ListSecrets", - "secretsmanager:GetSecretValue", - "secretsmanager:UpdateSecret", - "secretsmanager:RestoreSecret", - "secretsmanager:DeleteSecret", - "servicediscovery:ListNamespaces", - "servicediscovery:CreatePrivateDnsNamespace", - "servicediscovery:GetOperation", - "servicediscovery:ListServices", - "servicediscovery:CreateService", - "servicediscovery:GetService" - ], - "Resource": "*" - }, - { - "Action": "iam:CreateServiceLinkedRole", - "Effect": "Allow", - "Resource": "arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS", - "Condition": { - "StringLike": { - "iam:AWSServiceName":"rds.amazonaws.com" - } - } - } - ] -} -``` +Copyright 2019, Geeks Accelerator +twins@geeksaccelerator.com -2. Create new user `saas-starter-kit-deploy` with _Programmatic Access_ and _Attach existing policies directly_ with the policy created from step 1 `saas-starter-kit-deploy` -3. Try running the deploy +## Description + +_Devops_ handles creating AWS resources and deploying your services with minimal +additional configuration. You can customizing any of the configuration in the code. While AWS is already a core part of +the saas-starter-kit, keeping the deployment in GoLang limits the scope of additional technologies required to get your +project successfully up and running. If you understand Golang, then you will be a master at devops with this tool. + +The project includes a Postgres database which adds an additional resource dependency when deploying the +project. It is important to know that the tasks running schema migration for the Postgres database can not run as shared +GitLab Runners since they will be outside the deployment AWS VPC. There are two options here: +1. Enable the AWS RDS database to be publicly available (not recommended). +2. Run your own GitLab runners inside the same AWS VPC and grant access for them to communicate with the database. + +This project has opted to implement option 2 and thus setting up the deployment pipeline requires a few more additional steps. + +Note that using shared runners hosted by GitLab also requires AWS credentials to be input into GitLab for configuration. + +Hosted your own GitLab runners uses AWS Roles instead of hardcoding the access key ID and secret access key in GitLab and +in other configuration files. And since this project is open-source, we wanted to avoid sharing our AWS credentials. + +If you don't have an AWS account, signup for one now and then proceed with the deployment setup. + + +## Getting Started + +You can run the both commands `build` and `deploy` locally after setting up the initial +AWS permissions. + +1. You will need an existing AWS account or create a new AWS account. + +2. Define a new [AWS IAM Policy](https://console.aws.amazon.com/iam/home?region=us-west-2#/policies$new?step=edit) +called `saas-starter-kit-deploy` with a defined JSON statement instead of using the visual +editor. The statement is rather large as each permission is granted individually. A copy of +the statement is stored in the repo at +[resources/saas-starter-kit-deploy-policy.json](https://gitlab.com/geeks-accelerator/oss/saas-starter-kit/blob/master/resources/saas-starter-kit-deploy-policy.json) + +3. Create new [AWS User](https://console.aws.amazon.com/iam/home?region=us-west-2#/users$new?step=details) +called `saas-starter-kit-deploy` with _Programmatic Access_ and _Attach existing policies directly_ with the policy +created from step 1 `saas-starter-kit-deploy` + +4. Try running the deploy ```bash go run main.go deploy -service=web-api -env=dev ``` -Or -```bash -go run main.go deploy -service=web-api -env=dev -enable_https=true -primary_host=eproc.tech -host_names=www.eproc.tech -host_names=api.eproc.tech -recreate_service=false -``` +Note: This user created is only for development purposes and is not needed for the build +pipeline using GitLab CI / CD. + + +## Setup GitLab CI / CD +Below outlines the basic steps to setup [Autoscaling GitLab Runner on AWS](https://docs.gitlab.com/runner/configuration/runner_autoscale_aws/). - \ No newline at end of file +1. Define an [AWS IAM Role](https://console.aws.amazon.com/iam/home?region=us-west-2#/roles$new?step=type) that will be +attached to the GitLab Runner instances. The role will need permission to scale (EC2), update the cache (via S3) and +perform the project specific deployment commands. + ``` + Trusted Entity: AWS Service + Service that will use this role: EC2 + Attach permissions policies: AmazonEC2FullAccess, AmazonS3FullAccess, saas-starter-kit-deploy + Role Name: SaasStarterKitEc2RoleForGitLabRunner + Role Description: Allows GitLab runners hosted on EC2 instances to call AWS services on your behalf. + ``` + +2. Launch a new [AWS EC2 Instance](https://us-west-2.console.aws.amazon.com/ec2/v2/home?region=us-west-2#LaunchInstanceWizard). +`GitLab Runner` will be installed on this instance and will serve as the bastion that spawns new instances. This +instance will be a dedicated host since we need it always up and running, thus it will be the standard costs apply. + + Note: Since this machine will not run any jobs itself, it does not need to be very powerful. A t2.micro instance will be sufficient. + ``` + Amazon Machine Image (AMI): Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type - ami-0f2176987ee50226e + Instance Type: t2.micro + ``` + +3. Configure Instance Details. + + Note: Do not forget to select the IAM Role _SaasStarterKitEc2RoleForGitLabRunner_ + ``` + Number of instances: 1 + Network: default VPC + Subnet: no Preference + Auto-assign Public IP: Use subnet setting (Enable) + Placement Group: not checked/disabled + Capacity Reservation: Open + IAM Role: SaasStarterKitEc2RoleForGitLabRunner + Shutdown behavior: Stop + Enable termination project: checked/enabled + Monitoring: not checked/disabled + Tenancy: Shared + Elastic Interence: not checked/disabled + T2/T3 Unlimited: not checked/disabled + Advanced Details: none + ``` + +4. Add Storage. Increase the volume size for the root device to 100 GiB. + ``` + Volume Type | Device | Size (GiB) | Volume Type + Root | /dev/xvda | 100 | General Purpose SSD (gp2) + ``` + +5. Add Tags. + ``` + Name: gitlab-runner + ``` + +6. Configure Security Group. Create a new security group with the following details: + ``` + Name: gitlab-runner + Description: Gitlab runners for running CICD. + Rules: + Type | Protocol | Port Range | Source | Description + SSH | TCP | 22 | My IP | SSH access for setup. + ``` + +7. Review and Launch instance. Select an existing key pair or create a new one. This will be used to SSH into the + instance for additional configuration. + +8. Update the security group to reference itself. The instances need to be able to communicate between each other. + + Navigate to edit the security group and add the following two rules where `SECURITY_GROUP_ID` is replaced with the + name of the security group created in step 6. + ``` + Rules: + Type | Protocol | Port Range | Source | Description + Custom TCP | TCP | 2376 | SECURITY_GROUP_ID | Gitlab runner for Docker Machine to communicate with Docker daemon. + SSH | TCP | 22 | SECURITY_GROUP_ID | SSH access for setup. + ``` + +8. SSH into the newly created instance. + + ```bash + ssh -i ~/saas-starter-kit-uswest2-gitlabrunner.pem ec2-user@ec2-52-36-105-172.us-west-2.compute.amazonaws.com + ``` + Note: If you get the error `Permissions 0666 are too open`, then you will need to `chmod 400 FILENAME` + +9. Install GitLab Runner from the [official GitLab repository](https://docs.gitlab.com/runner/install/linux-repository.html) + ```bash + curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash + sudo yum install gitlab-runner + ``` + +10. [Install Docker Community Edition](https://docs.docker.com/install/). + ```bash + sudo yum install docker + ``` + +11. [Install Docker Machine](https://docs.docker.com/machine/install-machine/). + ```bash + base=https://github.com/docker/machine/releases/download/v0.16.0 && + curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine && + sudo install /tmp/docker-machine /usr/sbin/docker-machine + ``` + +12. [Register the runner](https://docs.gitlab.com/runner/register/index.html). + ```bash + sudo gitlab-runner register + ``` + Notes: + * When asked for gitlab-ci tags, enter `master,dev,dev-*` + * This will limit commits to the master or dev branches from triggering the pipeline to run. This includes a + wildcard for any branch named with the prefix `dev-`. + * When asked the executor type, enter `docker+machine` + * When asked for the default Docker image, enter `geeksaccelerator/docker-library:golang1.12-docker` + +13. [Configuring the GitLab Runner](https://docs.gitlab.com/runner/configuration/runner_autoscale_aws/#configuring-the-gitlab-runner) + + ```bash + sudo vim /etc/gitlab-runner/config.toml + ``` + + Update the `[runners.docker]` configuration section in `config.toml` to match the example below replacing the + obvious placeholder `XXXXX` with the relevant value. + ```yaml + [runners.docker] + tls_verify = false + image = "geeksaccelerator/docker-library:golang1.12-docker" + privileged = true + disable_entrypoint_overwrite = false + oom_kill_disable = false + disable_cache = true + volumes = ["/cache"] + shm_size = 0 + [runners.cache] + Type = "s3" + Shared = true + [runners.cache.s3] + ServerAddress = "s3.us-west-2.amazonaws.com" + BucketName = "XXXXX" + BucketLocation = "us-west-2" + [runners.machine] + IdleCount = 0 + IdleTime = 1800 + MachineDriver = "amazonec2" + MachineName = "gitlab-runner-machine-%s" + MachineOptions = [ + "amazonec2-iam-instance-profile=SaasStarterKitEc2RoleForGitLabRunner", + "amazonec2-region=us-west-2", + "amazonec2-vpc-id=XXXXX", + "amazonec2-subnet-id=XXXXX", + "amazonec2-zone=d", + "amazonec2-use-private-address=true", + "amazonec2-tags=runner-manager-name,gitlab-aws-autoscaler,gitlab,true,gitlab-runner-autoscale,true", + "amazonec2-security-group=gitlab-runner", + "amazonec2-instance-type=t2.large" + ] + ``` + + You will need use the same VPC subnet and availability zone as the instance launched in step 2. We are using AWS + region `us-west-2`. The _ServerAddress_ for S3 will need to be updated if the region is changed. For `us-east-1` the + _ServerAddress_ is `s3.amazonaws.com`. Under MachineOptions you can add anything that the [AWS Docker Machine](https://docs.docker.com/machine/drivers/aws/#options) + driver supports. + + Below are some example values for the placeholders to ensure for format of your values are correct. + ```yaml + BucketName = saas-starter-kit-usw + amazonec2-vpc-id=vpc-5f43f027 + amazonec2-subnet-id=subnet-693d3110 + amazonec2-zone=a + ``` + + Once complete, restart the runner. + ```bash + sudo gitlab-runner restart + ``` \ No newline at end of file