Skip to content

Commit 74811c4

Browse files
author
rohit-ng
committed
feat: add module for github self hosted runner
1 parent 726b1c5 commit 74811c4

File tree

11 files changed

+256
-1
lines changed

11 files changed

+256
-1
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
| <a name="module_ecs_node_security_group"></a> [ecs\_node\_security\_group](#module\_ecs\_node\_security\_group) | terraform-aws-modules/security-group/aws | ~> 5.1.2 |
2020
| <a name="module_ecs_task_role"></a> [ecs\_task\_role](#module\_ecs\_task\_role) | ./modules/iam | n/a |
2121
| <a name="module_ecs_task_security_group"></a> [ecs\_task\_security\_group](#module\_ecs\_task\_security\_group) | terraform-aws-modules/security-group/aws | ~> 5.1.2 |
22+
| <a name="module_github_runner"></a> [github\_runner](#module\_github\_runner) | ./modules/github-runner | n/a |
2223
| <a name="module_internal_alb_kong"></a> [internal\_alb\_kong](#module\_internal\_alb\_kong) | github.com/infraspecdev/terraform-aws-ecs-deployment//modules/alb | v1.1.1 |
2324
| <a name="module_internal_alb_security_group"></a> [internal\_alb\_security\_group](#module\_internal\_alb\_security\_group) | terraform-aws-modules/security-group/aws | ~> 5.1.2 |
2425
| <a name="module_kong_internal_dns_record"></a> [kong\_internal\_dns\_record](#module\_kong\_internal\_dns\_record) | ./modules/route-53-record | n/a |
@@ -56,6 +57,8 @@
5657
| <a name="input_ecs_node_security_group_id"></a> [ecs\_node\_security\_group\_id](#input\_ecs\_node\_security\_group\_id) | ECS node security group id | `string` | `null` | no |
5758
| <a name="input_ecs_task_security_group_id"></a> [ecs\_task\_security\_group\_id](#input\_ecs\_task\_security\_group\_id) | ECS task security group id | `string` | `null` | no |
5859
| <a name="input_force_new_deployment"></a> [force\_new\_deployment](#input\_force\_new\_deployment) | Whether to force new deployment | `bool` | `true` | no |
60+
| <a name="input_github_config_token"></a> [github\_config\_token](#input\_github\_config\_token) | Github config token for self-hosted runner | `string` | n/a | yes |
61+
| <a name="input_github_config_url"></a> [github\_config\_url](#input\_github\_config\_url) | Github config url for self-hosted runner | `string` | n/a | yes |
5962
| <a name="input_instance_type_for_kong"></a> [instance\_type\_for\_kong](#input\_instance\_type\_for\_kong) | Instance type for kong | `string` | `"t2.micro"` | no |
6063
| <a name="input_key_name_for_kong"></a> [key\_name\_for\_kong](#input\_key\_name\_for\_kong) | Key name for to SSH into kong instance | `string` | `null` | no |
6164
| <a name="input_kong_admin_sub_domain_names"></a> [kong\_admin\_sub\_domain\_names](#input\_kong\_admin\_sub\_domain\_names) | List of kong admin sub domain names | `list(any)` | n/a | yes |

main.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,3 +363,11 @@ module "kong_internal_dns_record" {
363363
alb_dns_name = module.internal_alb_kong.dns_name
364364
alb_zone_id = module.ecs_kong.alb_zone_id
365365
}
366+
367+
module "github_runner" {
368+
source = "./modules/github-runner"
369+
vpc_id = var.vpc_id
370+
private_subnet_id = var.private_subnet_ids[0]
371+
github_config_token = var.github_config_token
372+
github_config_url = var.github_config_url
373+
}

modules/github-runner/.header.md

Whitespace-only changes.

modules/github-runner/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Requirements
2+
3+
No requirements.
4+
5+
## Providers
6+
7+
| Name | Version |
8+
|------|---------|
9+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.53.0 |
10+
11+
## Modules
12+
13+
No modules.
14+
15+
## Resources
16+
17+
| Name | Type |
18+
|------|------|
19+
| [aws_instance.github_runner](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource |
20+
| [aws_security_group.github_runner](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
21+
22+
## Inputs
23+
24+
| Name | Description | Type | Default | Required |
25+
|------|-------------|------|---------|:--------:|
26+
| <a name="input_ami_id"></a> [ami\_id](#input\_ami\_id) | AMI ID for the private instances | `string` | `"ami-0f58b397bc5c1f2e8"` | no |
27+
| <a name="input_github_config_token"></a> [github\_config\_token](#input\_github\_config\_token) | Github config token for self-hosted runners | `string` | n/a | yes |
28+
| <a name="input_github_config_url"></a> [github\_config\_url](#input\_github\_config\_url) | Github config url for self-hosted runners | `string` | n/a | yes |
29+
| <a name="input_key_name"></a> [key\_name](#input\_key\_name) | The name of the EC2 key pair | `string` | `"runner"` | no |
30+
| <a name="input_private_subnet_id"></a> [private\_subnet\_id](#input\_private\_subnet\_id) | The ID of the private subnet | `string` | n/a | yes |
31+
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The ID of the VPC | `string` | n/a | yes |
32+
33+
## Outputs
34+
35+
No outputs.

modules/github-runner/locals.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
locals {
2+
security_group_name_prefix = "github-runner-sg"
3+
ubuntu_instance_name = "github-runner"
4+
instance_type = "t2.micro"
5+
}

modules/github-runner/main.tf

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
resource "aws_instance" "github_runner" {
2+
ami = var.ami_id
3+
instance_type = local.instance_type
4+
subnet_id = var.private_subnet_id
5+
vpc_security_group_ids = [aws_security_group.github_runner.id]
6+
key_name = var.key_name
7+
user_data = templatefile("${path.module}/scripts/self-hosted-runner.sh", {
8+
CONFIG_TOKEN = var.github_config_token
9+
CONFIG_URL = var.github_config_url
10+
})
11+
tags = {
12+
Name = local.ubuntu_instance_name
13+
}
14+
}
15+
16+
resource "aws_security_group" "github_runner" {
17+
name_prefix = local.security_group_name_prefix
18+
description = "Allow ssh ingress and all egress traffic"
19+
vpc_id = var.vpc_id
20+
21+
ingress {
22+
from_port = 22
23+
to_port = 22
24+
protocol = "tcp"
25+
cidr_blocks = ["0.0.0.0/0"]
26+
}
27+
28+
egress {
29+
from_port = 0
30+
to_port = 0
31+
protocol = "-1"
32+
cidr_blocks = ["0.0.0.0/0"]
33+
}
34+
35+
tags = {
36+
Name = local.security_group_name_prefix
37+
}
38+
}

modules/github-runner/outputs.tf

Whitespace-only changes.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/bin/bash
2+
3+
# Define multiple runner configurations
4+
# declare -A RUNNERS=(
5+
# ["runner-1"]="https://github.com/actions/runner/releases/download/v2.317.0/actions-runner-linux-x64-2.317.0.tar.gz"
6+
# )
7+
8+
DEFAULT_USER="githubrunner"
9+
USER_HOME="/home/$DEFAULT_USER"
10+
USER_PASSWORD="password"
11+
RUNNER_VERSION="2.317.0"
12+
RUNNER_PACKAGE="actions-runner-linux-x64-$RUNNER_VERSION.tar.gz"
13+
14+
# Function to display error message and exit
15+
die() {
16+
echo >&2 "Error: $@"
17+
exit 1
18+
}
19+
20+
# Function to install required packages
21+
install_packages() {
22+
local packages="$@"
23+
if [ -x "$(command -v apt-get)" ]; then
24+
sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
25+
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install $packages || die "Failed to install $packages. Aborting."
26+
elif [ -x "$(command -v yum)" ]; then
27+
sudo yum -y install $packages || die "Failed to install $packages. Aborting."
28+
elif [ -x "$(command -v dnf)" ]; then
29+
sudo dnf -y install $packages || die "Failed to install $packages. Aborting."
30+
elif [ -x "$(command -v pacman)" ]; then
31+
sudo pacman -Sy --noconfirm $packages || die "Failed to install $packages. Aborting."
32+
else
33+
die "Unsupported package manager. Please install $packages manually."
34+
fi
35+
}
36+
37+
# Function to check if a command exists
38+
command_exists() {
39+
command -v "$1" >/dev/null 2>&1
40+
}
41+
42+
# Function to set up runner directory and permissions
43+
setup_runner_directory() {
44+
local RUNNER_NAME="$1"
45+
local RUNNER_DIR="$USER_HOME/$RUNNER_NAME/actions-runner"
46+
47+
sudo mkdir -p "$RUNNER_DIR" || die "Failed to create $RUNNER_DIR directory."
48+
sudo chown -R $DEFAULT_USER:$DEFAULT_USER "$RUNNER_DIR" || die "Failed to set ownership for $RUNNER_DIR."
49+
}
50+
51+
# Function to download and extract GitHub Actions runner package
52+
download_and_extract_runner() {
53+
local RUNNER_NAME="$1"
54+
local EXPECTED_CHECKSUM="9e883d210df8c6028aff475475a457d380353f9d01877d51cc01a17b2a91161d"
55+
local RUNNER="https://github.com/actions/runner/releases/download/v2.317.0/actions-runner-linux-x64-2.317.0.tar.gz"
56+
57+
# Ensure directory exists and has correct ownership
58+
sudo mkdir -p "$USER_HOME/$RUNNER_NAME/actions-runner" || die "Failed to create $USER_HOME/$RUNNER_NAME/actions-runner directory."
59+
sudo chown -R $DEFAULT_USER:$DEFAULT_USER "$USER_HOME/$RUNNER_NAME/actions-runner" || die "Failed to set ownership for $USER_HOME/$RUNNER_NAME/actions-runner."
60+
61+
# Download and verify checksum
62+
sudo -u $DEFAULT_USER curl -o "$USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE" -L "$RUNNER" || die "Failed to download $RUNNER_PACKAGE."
63+
sudo chown $DEFAULT_USER:$DEFAULT_USER "$USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE" || die "Failed to set ownership for $USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE."
64+
65+
# Verify SHA256 checksum
66+
actual_checksum=$(sudo -u $DEFAULT_USER sha256sum "$USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE" | awk '{print $1}')
67+
if [ "$EXPECTED_CHECKSUM" != "$actual_checksum" ]; then
68+
die "Checksum verification failed for $USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE. Aborting."
69+
fi
70+
71+
# Extract the runner package
72+
sudo -u $DEFAULT_USER tar xzf "$USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE" -C "$USER_HOME/$RUNNER_NAME/actions-runner" || die "Failed to extract $USER_HOME/$RUNNER_NAME/actions-runner/$RUNNER_PACKAGE."
73+
sudo chown -R $DEFAULT_USER:$DEFAULT_USER "$USER_HOME/$RUNNER_NAME/actions-runner" || die "Failed to set ownership for $USER_HOME/$RUNNER_NAME/actions-runner."
74+
}
75+
76+
# Function to configure and start the runner
77+
configure_and_start_runner() {
78+
local RUNNER_NAME="$1"
79+
80+
sudo -u $DEFAULT_USER -i <<EOF
81+
cd "$USER_HOME/$RUNNER_NAME/actions-runner" || exit 1
82+
83+
./config.sh --url "${CONFIG_URL}" \
84+
--token "${CONFIG_TOKEN}" \
85+
--name "$RUNNER_NAME" \
86+
--runnergroup "Default" \
87+
--work "_work" \
88+
--labels "self-hosted,Linux,X64,$RUNNER_NAME" \
89+
--unattended \
90+
--replace || { echo "Failed to configure GitHub Actions runner"; exit 1; }
91+
92+
nohup ./run.sh > runner.log 2>&1 &
93+
if [ \$? -ne 0 ]; then
94+
echo "Failed to start GitHub Actions runner $RUNNER_NAME"
95+
exit 1
96+
fi
97+
98+
echo "GitHub Actions runner setup for $RUNNER_NAME completed successfully."
99+
echo "The runner is running in the background. Check runner.log for output."
100+
EOF
101+
}
102+
103+
# Main script
104+
main() {
105+
local RUNNER_NAME="runner"
106+
# Install required packages if not already installed
107+
command_exists curl || install_packages curl
108+
109+
# Ensure default user exists and has necessary permissions (no longer creating new users)
110+
sudo useradd -m -s /bin/bash $DEFAULT_USER 2>/dev/null || true
111+
echo "$DEFAULT_USER:$USER_PASSWORD" | sudo chpasswd || die "Failed to set password for $DEFAULT_USER. Aborting."
112+
echo "$DEFAULT_USER ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/$DEFAULT_USER >/dev/null
113+
sudo chmod 0440 /etc/sudoers.d/$DEFAULT_USER
114+
115+
setup_runner_directory "$RUNNER_NAME"
116+
download_and_extract_runner "$RUNNER_NAME"
117+
configure_and_start_runner "$RUNNER_NAME"
118+
119+
echo "All GitHub Actions runners setup completed successfully."
120+
}
121+
122+
# Execute main script
123+
main

modules/github-runner/variables.tf

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
variable "ami_id" {
2+
description = "AMI ID for the private instances"
3+
type = string
4+
default = "ami-0f58b397bc5c1f2e8"
5+
}
6+
7+
variable "vpc_id" {
8+
description = "The ID of the VPC"
9+
type = string
10+
}
11+
12+
variable "private_subnet_id" {
13+
description = "The ID of the private subnet"
14+
type = string
15+
}
16+
17+
variable "key_name" {
18+
description = "The name of the EC2 key pair"
19+
type = string
20+
default = "runner"
21+
}
22+
23+
variable "github_config_url" {
24+
description = "Github config url for self-hosted runners"
25+
type = string
26+
sensitive = true
27+
}
28+
29+
variable "github_config_token" {
30+
description = "Github config token for self-hosted runners"
31+
type = string
32+
sensitive = true
33+
}

modules/iam/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ No requirements.
66

77
| Name | Version |
88
|------|---------|
9-
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
9+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.59.0 |
1010

1111
## Modules
1212

0 commit comments

Comments
 (0)