Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/auto register runner #46

Merged
merged 19 commits into from
Mar 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Auto register runner
  • Loading branch information
npalm committed Mar 1, 2019
commit bb6d0fed23ae0ef7a77f4a7d161a575858593ca8
95 changes: 34 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,36 @@ resource "aws_iam_service_linked_role" "autoscaling" {

### Configuration GitLab runner token

Currently register a new runner is a manual process. See the GitLab Runner [documentation](https://docs.gitlab.com/runner/register/index.html#docker) for more details.
By default the runner is registered the first time. In previous version this was a manual process. The manual process is still supported but will be removed in future releases. The runner token will be stored in the parameter store.

To register the runner automatically set the variable `gitlab_runner_registration_config["token"]` which you can find in your GitLab project, group or global settings. For a generic runner you find the token in the admin section. By default the runner will be locked to project, not run untagged. Below an example of the configuration map.

```
gitlab_runner_registration_config = {
registration_token = "<registration token>"
tag_list = "<your tags, comma separated"
description = "<some description>"
locked_to_project = "true"
run_untagged = "false"
maximum_timeout = "3600"
}
```

For migration to the new setup, just simply add the runner token to the parameter store. Once the runner is started it will lookup the parameter store for an already register one. If the value is null a new runner will be created.

```sh
docker run -it --rm gitlab/gitlab-runner register
```
# set the following variables, look up the variables in your terraform config.
# see your terraform variables to fill in the vars below.
aws-region=<${var.aws_region}>
token=<runner-token-see-your-gitlab-runner>
parameter-name=<${var.environment}>-<${var.secure_parameter_store_runner_token_key}>

aws ssm put-parameter --overwrite --type SecureString --name "${parameter-name}" --value ${token} --region "${aws-region}"
```
Once you have created the parameter, you have to remove the variable `runners_token` from your config. Then next time your gitlab runner instance is created it look up the token from the paramater store.

Finally the runner still support the manual runner creation, no changes are required. Please keep in mind that this setup will be removed.

Provide the details in the interactive terminal. Once done the token can be found in the GitLab runners section, choose edit to get the token or see the config.toml file.

## Usage

Expand Down Expand Up @@ -111,63 +134,13 @@ module "gitlab-runner" {

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| allow_iam_service_linked_role_creation | Attach policy to runner instance to create service linked roles. | string | `true` | no |
| ami_filter | AMI filter to select the AMI used to host the gitlab runner agent. By default the pattern `amzn-ami-hvm-2018.03*-x86_64-ebs` is used for the name. Currently Amazon Linux 2 `amzn2-ami-hvm-2.0.????????-x86_64-ebs` looks *not* working for this configuration. | list | `<list>` | no |
| ami_owners | A list of owners used to select the AMI for the instance. | list | `<list>` | no |
| aws_region | AWS region. | string | - | yes |
| cache_bucket_prefix | Prefix for s3 cache bucket name. | string | `` | no |
| cache_expiration_days | Number of days before cache objects expires. | string | `1` | no |
| cache_shared | Enables cache sharing between runners, false by default. | string | `false` | no |
| create_runners_iam_instance_profile | | string | `true` | no |
| docker_machine_instance_type | Instance type used for the instances hosting docker-machine. | string | `m4.large` | no |
| docker_machine_options | Additional to set options for docker machien. Each element of the list should be key and value. E.g. '["--amazonec2-zone=a"]' | list | `<list>` | no |
| docker_machine_spot_price_bid | Spot price bid. | string | `0.04` | no |
| docker_machine_user | User name for the user to create spot instances to host docker-machine. | string | `docker-machine` | no |
| docker_machine_version | Version of docker-machine. | string | `0.16.0` | no |
| enable_cloudwatch_logging | Enable or disable the CloudWatch logging. | string | `1` | no |
| environment | A name that identifies the environment, will used as prefix and for tagging. | string | - | yes |
| gitlab_runner_version | Version for the gitlab runner. | string | `11.6.0` | no |
| instance_role_json | Instance role json for the runner agent ec2 instance to override the default. | string | `` | no |
| instance_role_runner_json | Instance role json for the docker machine runners to override the default. | string | `` | no |
| instance_type | Instance type used for the gitlab-runner. | string | `t2.micro` | no |
| runners_concurrent | Concurrent value for the runners, will be used in the runner config.toml | string | `10` | no |
| runners_gitlab_url | URL of the gitlab instance to connect to. | string | - | yes |
| runners_iam_instance_profile_name | IAM instance profile name of the runners, will be used in the runner config.toml | string | `` | no |
| runners_idle_count | Idle count of the runners, will be used in the runner config.toml | string | `0` | no |
| runners_idle_time | Idle time of the runners, will be used in the runner config.toml | string | `600` | no |
| runners_image | Image to run builds, will be used in the runner config.toml | string | `docker:18.03.1-ce` | no |
| runners_limit | Limit for the runners, will be used in the runner config.toml | string | `0` | no |
| runners_machine_iam_instance_profile_name | IAM instance profile name to assign to the spot instance which runs the build. | string | `` | no |
| runners_monitoring | Enable detailed cloudwatch monitoring for spot instances. | string | `false` | no |
| runners_name | Name of the runner, will be used in the runner config.toml | string | - | yes |
| runners_off_peak_idle_count | Off peak idle count of the runners, will be used in the runner config.toml. | string | `0` | no |
| runners_off_peak_idle_time | Off peak idle time of the runners, will be used in the runner config.toml. | string | `0` | no |
| runners_off_peak_periods | Off peak periods of the runners, will be used in the runner config.toml. | string | `` | no |
| runners_off_peak_timezone | Off peak idle time zone of the runners, will be used in the runner config.toml. | string | `` | no |
| runners_output_limit | Set maximum build log size in kilobytes, by default set to 4096 (4MB) | string | `4096` | no |
| runners_post_build_script | Commands to be executed on the Runner just after executing the build, but before executing after_script. | string | `` | no |
| runners_pre_build_script | Script to execute in the pipeline just before the build, will be used in the runner config.toml | string | `` | no |
| runners_pre_clone_script | Commands to be executed on the Runner before cloning the Git repository. this can be used to adjust the Git client configuration first, for example. | string | `` | no |
| runners_privilled | Runners will run in privilled mode, will be used in the runner config.toml | string | `true` | no |
| runners_request_concurrency | Limit number of concurrent requests for new jobs from GitLab (default 1) | string | `1` | no |
| runners_root_size | Runnner instance root size in GB. | string | `16` | no |
| runners_token | Token for the runner, will be used in the runner config.toml | string | - | yes |
| runners_use_private_address | Restrict runners to use only private address | string | `true` | no |
| ssh_public_key | Public SSH key used for the gitlab-runner ec2 instance. | string | - | yes |
| subnet_ids_gitlab_runner | Subnets used for hosting the gitlab-runner. | list | - | yes |
| subnet_id_runners | Subnet used to hosts the docker-machine runners. | string | - | yes |
| tags | Map of tags that will be added to created resources. By default resources will be taggen with name and environemnt. | map | `<map>` | no |
| userdata_post_install | User-data script snippet to insert after gitlab-runner install | string | `` | no |
| userdata_pre_install | User-data script snippet to insert before gitlab-runner install | string | `` | no |
| vpc_id | The VPC that is used for the instances. | string | - | yes |

## Outputs

| Name | Description |
|------|-------------|
| runner_agent_role | ARN of the rule used for the ec2 instance for the GitLab runner agent. |
| runner_as_group_name | Name of the autoscaling group for the gitlab-runner instance |
| runner_cache_bucket_arn | ARN of the S3 for the build cache. |
| aws_region | AWS region. | string | `eu-west-1` | no |
| environment | A name that indentifies the environment, will used as prefix and for taggin. | string | `ci-runners` | no |
| gitlab_url | URL of the gitlab instance to connect to. | string | - | yes |
| private_ssh_key_filename | | string | `generated/id_rsa` | no |
| public_ssh_key_filename | | string | `generated/id_rsa.pub` | no |
| runner_name | Name of the runner, will be used in the runner config.toml | string | - | yes |
| runner_token | Token for the runner, will be used in the runner config.toml | string | - | yes |

## Example

Expand Down
10 changes: 9 additions & 1 deletion examples/runner-public/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,13 @@ module "runner" {

runners_name = "${var.runner_name}"
runners_gitlab_url = "${var.gitlab_url}"
runners_token = "${var.runner_token}"

gitlab_runner_registration_config = {
registration_token = "<ADD YOUR REGISTRATION TOKEN HERE>"
tag_list = "docker.m3"
description = "auto register"
locked_to_project = "true"
run_untagged = "false"
maximum_timeout = "3600"
}
}
43 changes: 36 additions & 7 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,22 @@ data "template_file" "gitlab_runner" {
template = "${file("${path.module}/template/gitlab-runner.tpl")}"

vars {
gitlab_runner_version = "${var.gitlab_runner_version}"
docker_machine_version = "${var.docker_machine_version}"
runners_config = "${data.template_file.runners.rendered}"
runners_executor = "${var.runners_executor}"
pre_install = "${var.userdata_pre_install}"
post_install = "${var.userdata_post_install}"
gitlab_runner_version = "${var.gitlab_runner_version}"
docker_machine_version = "${var.docker_machine_version}"
runners_config = "${data.template_file.runners.rendered}"
runners_executor = "${var.runners_executor}"
pre_install = "${var.userdata_pre_install}"
post_install = "${var.userdata_post_install}"
runners_gitlab_url = "${var.runners_gitlab_url}"
runners_token = "${var.runners_token}"
secure_parameter_store_runner_token_key = "${var.environment}-${var.secure_parameter_store_runner_token_key}"
secure_parameter_store_region = "${var.aws_region}"
gitlab_runner_registration_token = "${var.gitlab_runner_registration_config["registration_token"]}"
giltab_runner_description = "${var.gitlab_runner_registration_config["description"]}"
gitlab_runner_tag_list = "${var.gitlab_runner_registration_config["tag_list"]}"
gitlab_runner_locked_to_project = "${var.gitlab_runner_registration_config["locked_to_project"]}"
gitlab_runner_run_untagged = "${var.gitlab_runner_registration_config["run_untagged"]}"
gitlab_runner_maximum_timeout = "${var.gitlab_runner_registration_config["maximum_timeout"]}"
}
}

Expand Down Expand Up @@ -144,7 +154,6 @@ resource "aws_autoscaling_group" "gitlab_runner_instance" {
name = "${var.environment}-as-group"
vpc_zone_identifier = ["${var.subnet_ids_gitlab_runner}"]

# vpc_zone_identifier = ["${var.subnets}"]
min_size = "1"
max_size = "1"
desired_capacity = "1"
Expand Down Expand Up @@ -263,3 +272,23 @@ resource "aws_iam_role_policy_attachment" "service_linked_role" {
role = "${aws_iam_role.instance.name}"
policy_arn = "${aws_iam_policy.service_linked_role.arn}"
}

################################################################################
### AWS Systems Manager access to store runner token once regsitered
################################################################################
data "template_file" "ssm_policy" {
template = "${file("${path.module}/policies/instance-secure-parameter-role-policy.json")}"
}

resource "aws_iam_policy" "ssm" {
name = "${var.environment}-ssm"
path = "/"
description = "Policy for runner token param access via SSM"

policy = "${data.template_file.ssm_policy.rendered}"
}

resource "aws_iam_role_policy_attachment" "ssm" {
role = "${aws_iam_role.instance.name}"
policy_arn = "${aws_iam_policy.ssm.arn}"
}
19 changes: 19 additions & 0 deletions policies/instance-secure-parameter-role-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:PutParameter"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters"
],
"Resource": "arn:aws:ssm:*"
}
]
}
17 changes: 17 additions & 0 deletions template/gitlab-runner.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@ curl -L https://github.com/docker/machine/releases/download/v${docker_machine_ve
cp /tmp/docker-machine /usr/local/bin/docker-machine && \
ln -s /usr/local/bin/docker-machine /usr/bin/docker-machine


token=$(aws ssm get-parameters --names "${secure_parameter_store_runner_token_key}" --region "${secure_parameter_store_region}" | jq -r ".Parameters | .[0] | .Value")
if [[ `echo ${runners_token}` == "__REPLACED_BY_USER_DATA__" && `echo $token` == "null" ]]
then
token=$(curl --request POST -L "${runners_gitlab_url}/api/v4/runners" \
--form "token=${gitlab_runner_registration_token}" \
--form "tag_list=${gitlab_runner_tag_list}" \
--form "description=${giltab_runner_description}" \
--form "locked=${gitlab_runner_locked_to_project}" \
--form "run_untagged=${gitlab_runner_run_untagged}" \
--form "maximum_timeout=${gitlab_runner_maximum_timeout}" \
| jq -r .token)
aws ssm put-parameter --overwrite --type SecureString --name "${secure_parameter_store_runner_token_key}" --value $token --region "${secure_parameter_store_region}"
fi

sed -i.bak s/__REPLACED_BY_USER_DATA__/`echo $token`/g /etc/gitlab-runner/config.toml

${post_install}

service gitlab-runner restart
Expand Down
6 changes: 6 additions & 0 deletions template/logging.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ log_group_name = ${environment}
datetime_format = %b %d %H:%M:%S
initial_position = start_of_file

[/var/log/user-data.log]
file = /var/log/user-data.log
log_stream_name = {instanceId}/user-data
log_group_name = ${environment}
initial_position = start_of_file

EOF

# Set the region to send CloudWatch Logs data to (the region where the instance is located)
Expand Down
21 changes: 21 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ variable "runners_gitlab_url" {
variable "runners_token" {
description = "Token for the runner, will be used in the runner config.toml"
type = "string"
default = "__REPLACED_BY_USER_DATA__"
}

variable "runners_limit" {
Expand Down Expand Up @@ -266,3 +267,23 @@ variable "ami_owners" {
type = "list"
default = ["amazon"]
}

variable "gitlab_runner_registration_config" {
description = "Configurtion to register the runner. See the README for an example, or the examples."
type = "map"

default = {
registration_token = ""
tag_list = ""
description = ""
locked_to_project = "true"
run_untagged = "false"
maximum_timeout = "3600"
}
}

variable "secure_parameter_store_runner_token_key" {
type = "string"
description = "The key name used store the Gitlab runner token in Secure Paramater Store"
default = "runner-token"
}