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

Create infra code for runners #1

Merged
merged 12 commits into from
Apr 28, 2020
18 changes: 18 additions & 0 deletions examples/default/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
locals {
environment = "default-action-runners"
aws_region = "eu-west-1"
}

module "runners" {
source = "../../"

aws_region = local.aws_region
vpc_id = module.vpc.vpc_id

environment = local.environment
tags = {
Project = "ProjectX"
}

}

5 changes: 5 additions & 0 deletions examples/default/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
output "action_runners" {
value = {
runners = module.runners.runners
}
}
5 changes: 5 additions & 0 deletions examples/default/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
provider "aws" {
region = local.aws_region
version = "2.59"
}

7 changes: 7 additions & 0 deletions examples/default/vpc.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module "vpc" {
source = "git::https://github.com/philips-software/terraform-aws-vpc.git?ref=2.1.0"

environment = local.environment
aws_region = local.aws_region
}

64 changes: 64 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
resource "random_string" "random" {
length = 24
special = false
upper = false
}

module "dsitrubtion_cache" {
source = "./modules/action-runner-binary-cache"

aws_region = var.aws_region
environment = var.environment
tags = var.tags

distribution_bucket_name = "${var.environment}-dist-${random_string.random.result}"
}

module "runners" {
source = "./modules/runners"

aws_region = var.aws_region
vpc_id = var.vpc_id
environment = var.environment
tags = var.tags

s3_location_runner_distribution = module.dsitrubtion_cache.s3_location_runner_distribution
}


resource "aws_iam_policy" "dist_bucket" {
name = "${var.environment}-gh-distribution-bucket"
path = "/"
description = "Policy for the runner to download the github action runner."

policy = templatefile("${path.module}/policies/action-runner-s3-policy.json",
{
s3_arn = module.dsitrubtion_cache.distribution_bucket.arn
}
)
}

resource "aws_iam_role_policy_attachment" "dist_bucket" {
role = module.runners.role.name
policy_arn = aws_iam_policy.dist_bucket.arn
}

resource "aws_resourcegroups_group" "resourcegroups_group" {
name = "${var.environment}-group"

resource_query {
query = <<-JSON
{
"ResourceTypeFilters": [
"AWS::AllSupported"
],
"TagFilters": [
{
"Key": "Environment",
"Values": ["${var.environment}"]
}
]
}
JSON
}
}
11 changes: 11 additions & 0 deletions modules/action-runner-binary-cache/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
locals {
action_runner_distribution_object_key = "actions-runner-linux.tar.gz"
}

resource "aws_s3_bucket" "action_dist" {
bucket = var.distribution_bucket_name
acl = "private"
force_destroy = true
tags = var.tags
}

7 changes: 7 additions & 0 deletions modules/action-runner-binary-cache/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "distribution_bucket" {
value = aws_s3_bucket.action_dist
}

output "s3_location_runner_distribution" {
value = "s3://${aws_s3_bucket.action_dist.id}/${local.action_runner_distribution_object_key}"
}
21 changes: 21 additions & 0 deletions modules/action-runner-binary-cache/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
variable "aws_region" {
description = "AWS region."
type = string
}

variable "tags" {
description = "Map of tags that will be added to created resources. By default resources will be tagged with name and environment."
type = map(string)
default = {}
}

variable "environment" {
description = "A name that identifies the environment, used as prefix and for tagging."
type = string
}

variable "distribution_bucket_name" {
description = "Bucket for storing the action runner distribution."
type = string
}

8 changes: 8 additions & 0 deletions modules/runners/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Action runner module

The module create resources to facilitate the `orchestrator labmda` to recreate action runners.

- *launch template* : A launch template is created that can create an action runner, by default a spot instance is requested. For configuration parameters SSM is used.
- *security group* : Security groups attached to the action runner.
- *s3 bucket* : To avoid the action runner distribution to be downloaded from Github every time (which could be slow), a version is cached in a S3 bucket.
- *policies and roles* : Policies and roles for the action runner. By default the session manager is enabled
93 changes: 93 additions & 0 deletions modules/runners/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
locals {
name_sg = var.overrides["name_sg"] == "" ? local.tags["Name"] : var.overrides["name_sg"]

tags = merge(
{
"Name" = format("%s", var.environment)
},
{
"Environment" = format("%s", var.environment)
},
var.tags,
)
}

