Skip to content

Commit

Permalink
feat: [PAYMCLOUD-109] POC Github Runner on DevOpsLab (#139)
Browse files Browse the repository at this point in the history
* Add infrastructure setup for GitHub runner

This commit introduces new Terraform configurations to set up the infrastructure for a GitHub runner. It includes the addition of resource group, networking, container app environment and jobs, as well as corresponding variables and outputs. Additionally, a GitHub actions workflow for manual dispatch and supporting scripts have been added.

* Remove test-pipe workflow and add github-runner README

Deleted the manual dispatch workflow configuration from the test-pipe.yml file to streamline the repository. Added a new README.md for the GitHub runner in src/github-runner, providing detailed information on the requirements, modules, resources, inputs, and outputs for easy reference.

* Add manual dispatch workflow for self-hosted runner

This commit introduces a new GitHub Actions workflow that can be manually triggered via the workflow_dispatch event. The workflow includes steps to checkout the repository, echo a message, and run the `arp -a` command for testing purposes.

* Remove test-pipe workflow and update GitHub Runner config

Deleted the manual dispatch workflow YAML file and enhanced the GitHub Runner setup. Updated configurations to use specific branches and added managed identity outputs along with resource assignments.

* Update module source to tagged version v8.50.0

Changed the Terraform module source reference from a branch to a tagged version for improved stability and consistency. This ensures that the module uses a specific release version.
  • Loading branch information
ffppa authored Oct 16, 2024
1 parent d46c397 commit 25ebdc8
Show file tree
Hide file tree
Showing 16 changed files with 474 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/github-runner/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions src/github-runner/00_data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
data "azurerm_resource_group" "rg_common" {
name = "${var.prefix}-${var.env_short}-vnet-rg"
}

data "azurerm_key_vault" "key_vault_common" {
name = "${var.prefix}-${var.env_short}-${var.location_short}-kv"
resource_group_name = "${var.prefix}-${var.env_short}-sec-rg"
}

data "azurerm_virtual_network" "vnet_common" {
name = var.networking.vnet_common_name
resource_group_name = data.azurerm_resource_group.rg_common.name
}

data "azurerm_log_analytics_workspace" "law_common" {
name = var.law_name
resource_group_name = "${var.prefix}-${var.env_short}-monitor-rg"
}
6 changes: 6 additions & 0 deletions src/github-runner/00_resource_group.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
resource "azurerm_resource_group" "rg_github_runner" {
name = "${local.project}-github-runner-rg"
location = var.location

tags = var.tags
}
103 changes: 103 additions & 0 deletions src/github-runner/01_github_identity.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
data "azurerm_kubernetes_cluster" "aks" {
name = "${local.product}-itn-dev-aks"
resource_group_name = "${local.product}-itn-dev-aks-rg"
}

# repos must be lower than 20 items
locals {
repos_01 = [
"devops-app-status",
]

federations_01 = [
for repo in local.repos_01 : {
repository = repo
subject = "github-${var.env}"
}
]

namespace = "test-app-status"

# to avoid subscription Contributor -> https://github.com/microsoft/azure-container-apps/issues/35
environment_cd_roles = {
subscription = [
"Contributor"
]
resource_groups = {
"${azurerm_resource_group.rg_github_runner.name}" = [
"Key Vault Reader"
],
"${data.azurerm_kubernetes_cluster.aks.resource_group_name}" = [
"Contributor"
],
"${azurerm_resource_group.rg_github_runner.name}" = [
"Contributor"
]
}
}
}

module "identity_cd_01" {
source = "./.terraform/modules/__v3__/github_federated_identity"
# pagopa-<ENV><DOMAIN>-<COUNTER>-github-<PERMS>-identity
prefix = var.prefix
env_short = var.env_short

identity_role = "cd"

github_federations = local.federations_01

cd_rbac_roles = {
subscription_roles = local.environment_cd_roles.subscription
resource_groups = local.environment_cd_roles.resource_groups
}

tags = var.tags

}

resource "azurerm_key_vault_access_policy" "gha_iac_managed_identities" {
key_vault_id = data.azurerm_key_vault.key_vault_common.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = module.identity_cd_01.identity_principal_id

secret_permissions = ["Get", "List", "Set", ]

certificate_permissions = ["SetIssuers", "DeleteIssuers", "Purge", "List", "Get"]
key_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Encrypt", "Decrypt", "GetRotationPolicy"]

storage_permissions = []
}

resource "null_resource" "github_runner_app_permissions_to_namespace_cd_01" {
triggers = {
aks_id = data.azurerm_kubernetes_cluster.aks.id
service_principal_id = module.identity_cd_01.identity_client_id
namespace = local.namespace
version = "v2"
}

provisioner "local-exec" {
command = <<EOT
az role assignment create --role "Azure Kubernetes Service RBAC Admin" \
--assignee ${self.triggers.service_principal_id} \
--scope ${self.triggers.aks_id}/namespaces/${self.triggers.namespace}
az role assignment list --role "Azure Kubernetes Service RBAC Admin" \
--scope ${self.triggers.aks_id}/namespaces/${self.triggers.namespace}
EOT
}

provisioner "local-exec" {
when = destroy
command = <<EOT
az role assignment delete --role "Azure Kubernetes Service RBAC Admin" \
--assignee ${self.triggers.service_principal_id} \
--scope ${self.triggers.aks_id}/namespaces/${self.triggers.namespace}
EOT
}

depends_on = [
module.identity_cd_01
]
}
17 changes: 17 additions & 0 deletions src/github-runner/01_network.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module "subnet_runner" {
source = "./.terraform/modules/__v3__/subnet"

name = "${local.project}-github-runner-snet"
resource_group_name = data.azurerm_resource_group.rg_common.name
virtual_network_name = data.azurerm_virtual_network.vnet_common.name

address_prefixes = [
"${var.networking.subnet_cidr_block}"
]

service_endpoints = [
"Microsoft.Web"
]

private_endpoint_network_policies_enabled = true
}
21 changes: 21 additions & 0 deletions src/github-runner/02_container_app_environment.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module "container_app_environment_runner" {
source = "./.terraform/modules/__v3__/container_app_environment_v2"

resource_group_name = azurerm_resource_group.rg_github_runner.name
location = azurerm_resource_group.rg_github_runner.location
name = "${local.project}-github-runner-cae"

subnet_id = module.subnet_runner.id
internal_load_balancer = true
zone_redundant = false

tags = var.tags
log_analytics_workspace_id = data.azurerm_log_analytics_workspace.law_common.id
}

resource "azurerm_management_lock" "lock_cae" {
lock_level = "CanNotDelete"
name = "${local.project}-github-runner-cae"
notes = "This Container App Environment cannot be deleted"
scope = module.container_app_environment_runner.id
}
39 changes: 39 additions & 0 deletions src/github-runner/02_container_app_jobs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module "container_app_job" {

depends_on = [
module.container_app_environment_runner
]

source = "./.terraform/modules/__v3__/container_app_job_gh_runner_v2"

location = var.location
prefix = var.prefix
env_short = var.env_short
resource_group_name = azurerm_resource_group.rg_github_runner.name

job_meta = {
repo = "devops-app-status"
}

key_vault_name = data.azurerm_key_vault.key_vault_common.name
key_vault_rg = data.azurerm_key_vault.key_vault_common.resource_group_name
key_vault_secret_name = var.key_vault_common.pat_secret_name

environment_name = module.container_app_environment_runner.name
environment_rg = module.container_app_environment_runner.resource_group_name

polling_interval_in_seconds = 10
job = {
name = "infra"
repo = "devops-app-status"
polling_interval = 20
}

container = {
cpu = 1
memory = "2Gi"
image = "ghcr.io/pagopa/github-self-hosted-runner-azure:latest"
}

tags = var.tags
}
4 changes: 4 additions & 0 deletions src/github-runner/99_locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
locals {
project = "${var.prefix}-${var.env_short}"
product = "${var.prefix}-${var.env_short}"
}
23 changes: 23 additions & 0 deletions src/github-runner/99_main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "<= 3.116.0"
}
}

