AB#2578 Implement Azure IAM in terraform (#562)

* AB#2578 Azure IAM init

* AB#2578 Fixed application owner privileges, added docs

* Add all supported providers to TF lockfile

* Using service principal for role assignment in cluster resource group

Co-authored-by: Malte Poll <mp@edgeless.systems>

* Rephrased header for Azure

Co-authored-by: Malte Poll <mp@edgeless.systems>

* Registry -> Registration typo

Co-authored-by: Malte Poll <mp@edgeless.systems>

* Download lockfile

* File name casing

Co-authored-by: Malte Poll <mp@edgeless.systems>
This commit is contained in:
Moritz Sanft 2022-11-16 20:19:10 +01:00 committed by GitHub
parent cdaf1fc476
commit dfe7f855cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 250 additions and 0 deletions

View File

@ -0,0 +1,50 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/azuread" {
version = "2.30.0"
constraints = "~> 2.30.0"
hashes = [
"h1:MimDtBEnmdMwbriZQzga/kCjDZ1G0+QLVQjrYdBEpdc=",
"h1:Uw4TcmJBEJ71h+oCwwidlkk5jFpyFRDPAFCMs/bT/cw=",
"h1:WnSPiREAFwnBUKREokMdHQ8Cjs47MzvS9pG8VS1ktec=",
"h1:eMxghqjmi2DCdps3dgo2SVOUfebzCatA3OdsTowlqXw=",
"h1:xzNKb+lWPsBTxJiaAJ8ECZnY+D6QNM9tA1qpEncIba0=",
"zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7",
"zh:2e62c193030e04ebb10cc0526119cf69824bf2d7e4ea5a2f45bd5d5fb7221d36",
"zh:2f3c7a35257332d68b778cefc5201a5f044e4914dd03794a4da662ddfe756483",
"zh:35d0d3a1b58fdb8b8c4462d6b7e7016042da43ea9cc734ce897f52a73407d9b0",
"zh:47ede0cd0206ec953d40bf4a80aa6e59af64e26cbbd877614ac424533dbb693b",
"zh:48c190307d4d42ea67c9b8cc544025024753f46cef6ea64db84735e7055a72da",
"zh:6fff9b2c6a962252a70a15b400147789ab369b35a781e9d21cce3804b04d29af",
"zh:7646980cf3438bff29c91ffedb74458febbb00a996638751fbd204ab1c628c9b",
"zh:77aa2fa7ca6d5446afa71d4ff83cb87b70a2f3b72110fc442c339e8e710b2928",
"zh:e20b2b2c37175b89dd0db058a096544d448032e28e3b56e2db368343533a9684",
"zh:eab175b1dfe9865ad9404dccb6d5542899f8c435095aa7c679314b811c717ce7",
"zh:efc862bd78c55d2ff089729e2a34c1831ab4b0644fc11b36ee4ebed00a4797ba",
]
}
provider "registry.terraform.io/hashicorp/azurerm" {
version = "3.31.0"
constraints = "~> 3.31.0"
hashes = [
"h1:AXTMOUd/zMPymRuNeMb/wCzk9IabtHEW7cHwEghqmhc=",
"h1:HdMwAeU+yBk0+3XvFY5v1BkLX+o0ImrfbKamHKO9fmQ=",
"h1:TQtkrjZb0IT9SzzrjJ/gGDiMV0L/rmlR+LmJvmRzBYA=",
"h1:fBDej98yLWwuL3fPrMrwF9Wu+0To2x8EHDEGKH75iOY=",
"h1:zc5rG3g3DUeQQEYpCfqm0tCAlfqxeXc74iQ95EgDv/0=",
"zh:1b61b26373bbb06e811e4ccb762651354d776db574ec904ac32835c98322ab98",
"zh:2ccea8876e54127e16729c09e9c59d164abc2a600230d3fc8331c459f91187af",
"zh:300f35a16f08a19eed08708561ecca044bc570d91e7f863f2b203c78e9df3a5f",
"zh:4e77936cbf555ea068a63095072ad7b636b598da02629375925f8ac539313f96",
"zh:63486a678e9e536a3a996dd2698b7d39d3b65d83a79e14b5520d5e26bde76d47",
"zh:8c620e70cae53b7c9ed923596d441fa5f09ff50bd1379b936e4a88211de86951",
"zh:91cc1b9bc3dfcadfe40750872baf254a8b1f715e2784e3f323edcfebfe5a4012",
"zh:b0b4c3064a58f831ad7ee36baee9bb18fc24cab8ca76902fec8bbc95aefffadf",
"zh:b70ea503c093d6d4fbbcd064c93a2139c8424a6ade6a7d9d869cd7c367f0b050",
"zh:d9738184fccca96bec3ded26c2e10c104423330be25a473d4e5e383b2161cdfe",
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
"zh:fcf1630b47bfae8e9834390b1a5cf4f6fd9ff0cc1ca596e6b60e9327db7529f4",
]
}

View File