data "aws_ami" "runner" {
most_recent = "true"

dynamic "filter" {
for_each = var.ami_filter
content {
name = filter.key
values = filter.value
}
}

owners = var.ami_owners
}

resource "aws_launch_template" "runner" {
name = "${var.environment}-action-runner"

dynamic "block_device_mappings" {
for_each = [var.block_device_mappings]
content {
device_name = "/dev/xvda"

ebs {
delete_on_termination = lookup(block_device_mappings.value, "delete_on_termination", true)
volume_type = lookup(block_device_mappings.value, "volume_type", "gp2")
volume_size = lookup(block_device_mappings.value, "volume_size", 30)
encrypted = lookup(block_device_mappings.value, "encrypted", true)
iops = lookup(block_device_mappings.value, "iops", null)
}
}
}

iam_instance_profile {
name = aws_iam_instance_profile.runner.name
}

instance_initiated_shutdown_behavior = "terminate"

instance_market_options {
market_type = var.market_options
}

image_id = data.aws_ami.runner.id
instance_type = var.instance_type

vpc_security_group_ids = [aws_security_group.runner_sg.id]

tag_specifications {
resource_type = "instance"
tags = local.tags
}

user_data = base64encode(templatefile("${path.module}/templates/user-data.sh", {
environment = var.environment
pre_install = var.userdata_pre_install
post_install = var.userdata_post_install
s3_location_runner_distribution = var.s3_location_runner_distribution
}))
}

resource "aws_security_group" "runner_sg" {
name_prefix = "${var.environment}-github-actions-runner-sg"
description = "Github Actions Runner 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)
},
)
}
7 changes: 7 additions & 0 deletions modules/runners/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "launch_template" {
value = aws_launch_template.runner
}

output "role" {
value = aws_iam_role.runner
}
47 changes: 47 additions & 0 deletions modules/runners/policies.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
data "aws_caller_identity" "current" {}

resource "aws_iam_role" "runner" {
name = "${var.environment}-github-action-runners-runner-role"
assume_role_policy = templatefile("${path.module}/policies/instance-role-trust-policy.json", {})
tags = local.tags
}

resource "aws_iam_instance_profile" "runner" {
name = "${var.environment}-github-action-runners-profile"
role = aws_iam_role.runner.name
}

resource "aws_iam_policy" "runner_session_manager_policy" {
name = "${var.environment}-github-action-runners-session-manager"
path = "/"
description = "Policy session manager."

policy = templatefile("${path.module}/policies/instance-session-manager-policy.json", {})
}

resource "aws_iam_role_policy_attachment" "runner_session_manager_policy" {
role = aws_iam_role.runner.name
policy_arn = aws_iam_policy.runner_session_manager_policy.arn
}

resource "aws_iam_role_policy_attachment" "runner_session_manager_aws_managed" {
role = aws_iam_role.runner.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_policy" "ssm_parameters" {
name = "${var.environment}-runner-ssm-parameters"
path = "/"
description = "Policy for the runner to download the github action runner."

policy = templatefile("${path.module}/policies/instance-ssm-parameters-policy.json",
{
arn_ssm_parameters = "arn:aws:ssm:${var.aws_region}:${data.aws_caller_identity.current.account_id}:parameter/${var.environment}-*"
}
)
}

resource "aws_iam_role_policy_attachment" "ssm_parameters" {
role = aws_iam_role.runner.name
policy_arn = aws_iam_policy.ssm_parameters.arn
}
13 changes: 13 additions & 0 deletions modules/runners/policies/instance-role-trust-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
15 changes: 15 additions & 0 deletions modules/runners/policies/instance-session-manager-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
15 changes: 15 additions & 0 deletions modules/runners/policies/instance-ssm-parameters-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ssm:DeleteParameter"],
"Resource": "${arn_ssm_parameters}"
},
{
"Effect": "Allow",
"Action": ["ssm:GetParameters"],
"Resource": "${arn_ssm_parameters}"
}
]
}
Loading