Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
38 changes: 38 additions & 0 deletions .github/workflows/github-self-hosted-runner-testing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# The name of the pipeline. Must be unique.
name: "Terraform - AWS"

on:
push:
# only run when files in this path changes
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#example-using-positive-and-negative-patterns-1
paths:
- 'terraform-modules/aws/helm/github_runner/**'
branches:
- main
pull_request:
# only run when files in this path changes
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#example-using-positive-and-negative-patterns-1
paths:
- 'terraform-modules/aws/helm/github_runner/**'

jobs:
## This generates a matrix of changed directory to run Terraform on
self_hosted_runner:
#runs-on: ubuntu-latest
# Label from the CRD deployment: https://github.com/actions-runner-controller/actions-runner-controller#runner-labels
runs-on: custom-runner
env:
# The path that you want to construct the matrix on. Only files in this
# path that has changed will be included in.
TERRAFORM_CHECK_PATH: terraform-environments/aws/dev
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 2

- name: Runing on self hosted runner
run: |
echo hi
ps aux
curl -v https://651D35E97B291CC344F098C47028D880.gr7.us-west-2.eks.amazonaws.com -k
12 changes: 12 additions & 0 deletions terraform-modules/aws/helm/github_runner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Github Runner

Source: https://github.com/actions-runner-controller/actions-runner-controller


Requirements:
* cert-manager
* kubernetes-external-secrets (optional)

# Runner type support

Currently this module only supports the PAT runner type.
6 changes: 6 additions & 0 deletions terraform-modules/aws/helm/github_runner/helm_values.tpl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
# Using our own self signed cert
# https://github.com/actions-runner-controller/actions-runner-controller#using-without-cert-manager
certManagerEnabled: false
admissionWebHooks:
caBundle: ${ca_public_key}
164 changes: 164 additions & 0 deletions terraform-modules/aws/helm/github_runner/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
locals {
helm_repository = "https://actions-runner-controller.github.io/actions-runner-controller"
official_chart_name = "actions-runner-controller"
}

#
# create namespace
#
module "namespace" {
source = "github.com/ManagedKube/kubernetes-ops//terraform-modules/aws/kubernetes/namespace?ref=v1.0.50"

name = var.k8s_namespace
}

#
# Helm values
#
data "template_file" "helm_values" {
template = file("${path.module}/helm_values.tpl.yaml")
vars = {
ca_public_key = base64encode(module.cert.ca_public_key)
}
}

module "helm_generic" {
source = "github.com/ManagedKube/kubernetes-ops//terraform-modules/aws/helm/helm_generic?ref=v1.0.27"

repository = local.helm_repository
official_chart_name = local.official_chart_name
user_chart_name = var.user_chart_name
helm_version = var.helm_chart_version
namespace = var.k8s_namespace
helm_values = data.template_file.helm_values.rendered
helm_values_2 = var.helm_values_2

depends_on = [
module.cert,
kubernetes_secret_v1.this,
module.namespace,
]
}

#
# kubernetes-external-secret
#
# Using the Github PAT method
# doc: https://github.com/actions-runner-controller/actions-runner-controller#deploying-using-pat-authentication
# This is the secret referencing the PAT token in AWS Secret
resource "kubernetes_manifest" "kube_secret_crd" {
count = var.enable_kubernetes_external_secret ? 1 : 0

manifest = {
apiVersion = "kubernetes-client.io/v1"
kind = "ExternalSecret"

metadata = {
name = var.kubernetes_external_secret_name
namespace = var.k8s_namespace
}

spec = {
backendType = "secretsManager"

data = [
{
# AWS Secrets name
key = var.aws_secret_name
# The name in the k8s secret
name = var.k8s_secret_key_name
},
]
}
}

depends_on = [
module.namespace
]
}

