-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support autoscaling runners (#117)
## Description This PR explores using the fleeting plugins to create instances for GitLab runners ## Related Issue Fixes #79 Fixes #48 Fixes #66 ## Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [X] New feature (non-breaking change which adds functionality) - [ ] Other (security config, docs update, etc) ## Checklist before merging - [ ] Test, docs, adr added or updated as needed - [X] [Contributor Guide Steps](https://github.com/defenseunicorns/uds-package-gitlab-runner/blob/main/CONTRIBUTING.md#developer-workflow) followed --------- Co-authored-by: Jordan McClintock <jordan@defenseunicorns.com> Co-authored-by: Eric Wyles <23637493+ericwyles@users.noreply.github.com>
- Loading branch information
1 parent
c822744
commit 38482bd
Showing
27 changed files
with
956 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
provider "aws" { | ||
region = var.region | ||
|
||
default_tags { | ||
tags = { | ||
PermissionsBoundary = var.permissions_boundary_name | ||
} | ||
} | ||
} | ||
|
||
terraform { | ||
required_version = ">= 1.8.0" | ||
backend "s3" { | ||
} | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = ">= 4.0" | ||
} | ||
|
||
random = { | ||
source = "hashicorp/random" | ||
version = "3.6.2" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
data "aws_s3_bucket" "oidc_bucket" { | ||
bucket = "govcloud-ci-oidc" | ||
} | ||
|
||
data "aws_partition" "current" {} | ||
|
||
data "aws_caller_identity" "current" {} | ||
|
||
## This will create a policy for the Autoscaling Group (https://gitlab.com/gitlab-org/fleeting/plugins/aws#setting-an-iam-policy) | ||
resource "aws_iam_policy" "asg_policy" { | ||
name = "${var.name}-policy" | ||
path = "/" | ||
description = "IRSA policy to access the autoscaling group." | ||
policy = jsonencode({ | ||
Version = "2012-10-17" | ||
Statement = [ | ||
{ | ||
Effect = "Allow" | ||
Action = [ | ||
"autoscaling:SetDesiredCapacity", | ||
"autoscaling:TerminateInstanceInAutoScalingGroup", | ||
] | ||
Resource = aws_autoscaling_group.uds-package-gitlab-runner.arn | ||
}, | ||
{ | ||
Effect = "Allow" | ||
Action = [ | ||
"autoscaling:DescribeAutoScalingGroups", | ||
"ec2:DescribeInstances", | ||
] | ||
Resource = "*" | ||
}, | ||
{ | ||
Effect = "Allow" | ||
Action = [ | ||
"ec2:GetPasswordData", | ||
"ec2-instance-connect:SendSSHPublicKey", | ||
] | ||
Resource = "arn:${data.aws_partition.current.partition}:ec2:${var.region}:${data.aws_caller_identity.current.account_id}:instance/*" | ||
Condition = { | ||
StringEquals = { | ||
"ec2:ResourceTag/aws:autoscaling:groupName": aws_autoscaling_group.uds-package-gitlab-runner.name | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
} | ||
|
||
## Create service account role | ||
resource "aws_iam_role" "asg_role" { | ||
name = "${var.name}-asg-role" | ||
|
||
assume_role_policy = jsonencode({ | ||
Version = "2012-10-17" | ||
Statement = [ | ||
{ | ||
Action = "sts:AssumeRoleWithWebIdentity" | ||
Effect = "Allow" | ||
Principal = { | ||
Service = "ec2.amazonaws.com" | ||
"Federated" : "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${data.aws_s3_bucket.oidc_bucket.bucket_regional_domain_name}" | ||
} | ||
"Condition" : { | ||
"StringEquals" : { | ||
"${data.aws_s3_bucket.oidc_bucket.bucket_regional_domain_name}:aud" : "irsa", | ||
"${data.aws_s3_bucket.oidc_bucket.bucket_regional_domain_name}:sub" : "system:serviceaccount:${var.namespace}:${var.service_account}" | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
|
||
permissions_boundary = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/${var.permissions_boundary_name}" | ||
|
||
tags = { | ||
PermissionsBoundary = var.permissions_boundary_name | ||
} | ||
} | ||
|
||
resource "aws_iam_role_policy_attachment" "asg_policy_attach" { | ||
role = aws_iam_role.asg_role.name | ||
policy_arn = aws_iam_policy.asg_policy.arn | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
data "aws_availability_zones" "available" { | ||
state = "available" | ||
} | ||
|
||
module "vpc" { | ||
source = "terraform-aws-modules/vpc/aws" | ||
version = "5.1.1" | ||
|
||
name = "${var.name}-vpc" | ||
cidr = "10.0.0.0/16" | ||
azs = [for az_name in slice(data.aws_availability_zones.available.names, 0, min(length(data.aws_availability_zones.available.names), 3)) : az_name] | ||
public_subnets = [for k, v in module.vpc.azs : cidrsubnet(module.vpc.vpc_cidr_block, 5, k)] | ||
enable_nat_gateway = false | ||
|
||
instance_tenancy = "default" | ||
vpc_flow_log_permissions_boundary = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:policy/${var.permissions_boundary_name}" | ||
|
||
tags = { | ||
Name = "${var.name}-vpc" | ||
} | ||
} | ||
|
||
resource "aws_launch_template" "uds-package-gitlab-runner" { | ||
name_prefix = "uds-package-gitlab-runner-" | ||
image_id = var.ami_id | ||
instance_type = "t3.micro" | ||
|
||
network_interfaces { | ||
associate_public_ip_address = true | ||
security_groups = [aws_security_group.uds-package-gitlab-runner.id] | ||
} | ||
|
||
block_device_mappings { | ||
device_name = "/dev/xvda" | ||
ebs { | ||
volume_size = 8 | ||
} | ||
} | ||
|
||
tag_specifications { | ||
resource_type = "instance" | ||
tags = { | ||
Name = "${var.name}-launch-template" | ||
} | ||
} | ||
} | ||
|
||
# AWS Fleeting Plugin: https://gitlab.com/gitlab-org/fleeting/plugins/aws#autoscaling-group-setup | ||
resource "aws_autoscaling_group" "uds-package-gitlab-runner" { | ||
name = var.name | ||
desired_capacity = 0 | ||
max_size = 10 | ||
min_size = 0 | ||
vpc_zone_identifier = module.vpc.public_subnets | ||
|
||
launch_template { | ||
id = aws_launch_template.uds-package-gitlab-runner.id | ||
version = "$Latest" | ||
} | ||
} | ||
|
||
resource "aws_security_group" "uds-package-gitlab-runner" { | ||
name = "${var.name}-security-group" | ||
description = "Allow inbound traffic from GitHub runner" | ||
vpc_id = module.vpc.vpc_id | ||
|
||
ingress { | ||
from_port = 22 | ||
to_port = 22 | ||
protocol = "tcp" | ||
cidr_blocks = ["${var.runner_ip}/32"] | ||
} | ||
|
||
ingress { | ||
from_port = 443 | ||
to_port = 443 | ||
protocol = "tcp" | ||
cidr_blocks = [module.vpc.vpc_cidr_block] | ||
} | ||
|
||
egress { | ||
from_port = 0 | ||
to_port = 0 | ||
protocol = "-1" | ||
cidr_blocks = ["0.0.0.0/0"] | ||
} | ||
} | ||
|
||
resource "tls_private_key" "jumpbox_tls_key" { | ||
algorithm = "RSA" | ||
rsa_bits = 4096 | ||
} | ||
|
||
resource "aws_key_pair" "jumpbox_key_pair" { | ||
key_name = "${var.name}-jumpbox-ssh-key" | ||
public_key = tls_private_key.jumpbox_tls_key.public_key_openssh | ||
} | ||
|
||
resource "aws_instance" "jumpbox" { | ||
ami = var.ami_id | ||
instance_type = "t3.micro" | ||
key_name = aws_key_pair.jumpbox_key_pair.key_name | ||
|
||
tags = { | ||
Name = "${var.name}-jumpbox" | ||
} | ||
|
||
# Security group to allow SSH (port 22) | ||
vpc_security_group_ids = [aws_security_group.uds-package-gitlab-runner.id] | ||
subnet_id = module.vpc.public_subnets[0] | ||
|
||
associate_public_ip_address = true | ||
} | ||
|
||
resource "aws_route53_zone" "uds_dev" { | ||
name = "uds.dev" | ||
vpc { | ||
vpc_id = module.vpc.vpc_id | ||
} | ||
} | ||
|
||
resource "aws_route53_record" "my_domain" { | ||
zone_id = aws_route53_zone.uds_dev.id | ||
name = "gitlab.uds.dev" | ||
type = "A" | ||
ttl = 300 | ||
|
||
records = [aws_instance.jumpbox.private_ip] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
output "asg_arn" { | ||
value = aws_autoscaling_group.uds-package-gitlab-runner.arn | ||
description = "The ARN of the Autoscaling Group" | ||
} | ||
|
||
output "asg_role_arn" { | ||
value = aws_iam_role.asg_role.arn | ||
description = "The ARN of the ASG IRSA role" | ||
} | ||
|
||
output "jumpbox_public_ip" { | ||
value = aws_instance.jumpbox.public_ip | ||
description = "The IP Address of the jumpbox" | ||
sensitive = true | ||
} | ||
|
||
output "jumpbox_private_key" { | ||
value = tls_private_key.jumpbox_tls_key.private_key_pem | ||
description = "The SSH Key for the jumpbox" | ||
sensitive = true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
variable "runner_ip" { | ||
description = "Public IP of the GitHub Actions runner" | ||
type = string | ||
} | ||
|
||
variable "region" { | ||
description = "AWS region" | ||
type = string | ||
} | ||
|
||
variable "name" { | ||
description = "Name for the Autoscaling Group" | ||
type = string | ||
} | ||
|
||
variable "ami_id" { | ||
description = "The ID of the AMI to scale in the ASG (must have git and gitlab-runner installed)" | ||
type = string | ||
} | ||
|
||
variable "namespace" { | ||
description = "Namespace containing the GitLab Runner Service Account" | ||
type = string | ||
default = "gitlab-runner" | ||
} | ||
|
||
variable "service_account" { | ||
description = "Name of the GitLab Runner Service Account" | ||
type = string | ||
default = "gitlab-runner" | ||
} | ||
|
||
variable "permissions_boundary_name" { | ||
description = "The name of the permissions boundary for IAM resources. This will be used for tagging and to build out the ARN." | ||
type = string | ||
default = null | ||
} |
Oops, something went wrong.