backend "azurerm" {}
}

provider "azurerm" {
features {}
}

data "azurerm_subscription" "current" {}

data "azurerm_client_config" "current" {}

module "__v3__" {
# https://github.com/pagopa/terraform-azurerm-v3/releases/tag/v8.48.0
source = "git::https://github.com/pagopa/terraform-azurerm-v3.git?ref=v8.50.0"
}
44 changes: 44 additions & 0 deletions src/github-runner/99_outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
output "subnet_name" {
value = module.subnet_runner.name
description = "Subnet name"
}

output "subnet_id" {
value = module.subnet_runner.id
description = "Subnet id"
}

output "cae_id" {
value = module.container_app_environment_runner.id
description = "Container App Environment id"
}

output "cae_name" {
value = module.container_app_environment_runner.name
description = "Container App Environment name"
}

output "ca_job_id" {
value = module.container_app_job.id
description = "Container App job id"
}

output "ca_job_name" {
value = module.container_app_job.name
description = "Container App job name"
}

output "github_manage_identity_client_id" {
value = module.identity_cd_01.identity_client_id
description = "Managed identity client ID"
}

output "github_manage_identity_principal_id" {
value = module.identity_cd_01.identity_principal_id
description = "Managed identity principal ID"
}

output "github_manage_identity_name" {
value = module.identity_cd_01.identity_app_name
description = "Managed identity name"
}
64 changes: 64 additions & 0 deletions src/github-runner/99_variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
variable "prefix" {
type = string
validation {
condition = (
length(var.prefix) <= 6
)
error_message = "Max length is 6 chars."
}
}

variable "env" {
type = string
}

variable "env_short" {
type = string
validation {
condition = (
length(var.env_short) == 1
)
error_message = "Length must be 1 chars."
}
}

variable "tags" {
type = map(any)
default = {
CreatedBy = "Terraform"
}
}

variable "location" {
type = string
default = "northeurope"
}

variable "location_short" {
type = string
default = "neu"
validation {
condition = length(var.location_short) <= 3
error_message = "The length of the 'location_short' variable must not exceed 3 characters."
}
}


variable "key_vault_common" {
type = object({
name = string
pat_secret_name = string
})
}

variable "networking" {
type = object({
vnet_common_name = string
subnet_cidr_block = string
})
}

variable "law_name" {
type = string
default = "Log Analytics Workspace name"
}
Loading

0 comments on commit 25ebdc8

Please sign in to comment.