@ -0,0 +1,37 @@
# Terraform Azure IAM creation
This terraform configuration creates the necessary Azure resources that need to be available to host a Constellation cluster.
You can create the resources with the following commands:
```sh
mkdir constellation_azure_iam
cd constellation_azure_iam
curl --remote-name-all https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/terraform/azure/iam/{main.tf,output.tf,variables.tf,.terraform.lock.hcl}
terraform init
terraform apply
```
The following terraform output values are available (with their corresponding keys in the Constellation configuration file):
- `subscription_id` (subscription)
- `tenant_id` (tenant)
- `region` (location)
- `base_resource_group_name` (resourceGroup)
- `application_id` (appClientID)
- `uami_id` (userAssignedIdentity)
- `application_client_secret_value` (clientSecretValue) - **Sensitive Value**
You can either get the profile names from the Terraform output and manually add them to your Constellation configuration file according to our [Documentation](https://docs.edgeless.systems/constellation/getting-started/first-steps).
Or you can do this with a `yq` command:
```sh
yq -i "
.provider.azure.subscription = $(terraform output subscription_id) |
.provider.azure.tenant = $(terraform output tenant_id) |
.provider.azure.location = $(terraform output region) |
.provider.azure.resourceGroup = $(terraform output base_resource_group_name) |
.provider.azure.appClientID = $(terraform output application_id) |
.provider.azure.userAssignedIdentity = $(terraform output uami_id) |
.provider.azure.clientSecretValue = $(terraform output application_client_secret_value)
" path/to/constellation-conf.yaml
```
Where `path/to/constellation-conf.yaml` is the path to your Constellation configuration file.

View File

@ -0,0 +1,84 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.31.0"
}
azuread = {
source = "hashicorp/azuread"
version = "~> 2.30.0"
}
}
}
# Configure Azure resource management provider
provider "azurerm" {
features {}
}
# Configure Azure active directory provider
provider "azuread" {
tenant_id = data.azurerm_subscription.current.tenant_id
}
# Access current subscription (available via Azure CLI)
data "azurerm_subscription" "current" {}
# # Access current AzureAD configuration
data "azuread_client_config" "current" {}
# Create base resource group
resource "azurerm_resource_group" "base_resource_group" {
name = var.resource_group_name
location = var.region
}
# Create identity resource group
resource "azurerm_resource_group" "identity_resource_group" {
name = "${var.resource_group_name}-identity"
location = var.region
}
# Create managed identity
resource "azurerm_user_assigned_identity" "identity_uami" {
location = var.region
name = var.service_principal_name
resource_group_name = azurerm_resource_group.identity_resource_group.name
}
# Assign roles to managed identity
resource "azurerm_role_assignment" "virtual_machine_contributor_role" {
scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.resource_group_name}"
role_definition_name = "Virtual Machine Contributor"
principal_id = azurerm_user_assigned_identity.identity_uami.principal_id
}
resource "azurerm_role_assignment" "application_insights_component_contributor_role" {
scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.resource_group_name}"
role_definition_name = "Application Insights Component Contributor"
principal_id = azurerm_user_assigned_identity.identity_uami.principal_id
}
# Create application registration
resource "azuread_application" "base_application" {
display_name = "${var.resource_group_name}-application"
owners = [data.azuread_client_config.current.object_id]
}
resource "azuread_service_principal" "application_principal" {
application_id = azuread_application.base_application.application_id
app_role_assignment_required = false
owners = [data.azuread_client_config.current.object_id]
}
# Set identity as base resource group owner
resource "azurerm_role_assignment" "owner_role" {
scope = "/subscriptions/${data.azurerm_subscription.current.subscription_id}/resourceGroups/${var.resource_group_name}"
role_definition_name = "Owner"
principal_id = azuread_service_principal.application_principal.object_id
}
# Create application secret (password)
resource "azuread_application_password" "base_application_secret" {
application_object_id = azuread_application.base_application.object_id
}

View File

@ -0,0 +1,28 @@
output "subscription_id" {
value = data.azurerm_subscription.current.subscription_id
}
output "tenant_id" {
value = data.azurerm_subscription.current.tenant_id
}
output "region" {
value = var.region
}
output "base_resource_group_name" {
value = var.resource_group_name
}
output "application_id" {
value = azuread_application.base_application.application_id
}
output "uami_id" {
value = azurerm_user_assigned_identity.identity_uami.id
}
output "application_client_secret_value" {
value = azuread_application_password.base_application_secret.value
sensitive = true
}

View File

@ -0,0 +1,37 @@
# Terraform Azure IAM creation
This terraform configuration creates the necessary Azure resources that need to be available to host a Constellation cluster.
You can create the resources with the following commands:
```sh
mkdir constellation_azure_iam
cd constellation_azure_iam
curl --remote-name-all https://raw.githubusercontent.com/edgelesssys/constellation/main/hack/terraform/azure/iam/{main.tf,output.tf,variables.tf,.terraform.lock.hcl}
terraform init
terraform apply
```
The following terraform output values are available (with their corresponding keys in the Constellation configuration file):
- `subscription_id` (subscription)
- `tenant_id` (tenant)
- `region` (location)
- `base_resource_group_name` (resourceGroup)
- `application_id` (appClientID)
- `uami_id` (userAssignedIdentity)
- `application_client_secret_value` (clientSecretValue) - **Sensitive Value**
You can either get the profile names from the Terraform output and manually add them to your Constellation configuration file according to our [Documentation](https://docs.edgeless.systems/constellation/getting-started/first-steps).
Or you can do this with a `yq` command:
```sh
yq -i "
.provider.azure.subscription = $(terraform output subscription_id) |
.provider.azure.tenant = $(terraform output tenant_id) |
.provider.azure.location = $(terraform output region) |
.provider.azure.resourceGroup = $(terraform output base_resource_group_name) |
.provider.azure.appClientID = $(terraform output application_id) |
.provider.azure.userAssignedIdentity = $(terraform output uami_id) |
.provider.azure.clientSecretValue = $(terraform output application_client_secret_value)
" path/to/constellation-conf.yaml
```
Where `path/to/constellation-conf.yaml` is the path to your Constellation configuration file.

View File

@ -0,0 +1,14 @@
variable "resource_group_name" {
type = string
description = "Resource group name"
}
variable "service_principal_name" {
type = string
description = "Service principal name"
}
variable "region" {
type = string
description = "Azure resource location"
}