#
# Generate self signed certs for use with the runner:
# doc: https://github.com/actions-runner-controller/actions-runner-controller#using-without-cert-manager
# Even the cert-manager is configured to generate a self signed cert
#
module "cert" {
source = "github.com/ManagedKube/kubernetes-ops//terraform-modules/generate-cert?ref=github-runner"

ca_public_key_file_path = "/tmp/ca_public_key_file"
public_key_file_path = "/tmp/public_key_file"
private_key_file_path = "/tmp/private_key_file"
owner = "k8s"
ca_common_name = "k8s"
common_name = "k8s"
ip_addresses = []
validity_period_hours = 43830
organization_name = "k8s"

dns_names = [
"webhook-service.${var.k8s_namespace}.svc",
"webhook-service.${var.k8s_namespace}.svc.cluster.local",
"${var.k8s_namespace}-webhook.${var.k8s_namespace}.svc",
"${var.k8s_namespace}-webhook.${var.k8s_namespace}.svc",
]
}

resource "kubernetes_secret_v1" "this" {
metadata {
name = "${var.k8s_namespace}-serving-cert"
# name = "webhook-server-cert"
namespace = var.k8s_namespace
}

data = {
"tls.crt" = module.cert.client_cert
"tls.key" = module.cert.client_private_key
}

type = "kubernetes.io/tls"

depends_on = [
module.cert,
module.namespace,
]
}

#
# Github Action Runner deployments
#
# The above deploys the control nodes. This deploys the actual Github Action runners
# where the jobs will run in. This creates the "RunnerDeployment" CRD which will
# Create the runner deployments.
#
# Docs: https://github.com/actions-runner-controller/actions-runner-controller#runnerdeployments
#
# To view the runner: github.com -> settings -> Actions -> Runners
#
resource "kubernetes_manifest" "runnerDeployment" {
manifest = {
apiVersion = "actions.summerwind.dev/v1alpha1"
kind = "RunnerDeployment"

metadata = {
name = var.runner_deployment_name
namespace = var.k8s_namespace
}

spec = {
replicas = var.runner_number_of_replicas

template ={
spec = {
repository = var.runner_repository_name
# env = []

# The labels on how to target this runner from the GHA's workflow files
# Doc: https://github.com/actions-runner-controller/actions-runner-controller#runner-labels
labels = [
var.runner_label
]
}
}
}
}
}
67 changes: 67 additions & 0 deletions terraform-modules/aws/helm/github_runner/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
variable "user_chart_name" {
default = "actions-runner-controller"
description = "The Helm name to install this chart under"
}

variable "helm_chart_version" {
default = "0.15.1"
description = "The version of this helm chart to use"
}

variable "k8s_namespace" {
default = "actions-runner-controller"
}

variable "helm_values_2" {
type = string
default = ""
description = "Helm values that will overwrite the helm chart defaults and this modules default for further user customization"
}

variable "enable_kubernetes_external_secret" {
type = bool
description = "To create the kubernetes-external-secret or not. Only if you are using the kubernetes-external-secret controller"
default = false
}

variable "kubernetes_external_secret_name" {
type = string
description = "The kubernetes-external secret name and the secret name. enable_kubernetes_external_secret must be set to true"
default = "controller-manager"
}

variable "aws_secret_name" {
type = string
description = "The name of the AWS Secret to pull from. enable_kubernetes_external_secret must be set to true"
default = "github_token"
}

variable "k8s_secret_key_name" {
type = string
description = "The key name in the k8s secret. enable_kubernetes_external_secret must be set to true"
default = "github_token"
}

variable "runner_repository_name" {
type = string
description = "Runner config. The repository name to associate this runner to"
default = null
}

variable "runner_label" {
type = string
description = "Runner config. The label to place onto the runner and the label to use on the runs-on field in the GHA workflow file."
default = "self-hosted"
}

variable "runner_deployment_name" {
type = string
description = "Runner config. The runner CRD deployment name."
default = "runnerdeploy"
}

variable "runner_number_of_replicas" {
type = number
description = "Runner config. The number of runner replicas to create"
default = 1
}
8 changes: 8 additions & 0 deletions terraform-modules/generate-cert/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Generate Cert

Source: https://github.com/gruntwork-io/private-tls-cert

This repository contains a Terraform module that can be used to generate self-signed TLS certificate. To be more accurate, the module generates the following:

* A Certificate Authority (CA) public key
* The public and private keys of a TLS certificate signed by the CA
72 changes: 72 additions & 0 deletions terraform-modules/generate-cert/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# ---------------------------------------------------------------------------------------------------------------------
# CREATE A CA CERTIFICATE
# ---------------------------------------------------------------------------------------------------------------------

resource "tls_private_key" "ca" {
algorithm = "${var.private_key_algorithm}"
ecdsa_curve = "${var.private_key_ecdsa_curve}"
rsa_bits = "${var.private_key_rsa_bits}"
}

resource "tls_self_signed_cert" "ca" {
key_algorithm = "${tls_private_key.ca.algorithm}"
private_key_pem = "${tls_private_key.ca.private_key_pem}"
is_ca_certificate = true

validity_period_hours = "${var.validity_period_hours}"
allowed_uses = var.ca_allowed_uses

subject {
common_name = "${var.ca_common_name}"
organization = "${var.organization_name}"
}

# Store the CA public key in a file.
# provisioner "local-exec" {
# command = "echo '${tls_self_signed_cert.ca.cert_pem}' > '${var.ca_public_key_file_path}' && chmod ${var.permissions} '${var.ca_public_key_file_path}' && chown ${var.owner} '${var.ca_public_key_file_path}'"
# }
}

# ---------------------------------------------------------------------------------------------------------------------
# CREATE A TLS CERTIFICATE SIGNED USING THE CA CERTIFICATE
# ---------------------------------------------------------------------------------------------------------------------

resource "tls_private_key" "cert" {
algorithm = "${var.private_key_algorithm}"
ecdsa_curve = "${var.private_key_ecdsa_curve}"
rsa_bits = "${var.private_key_rsa_bits}"

# Store the certificate's private key in a file.
# provisioner "local-exec" {
# command = "echo '${tls_private_key.cert.private_key_pem}' > '${var.private_key_file_path}' && chmod ${var.permissions} '${var.private_key_file_path}' && chown ${var.owner} '${var.private_key_file_path}'"
# }
}

resource "tls_cert_request" "cert" {
key_algorithm = "${tls_private_key.cert.algorithm}"
private_key_pem = "${tls_private_key.cert.private_key_pem}"

dns_names = var.dns_names
ip_addresses = var.ip_addresses

subject {
common_name = "${var.common_name}"
organization = "${var.organization_name}"
}
}

resource "tls_locally_signed_cert" "cert" {
cert_request_pem = "${tls_cert_request.cert.cert_request_pem}"

ca_key_algorithm = "${tls_private_key.ca.algorithm}"
ca_private_key_pem = "${tls_private_key.ca.private_key_pem}"
ca_cert_pem = "${tls_self_signed_cert.ca.cert_pem}"

validity_period_hours = "${var.validity_period_hours}"
allowed_uses = var.allowed_uses

# Store the certificate's public key in a file.
# provisioner "local-exec" {
# command = "echo '${tls_locally_signed_cert.cert.cert_pem}' > '${var.public_key_file_path}' && chmod ${var.permissions} '${var.public_key_file_path}' && chown ${var.owner} '${var.public_key_file_path}'"
# }
}
11 changes: 11 additions & 0 deletions terraform-modules/generate-cert/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "ca_public_key" {
value = tls_self_signed_cert.ca.cert_pem
}

output "client_cert" {
value = tls_locally_signed_cert.cert.cert_pem
}

output "client_private_key" {
value = tls_private_key.cert.private_key_pem
}
Loading