diff --git a/CHANGELOG.md b/CHANGELOG.md index f1ed3d6d8..54b59d048 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## 4.14.0 - 2020-04094 +- Add: Allow traffic from a list of security group IDs (#207) by @fliphess +- Bugfix: Fix missing policy for existing cache (#208, #206) + + ## 4.13.0 - 2020-03-26 - Add: variables `cache_lifecycle_prefix` and `cache_lifecycle_clear` to increase flexibility of the cache usages. - Add: Parametrize the AWS ARN for policies (#203) @ericamador @@ -291,7 +296,9 @@ Module is available as Terraform 0.11 module, pin module to version 3.x. Please - Update default AMI's to The latest Amazon Linux AMI 2017.09.1 - released on 2018-01-17. - Minor updates in the example -[Unreleased]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.12.0...HEAD +[Unreleased]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.14.0...HEAD +[4.13.0]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.14.0...4.13.0 +[4.13.0]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.13.0...4.12.0 [4.12.0]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.12.0...4.11.1 [4.11.1]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.11.1...4.11.0 [4.11.0]: https://github.com/npalm/terraform-aws-gitlab-runner/compare/4.11.0...4.10.0 diff --git a/_docs/TF_MODULE.md b/_docs/TF_MODULE.md index 25046d460..bc69485c2 100644 --- a/_docs/TF_MODULE.md +++ b/_docs/TF_MODULE.md @@ -40,7 +40,8 @@ | enable\_schedule | Flag used to enable/disable auto scaling group schedule for the runner instance. | `bool` | `false` | no | | environment | A name that identifies the environment, used as prefix and for tagging. | `string` | n/a | yes | | gitlab\_runner\_registration\_config | Configuration used to register the runner. See the README for an example, or reference the examples in the examples directory of this repo. | `map(string)` |
{| no | -| gitlab\_runner\_ssh\_cidr\_blocks | List of CIDR blocks to allow SSH Access to the gitlab runner instance. | `list(string)` |
"access_level": "",
"description": "",
"locked_to_project": "",
"maximum_timeout": "",
"registration_token": "",
"run_untagged": "",
"tag_list": ""
}
[| no | +| gitlab\_runner\_ssh\_cidr\_blocks | List of CIDR blocks to allow SSH Access to the gitlab runner instance. | `list(string)` |
"0.0.0.0/0"
]
[| no | +| gitlab\_runner\_security\_group\_ids | List of security group IDs to allow Access to the gitlab runner instances. | `list(string)` |
]
[` | no | | gitlab\_runner\_version | Version of the GitLab runner. | `string` | `"12.8.0"` | no | | instance\_role\_json | Default runner instance override policy, expected to be in JSON format. | `string` | `""` | no | | instance\_type | Instance type used for the GitLab runner. | `string` | `"t3.micro"` | no | diff --git a/bin/remove-runner.sh b/bin/remove-runner.sh old mode 100644 new mode 100755 diff --git a/examples/runner-default/_docs/README.md b/examples/runner-default/_docs/README.md index f625b706d..b63e09754 100644 --- a/examples/runner-default/_docs/README.md +++ b/examples/runner-default/_docs/README.md @@ -7,6 +7,7 @@ This examples shows: - No SSH keys, you can log into the instance via SSM (Session Manager). - Registration via GitLab token. - Auto scaling using `docker+machine` executor. +- Addtional security groups that are allowed access to the runner agent ![runners-default](https://github.com/npalm/assets/raw/master/images/terraform-aws-gitlab-runner/runner-default.png) diff --git a/examples/runner-default/main.tf b/examples/runner-default/main.tf index 2490e023e..218379457 100644 --- a/examples/runner-default/main.tf +++ b/examples/runner-default/main.tf @@ -2,6 +2,10 @@ data "aws_availability_zones" "available" { state = "available" } +data "aws_security_group" "default" { + name = "default" +} + module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "2.21" @@ -37,6 +41,8 @@ module "runner" { enable_runner_ssm_access = true enable_eip = true + gitlab_runner_security_group_ids = [data.aws_security_group.default.id] + docker_machine_spot_price_bid = "0.06" gitlab_runner_registration_config = { diff --git a/main.tf b/main.tf index 87a6a22bc..0d6b0876d 100644 --- a/main.tf +++ b/main.tf @@ -6,133 +6,6 @@ resource "aws_key_pair" "key" { public_key = var.ssh_public_key } -resource "aws_security_group" "runner" { - name_prefix = "${var.environment}-security-group" - vpc_id = var.vpc_id - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - tags = merge( - local.tags, - { - "Name" = format("%s", local.name_sg) - }, - ) -} - -resource "aws_security_group_rule" "runner_ssh" { - count = var.enable_gitlab_runner_ssh_access ? 1 : 0 - - type = "ingress" - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = var.gitlab_runner_ssh_cidr_blocks - - security_group_id = aws_security_group.runner.id -} - -resource "aws_security_group_rule" "runner_ping" { - count = var.enable_ping ? 1 : 0 - - type = "ingress" - from_port = -1 - to_port = -1 - protocol = "icmp" - cidr_blocks = var.gitlab_runner_ssh_cidr_blocks - - security_group_id = aws_security_group.runner.id -} - -resource "aws_security_group" "docker_machine" { - name_prefix = "${var.environment}-docker-machine" - vpc_id = var.vpc_id - - tags = merge( - local.tags, - { - "Name" = format("%s", local.name_sg) - }, - ) -} - -resource "aws_security_group_rule" "docker_machine_docker_runner" { - type = "ingress" - from_port = 2376 - to_port = 2376 - protocol = "tcp" - source_security_group_id = aws_security_group.runner.id - - security_group_id = aws_security_group.docker_machine.id -} - -resource "aws_security_group_rule" "docker_machine_docker_self" { - type = "ingress" - from_port = 2376 - to_port = 2376 - protocol = "tcp" - self = true - - security_group_id = aws_security_group.docker_machine.id -} - -resource "aws_security_group_rule" "docker_machine_ssh_runner" { - type = "ingress" - from_port = 22 - to_port = 22 - protocol = "tcp" - source_security_group_id = aws_security_group.runner.id - - security_group_id = aws_security_group.docker_machine.id -} - -resource "aws_security_group_rule" "docker_machine_ping_runner" { - count = var.enable_ping ? 1 : 0 - type = "ingress" - from_port = -1 - to_port = -1 - protocol = "icmp" - source_security_group_id = aws_security_group.runner.id - - security_group_id = aws_security_group.docker_machine.id -} - -resource "aws_security_group_rule" "docker_machine_ssh_self" { - type = "ingress" - from_port = 22 - to_port = 22 - protocol = "tcp" - self = true - - security_group_id = aws_security_group.docker_machine.id -} - -resource "aws_security_group_rule" "docker_machine_ping_self" { - count = var.enable_ping ? 1 : 0 - type = "ingress" - from_port = -1 - to_port = -1 - protocol = "icmp" - self = true - - security_group_id = aws_security_group.docker_machine.id -} - -resource "aws_security_group_rule" "out_all" { - type = "egress" - from_port = 0 - to_port = 65535 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - - security_group_id = aws_security_group.docker_machine.id -} - # Parameter value is managed by the user-data script of the gitlab runner instance resource "aws_ssm_parameter" "runner_registration_token" { name = local.secure_parameter_store_runner_token_key @@ -451,7 +324,7 @@ resource "aws_iam_role_policy_attachment" "instance_session_manager_aws_managed" ### Policy for the docker machine instance to access cache ################################################################################ resource "aws_iam_role_policy_attachment" "docker_machine_cache_instance" { - count = var.cache_bucket["create"] ? 1 : 0 + count = var.cache_bucket["create"] || var.cache_bucket["policy"] != "" ? 1 : 0 role = aws_iam_role.instance.name policy_arn = local.bucket_policy } diff --git a/security_groups.tf b/security_groups.tf new file mode 100644 index 000000000..ad1c99ab7 --- /dev/null +++ b/security_groups.tf @@ -0,0 +1,269 @@ +######################################## +## Gitlab-runner agent security group ## +######################################## + +resource "aws_security_group" "runner" { + name_prefix = "${var.environment}-security-group" + vpc_id = var.vpc_id + description = "A security group containing gitlab-runner agent instances" + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = merge( + local.tags, + { + "Name" = format("%s", local.name_sg) + }, + ) +} + +######################################## +## CIDR ranges to runner agent ## +######################################## + +# Allow SSH traffic from allowed cidr blocks to gitlab-runner agent instances +resource "aws_security_group_rule" "runner_ssh" { + count = length(var.gitlab_runner_ssh_cidr_blocks) > 0 && var.enable_gitlab_runner_ssh_access ? length(var.gitlab_runner_ssh_cidr_blocks) : 0 + + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + + cidr_blocks = [element(var.gitlab_runner_ssh_cidr_blocks, count.index)] + security_group_id = aws_security_group.runner.id + + description = format( + "Allow SSH traffic from %s to gitlab-runner agent instances in group %s", + element(var.gitlab_runner_ssh_cidr_blocks, count.index), + aws_security_group.runner.name + ) +} + +# Allow ICMP traffic from allowed cidr blocks to gitlab-runner agent instances +resource "aws_security_group_rule" "runner_ping" { + count = length(var.gitlab_runner_ssh_cidr_blocks) > 0 && var.enable_ping ? length(var.gitlab_runner_ssh_cidr_blocks) : 0 + + type = "ingress" + from_port = -1 + to_port = -1 + protocol = "icmp" + + cidr_blocks = [element(var.gitlab_runner_ssh_cidr_blocks, count.index)] + security_group_id = aws_security_group.runner.id + + description = format( + "Allow ICMP traffic from %s to gitlab-runner agent instances in group %s", + element(var.gitlab_runner_ssh_cidr_blocks, count.index), + aws_security_group.runner.name + ) +} + +######################################## +## Security group IDs to runner agent ## +######################################## + +# Allow SSH traffic from allowed security group IDs to gitlab-runner agent instances +resource "aws_security_group_rule" "runner_ssh_group" { + count = length(var.gitlab_runner_security_group_ids) > 0 && var.enable_gitlab_runner_ssh_access ? length(var.gitlab_runner_security_group_ids) : 0 + + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + + source_security_group_id = element(var.gitlab_runner_security_group_ids, count.index) + security_group_id = aws_security_group.runner.id + + description = format( + "Allow SSH traffic from %s to gitlab-runner agent instances in group %s", + element(var.gitlab_runner_security_group_ids, count.index), + aws_security_group.runner.name + ) +} + +# Allow ICMP traffic from allowed security group IDs to gitlab-runner agent instances +resource "aws_security_group_rule" "runner_ping_group" { + count = length(var.gitlab_runner_security_group_ids) > 0 && var.enable_ping ? length(var.gitlab_runner_security_group_ids) : 0 + + type = "ingress" + from_port = -1 + to_port = -1 + protocol = "icmp" + + source_security_group_id = element(var.gitlab_runner_security_group_ids, count.index) + security_group_id = aws_security_group.runner.id + + description = format( + "Allow ICMP traffic from %s to gitlab-runner agent instances in group %s", + element(var.gitlab_runner_security_group_ids, count.index), + aws_security_group.runner.name + ) +} + +######################################## +## Docker-machine security group ## +######################################## + +resource "aws_security_group" "docker_machine" { + name_prefix = "${var.environment}-docker-machine" + vpc_id = var.vpc_id + description = "A security group containing docker-machine instances" + + tags = merge( + local.tags, + { + "Name" = format("%s", local.name_sg) + }, + ) +} + +######################################## +## Runner agent to docker-machine ## +######################################## + +# Allow docker-machine traffic from gitlab-runner agent instances to docker-machine instances +resource "aws_security_group_rule" "docker_machine_docker_runner" { + type = "ingress" + from_port = 2376 + to_port = 2376 + protocol = "tcp" + + source_security_group_id = aws_security_group.runner.id + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow docker-machine traffic from group %s to docker-machine instances in group %s", + aws_security_group.runner.name, + aws_security_group.docker_machine.name + ) +} + +######################################## +## Security groups to docker-machine ## +######################################## + +# Combine runner security group id and additional security group IDs +locals { + # Always include the runner security group id, add additional if ssh is enabled + security_groups_ssh = var.enable_gitlab_runner_ssh_access && length(var.gitlab_runner_security_group_ids) > 0 ? concat(var.gitlab_runner_security_group_ids, [aws_security_group.runner.id]) : [aws_security_group.runner.id] + + # Only include runner security group id and addtional if ping is enabled + security_groups_ping = var.enable_ping && length(var.gitlab_runner_security_group_ids) > 0 ? concat(var.gitlab_runner_security_group_ids, [aws_security_group.runner.id]) : [] +} + +# Allow SSH traffic from gitlab-runner agent instances and security group IDs to docker-machine instances +resource "aws_security_group_rule" "docker_machine_ssh_runner" { + count = length(local.security_groups_ssh) + + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + + source_security_group_id = element(local.security_groups_ssh, count.index) + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow SSH traffic from %s to docker-machine instances in group %s on port 22", + element(local.security_groups_ssh, count.index), + aws_security_group.docker_machine.name + ) +} + +# Allow ICMP traffic from gitlab-runner agent instances and security group IDs to docker-machine instances +resource "aws_security_group_rule" "docker_machine_ping_runner" { + count = length(local.security_groups_ping) + + type = "ingress" + from_port = -1 + to_port = -1 + protocol = "icmp" + + source_security_group_id = element(local.security_groups_ping, count.index) + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow ICMP traffic from %s to docker-machine instances in group %s", + element(local.security_groups_ping, count.index), + aws_security_group.docker_machine.name + ) +} + +######################################## +## Docker-machine instances to self ## +######################################## + +# Allow docker-machine traffic from docker-machine instances to docker-machine instances on port 2376 +resource "aws_security_group_rule" "docker_machine_docker_self" { + type = "ingress" + from_port = 2376 + to_port = 2376 + protocol = "tcp" + self = true + + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow docker-machine traffic within group %s on port 2376", + aws_security_group.docker_machine.name, + ) +} + +# Allow SSH traffic from docker-machine instances to docker-machine instances on port 22 +resource "aws_security_group_rule" "docker_machine_ssh_self" { + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + self = true + + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow SSH traffic within group %s on port 22", + aws_security_group.docker_machine.name, + ) +} + +# Allow ICMP traffic from docker-machine instances to docker-machine instances +resource "aws_security_group_rule" "docker_machine_ping_self" { + count = var.enable_ping ? 1 : 0 + type = "ingress" + from_port = -1 + to_port = -1 + protocol = "icmp" + self = true + + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow ICMP traffic within group %s", + aws_security_group.docker_machine.name, + ) +} + +######################################## +## Egress Security rules ## +######################################## + +# Allow egress traffic from docker-machine instances +resource "aws_security_group_rule" "out_all" { + type = "egress" + from_port = 0 + to_port = 65535 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + + security_group_id = aws_security_group.docker_machine.id + + description = format( + "Allow egress traffic for group %s", + aws_security_group.docker_machine.name, + ) +} diff --git a/variables.tf b/variables.tf index 129d44e83..e24210e32 100644 --- a/variables.tf +++ b/variables.tf @@ -324,7 +324,13 @@ variable "enable_gitlab_runner_ssh_access" { variable "gitlab_runner_ssh_cidr_blocks" { description = "List of CIDR blocks to allow SSH Access to the gitlab runner instance." type = list(string) - default = ["0.0.0.0/0"] + default = [] +} + +variable "gitlab_runner_security_group_ids" { + description = "A list of security group ids that are allowed to access the gitlab runner agent" + type = list(string) + default = [] } variable "enable_cloudwatch_logging" {
]