Verwendete Mittel
Folgende Mittel sind für die Implementation in dieser Umsetzung zum Einsatz gekommen:
Ziele
Folgende Ziele müssen erfüllt werden:
- Dienste wie Pipelines nach bestem Gewissen authorisieren gewisse Änderungen an der Infrastruktur zu machen
- Backend für Terraform mit Entra ID authorisieren
Umsetzung
Entra ID mit OpenID Connect und oauth2.0 stellt die Basis für die Authentifizierung und Authorisierung dar. Um somit Berechtigunen an Service Principals zu erteilen muss die Applikation in Entra zuerst erstellt werden.
Nach der Erstellung der App Registration können die ersten wichtigen Infos ausgelesen werden:

Nach der Registration können die Daten zur Authentifizerung der Applikation mittels OpenID Connect im Entra Portal ausgelesen werden und als Secret in die Pipeline eingeführt werden.

Authorisieren der Pipeline
Die gesamte Application Registration mitsamt Berechtigungserteilung findet im Terraform statt. Um Github als Applikation mit der Pipeline authorisieren zu können, wurden alle nötigen Resourcen und Verbindungen im File github.tf.
locals {
github_roles = [
"Privileged Role Administrator",
"User Administrator"
]
}
data "azurerm_subscription" "top-level" {
for_each = toset(var.subscription_ids)
subscription_id = each.value
}
data "azuread_user" "owner" {
user_principal_name = var.owner
}
resource "azuread_application" "github" {
display_name = "sp-github-shared"
description = "Service Principal for Github"
owners = [data.azuread_user.owner.object_id]
prevent_duplicate_names = true
}
resource "azuread_service_principal" "github" {
account_enabled = true
client_id = azuread_application.github.client_id
tags = ["github"]
owners = [data.azuread_user.owner.object_id]
}
resource "azuread_directory_role" "role" {
for_each = toset(local.github_roles)
display_name = each.value
}
resource "azuread_directory_role_assignment" "github_role_assignment" {
for_each = toset(local.github_roles)
principal_object_id = azuread_service_principal.github.object_id
role_id = azuread_directory_role.role[each.value].template_id
}
resource "azurerm_role_assignment" "github" {
for_each = data.azurerm_subscription.top-level
principal_id = azuread_service_principal.github.object_id
scope = each.value.id
role_definition_name = "Contributor"
}In diesem Fall ist zu sehen dass folgende Resourcen wie folgt aufgebaut sind:
- Die Rolle soll auf alle in der Variable
var.subscription_idsdefinierten Azure Subscriptions angewendet werden. - Es wird die Applikation mitsamt Service Principal erstellt
- Es werden mehrere Rollen auf dem Principal angewandt
Terraform Backend
Der einzige Schritt welches durch klicken und scrollen erstellt wurde ist ein Storage Account. Denn im Falle einer Zerstötung der Infrastruktur seitens Terraform, muss der Storage Container noch stehen können.
Mithilfe der Role Assignment welche in Terraform erstellt wurde, wurde automatisch die richtige Berechtigung zu Erstellung von Resourcen auf Azure inkl. dem ablegen von Daten auf dem Blob Storage im Storage Account erstellt.
Um das Terraform Backend zu initialisieren gibt es 2 Wege eine Verbindung mit diesem Backend zu erstellen:
- Mit az login und einem
backend-file - Mit dem Service Principal
az login
## Interaktives Login
terraform init -backend-config backend.hclJedoch beim Login mit einem Service Principal müssen alle Parameter einer OpenID Verbindung als Parameter übergeben.
Hier ein Beispiel von meiner Pipeline zur Anmeldung über einen Service Principal.
terraform init \
-input=false \
-backend-config="resource_group_name=${{vars.resource_group_name}}" \
-backend-config="storage_account_name=${{vars.storage_account_name}}" \
-backend-config="container_name=${{vars.container_name}}" \
-backend-config="key=${{vars.key}}" \
-backend-config=use_oidc=true \
-backend-config="tenant_id=${{secrets.tenant_id}}" \
-backend-config="client_id=${{secrets.client_id}}" \
-backend-config="client_secret=${{secrets.client_secret}}" \
-backend-config="subscription_id=${{secrets.subscription_id}}"Einsatz
Im tincloud Infrastructure Repository kann im Ordner az/shared das main.tf initialisiert werden.
# az/shared
cd az/shared
terraform init -backend-config backend.hclPasse das .tfvars-file an und übergib es an terraform für plan oder apply
terraform plan -var-file prod.tfvars
terraform apply -var-file prod.tfvarsResourcen
Folgende Resourcen sind zur Umsetzung eingesetzt worden: