Skip to content

Commit 1229c55

Browse files
committed
Azure customer managed resources
1 parent e04d4a8 commit 1229c55

16 files changed

Lines changed: 1039 additions & 0 deletions

customer-managed/azure/terraform/.terraform.lock.hcl

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data "azurerm_client_config" "current" {}
2+
3+
data "azurerm_location" "redpanda" {
4+
location = var.region
5+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
resource "azurerm_user_assigned_identity" "redpanda_agent" {
2+
location = azurerm_resource_group.iam.location
3+
name = "${var.resource_name_prefix}${var.redpanda_agent_identity_name}"
4+
resource_group_name = azurerm_resource_group.iam.name
5+
}
6+
7+
resource "azurerm_user_assigned_identity" "cert_manager" {
8+
location = azurerm_resource_group.iam.location
9+
name = "${var.resource_name_prefix}${var.redpanda_cert_manager_identity_name}"
10+
resource_group_name = azurerm_resource_group.iam.name
11+
}
12+
13+
resource "azurerm_user_assigned_identity" "external_dns" {
14+
location = azurerm_resource_group.iam.location
15+
name = "${var.resource_name_prefix}${var.redpanda_external_dns_identity_name}"
16+
resource_group_name = azurerm_resource_group.iam.name
17+
}
18+
19+
resource "azurerm_user_assigned_identity" "redpanda_cluster" {
20+
location = azurerm_resource_group.iam.location
21+
name = "${var.resource_name_prefix}${var.redpanda_cluster_identity_name}"
22+
resource_group_name = azurerm_resource_group.iam.name
23+
}
24+
25+
resource "azurerm_user_assigned_identity" "redpanda_console" {
26+
location = azurerm_resource_group.iam.location
27+
name = "${var.resource_name_prefix}${var.redpanda_console_identity_name}"
28+
resource_group_name = azurerm_resource_group.iam.name
29+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
locals {
2+
allowed_subnet_ids = [for s in azurerm_subnet.private : s.id]
3+
}
4+
5+
6+
resource "azurerm_key_vault" "vault" {
7+
count = var.redpanda_management_key_vault_name != "" ? 1 : 0
8+
name = "${var.resource_name_prefix}${var.redpanda_management_key_vault_name}"
9+
resource_group_name = azurerm_resource_group.redpanda.name
10+
location = azurerm_resource_group.redpanda.location
11+
sku_name = "standard"
12+
tenant_id = var.azure_tenant_id
13+
14+
public_network_access_enabled = true
15+
16+
enabled_for_deployment = true
17+
enabled_for_disk_encryption = true
18+
enabled_for_template_deployment = true
19+
purge_protection_enabled = true
20+
enable_rbac_authorization = true
21+
22+
network_acls {
23+
bypass = "AzureServices"
24+
default_action = "Allow"
25+
virtual_network_subnet_ids = local.allowed_subnet_ids
26+
}
27+
28+
access_policy {
29+
tenant_id = var.azure_tenant_id
30+
object_id = data.azurerm_client_config.current.object_id
31+
application_id = data.azurerm_client_config.current.client_id
32+
33+
secret_permissions = [
34+
"Set",
35+
"Get",
36+
"List",
37+
"Delete",
38+
"Purge",
39+
"Recover",
40+
"Restore",
41+
"Backup",
42+
]
43+
}
44+
45+
tags = var.tags
46+
}
47+
48+
resource "azurerm_key_vault" "console" {
49+
count = var.redpanda_console_key_vault_name != "" ? 1 : 0
50+
name = "${var.resource_name_prefix}${var.redpanda_console_key_vault_name}"
51+
resource_group_name = azurerm_resource_group.redpanda.name
52+
location = azurerm_resource_group.redpanda.location
53+
sku_name = "standard"
54+
tenant_id = var.azure_tenant_id
55+
56+
public_network_access_enabled = true
57+
58+
enabled_for_deployment = true
59+
enabled_for_disk_encryption = true
60+
enabled_for_template_deployment = true
61+
purge_protection_enabled = true
62+
enable_rbac_authorization = true
63+
64+
network_acls {
65+
bypass = "AzureServices"
66+
default_action = "Allow"
67+
virtual_network_subnet_ids = local.allowed_subnet_ids
68+
}
69+
70+
access_policy {
71+
tenant_id = var.azure_tenant_id
72+
object_id = data.azurerm_client_config.current.object_id
73+
application_id = data.azurerm_client_config.current.client_id
74+
75+
secret_permissions = [
76+
"Set",
77+
"Get",
78+
"List",
79+
"Delete",
80+
"Purge",
81+
"Recover",
82+
"Restore",
83+
"Backup",
84+
]
85+
}
86+
87+
tags = var.tags
88+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
resource "azurerm_virtual_network" "redpanda" {
2+
name = "${var.resource_name_prefix}${var.vnet_name}"
3+
location = var.region
4+
resource_group_name = azurerm_resource_group.network.name
5+
address_space = var.vnet_addresses
6+
7+
tags = var.tags
8+
}
9+
10+
11+
resource "azurerm_subnet" "private" {
12+
for_each = var.private_subnets
13+
14+
name = "${var.resource_name_prefix}${each.value.name}"
15+
resource_group_name = azurerm_resource_group.network.name
16+
virtual_network_name = azurerm_virtual_network.redpanda.name
17+
address_prefixes = [each.value.cidr]
18+
19+
# Use Azure's internal network to reach out to the following Azure services
20+
service_endpoints = [
21+
"Microsoft.Storage.Global",
22+
"Microsoft.AzureActiveDirectory",
23+
"Microsoft.KeyVault"
24+
]
25+
26+
lifecycle {
27+
# AKS automatically configures subnet delegations when the subnets are assigned
28+
# to node pools. To prevent undoing the delegations when network provisioning
29+
# re-runs, we ignore any changes on them.
30+
ignore_changes = [delegation]
31+
}
32+
}
33+
34+
resource "azurerm_subnet" "public" {
35+
for_each = var.egress_subnets
36+
37+
name = "${var.resource_name_prefix}${each.value.name}"
38+
resource_group_name = azurerm_resource_group.network.name
39+
virtual_network_name = azurerm_virtual_network.redpanda.name
40+
address_prefixes = [each.value.cidr]
41+
42+
# Use Azure's internal network to reach out to the following Azure services
43+
service_endpoints = [
44+
"Microsoft.Storage.Global",
45+
"Microsoft.AzureActiveDirectory",
46+
"Microsoft.KeyVault",
47+
]
48+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
terraform {
2+
#backend "azurerm" {}
3+
required_providers {
4+
azurerm = {
5+
source = "hashicorp/azurerm"
6+
version = "=3.98.0"
7+
}
8+
}
9+
}
10+
11+
provider "azurerm" {
12+
features {}
13+
skip_provider_registration = false
14+
15+
client_id = var.azure_client_id
16+
client_secret = var.azure_client_secret
17+
tenant_id = var.azure_tenant_id
18+
subscription_id = var.azure_subscription_id
19+
20+
use_cli = var.azure_use_cli
21+
use_msi = var.azure_use_msi
22+
use_oidc = var.azure_use_oidc
23+
24+
# Always use Entra ID authentication instead of shared static keys
25+
# If set to false, we get
26+
# Error: retrieving queue properties for Storage Account (Subscription: "60fc0bed-3072-4c53-906a-d130a934d520"
27+
# Resource Group Name: "pz-tiered-storage-rg"
28+
# Storage Account Name: "pztieredstorage"): unmarshalling response: could not parse response body
29+
storage_use_azuread = true
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
3+
resource "azurerm_resource_group" "redpanda" {
4+
name = "${var.resource_name_prefix}${var.redpanda_resource_group_name}"
5+
location = var.region
6+
7+
tags = var.tags
8+
}
9+
10+
resource "azurerm_resource_group" "storage" {
11+
name = "${var.resource_name_prefix}${var.redpanda_storage_resource_group_name}"
12+
location = var.region
13+
14+
tags = var.tags
15+
}
16+
17+
resource "azurerm_resource_group" "network" {
18+
name = "${var.resource_name_prefix}${var.redpanda_network_resource_group_name}"
19+
location = var.region
20+
21+
tags = var.tags
22+
}
23+
24+
resource "azurerm_resource_group" "iam" {
25+
name = "${var.resource_name_prefix}${var.redpanda_iam_resource_group_name}"
26+
location = var.region
27+
28+
tags = var.tags
29+
}
30+
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
locals {
2+
create_role_assignment = var.create_role_assignment ? 1 : 0
3+
4+
redpanda_operator_namespace = "redpanda"
5+
6+
# aks_oidc_issuer_url = "https://TODO"
7+
}
8+
9+
// Allow storing Redpanda TF state to storage
10+
resource "azurerm_role_assignment" "assign_identity_storage_blob_data_contributor" {
11+
count = local.create_role_assignment
12+
13+
scope = azurerm_storage_account.management.id
14+
principal_id = azurerm_user_assigned_identity.redpanda_agent.principal_id
15+
role_definition_name = "Storage Blob Data Contributor"
16+
}
17+
18+
// Allow access to key vault
19+
resource "azurerm_role_assignment" "vault_secrets_officer" {
20+
count = local.create_role_assignment
21+
22+
scope = azurerm_resource_group.redpanda.id
23+
principal_id = data.azurerm_client_config.current.object_id
24+
role_definition_name = "Key Vault Secrets Officer"
25+
}
26+
27+
resource "azurerm_role_assignment" "redpanda_agent_redpanda" {
28+
count = local.create_role_assignment
29+
30+
principal_id = azurerm_user_assigned_identity.redpanda_agent.principal_id
31+
scope = azurerm_resource_group.redpanda.id
32+
role_definition_id = azurerm_role_definition.redpanda_agent.role_definition_resource_id
33+
}
34+
35+
resource "azurerm_role_assignment" "redpanda_agent_network" {
36+
count = local.create_role_assignment
37+
38+
principal_id = azurerm_user_assigned_identity.redpanda_agent.principal_id
39+
scope = azurerm_resource_group.network.id
40+
role_definition_id = azurerm_role_definition.redpanda_agent.role_definition_resource_id
41+
}
42+
43+
resource "azurerm_role_assignment" "redpanda_agent_tiered_storage" {
44+
count = local.create_role_assignment
45+
46+
principal_id = azurerm_user_assigned_identity.redpanda_agent.principal_id
47+
scope = azurerm_resource_group.storage.id
48+
role_definition_id = azurerm_role_definition.redpanda_agent.role_definition_resource_id
49+
}
50+
51+
resource "azurerm_role_assignment" "redpanda_agent_iam" {
52+
count = local.create_role_assignment
53+
54+
principal_id = azurerm_user_assigned_identity.redpanda_agent.principal_id
55+
scope = azurerm_resource_group.iam.id
56+
role_definition_id = azurerm_role_definition.redpanda_agent.role_definition_resource_id
57+
}
58+
59+
resource "azurerm_role_assignment" "redpanda_cluster_network_contributor" {
60+
count = local.create_role_assignment
61+
62+
scope = azurerm_resource_group.network.id
63+
principal_id = azurerm_user_assigned_identity.redpanda_cluster.principal_id
64+
role_definition_name = "Network Contributor"
65+
}
66+
67+
resource "azurerm_role_assignment" "redpanda_private_link" {
68+
count = local.create_role_assignment
69+
70+
principal_id = azurerm_user_assigned_identity.redpanda_cluster.principal_id
71+
scope = azurerm_resource_group.redpanda.id
72+
role_definition_id = azurerm_role_definition.redpanda_private_link.role_definition_resource_id
73+
}
74+
75+
resource "azurerm_role_assignment" "redpanda_cluster" {
76+
count = local.create_role_assignment
77+
78+
principal_id = azurerm_user_assigned_identity.redpanda_cluster.principal_id
79+
# See https://learn.microsoft.com/en-us/azure/role-based-access-control/troubleshooting?tabs=bicep#symptom---assigning-a-role-to-a-new-principal-sometimes-fails
80+
principal_type = "ServicePrincipal"
81+
scope = azurerm_storage_account.tiered_storage.id
82+
role_definition_name = "Storage Blob Data Contributor"
83+
}
84+
85+
resource "azurerm_role_assignment" "redpanda_console" {
86+
count = local.create_role_assignment
87+
88+
principal_id = azurerm_user_assigned_identity.redpanda_console.principal_id
89+
scope = azurerm_key_vault.console[0].id
90+
role_definition_id = azurerm_role_definition.redpanda_console.role_definition_resource_id
91+
}
92+
93+
# federated identity is done in TF provisioner.
94+
# resource "azurerm_federated_identity_credential" "redpanda_cluster" {
95+
# count = local.create_role_assignment
96+
# name = var.redpanda_cluster_workload_identity_name
97+
# resource_group_name = azurerm_resource_group.redpanda.name
98+
# audience = ["api://AzureADTokenExchange"]
99+
# ## We know the oidc issuer url only after AKS cluster is created.
100+
# ## Check whether RP can come up if this resource is created during cluster creation.
101+
# ## If yes, we will have to ask customer to apply when we have the oidc issuer url.
102+
# ## In TF, issuer is required. But in AZ cli, it is optional in https://learn.microsoft.com/en-us/cli/azure/identity/federated-credential?view=azure-cli-latest
103+
# issuer = local.aks_oidc_issuer_url
104+
# parent_id = azurerm_user_assigned_identity.redpanda_cluster.id
105+
# subject = "system:serviceaccount:${local.redpanda_operator_namespace}:${azurerm_user_assigned_identity.redpanda_cluster.name}"
106+
# }
107+
108+
resource "azurerm_role_assignment" "cert_manager" {
109+
count = local.create_role_assignment
110+
# In TF provisioner, the scope is a DNS zone specific resource. We change it to RG here since DNS zone is not avaiable until cluster is being deployed.
111+
# scope = "/subscriptions/60fc0bed-3072-4c53-906a-d130a934d520/resourceGroups/rg-rpcloud-cqclghd44f471cmf8ojg/providers/Microsoft.Network/dnsZones/cqclghd44f471cmf8ojg.byoc.ign.cloud.redpanda.com"
112+
scope = azurerm_resource_group.redpanda.id
113+
role_definition_name = "DNS Zone Contributor"
114+
principal_id = azurerm_user_assigned_identity.cert_manager.principal_id
115+
# See https://learn.microsoft.com/en-us/azure/role-based-access-control/troubleshooting?tabs=bicep#symptom---assigning-a-role-to-a-new-principal-sometimes-fails
116+
principal_type = "ServicePrincipal"
117+
}
118+
119+
resource "azurerm_role_assignment" "external_dns_zone_contributor" {
120+
count = local.create_role_assignment
121+
# In TF provisioner, the scope is a DNS zone specific resource. We change it to RG here since DNS zone is not avaiable until cluster is being deployed.
122+
#scope = "/subscriptions/60fc0bed-3072-4c53-906a-d130a934d520/resourceGroups/rg-rpcloud-cqclghd44f471cmf8ojg/providers/Microsoft.Network/dnsZones/cqclghd44f471cmf8ojg.byoc.ign.cloud.redpanda.com"
123+
scope = azurerm_resource_group.redpanda.id
124+
role_definition_name = "DNS Zone Contributor"
125+
principal_id = azurerm_user_assigned_identity.external_dns.principal_id
126+
# See https://learn.microsoft.com/en-us/azure/role-based-access-control/troubleshooting?tabs=bicep#symptom---assigning-a-role-to-a-new-principal-sometimes-fails
127+
principal_type = "ServicePrincipal"
128+
}
129+
130+
resource "azurerm_role_assignment" "external_dns_rgreader" {
131+
count = local.create_role_assignment
132+
scope = azurerm_resource_group.redpanda.id
133+
role_definition_name = "Reader"
134+
principal_id = azurerm_user_assigned_identity.external_dns.principal_id
135+
# See https://learn.microsoft.com/en-us/azure/role-based-access-control/troubleshooting?tabs=bicep#symptom---assigning-a-role-to-a-new-principal-sometimes-fails
136+
principal_type = "ServicePrincipal"
137+
}
138+

0 commit comments

Comments
 (0)