Skip to content

Add production-ready Azure lab with identity chain - #14

Merged
lonegunmanb merged 3 commits into
mainfrom
copilot/add-azure-experiment-lab
May 16, 2026
Merged

Add production-ready Azure lab with identity chain#14
lonegunmanb merged 3 commits into
mainfrom
copilot/add-azure-experiment-lab

Conversation

Copilot AI commented May 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Added terraform-production-ready-azure Killercoda scenario using miniblue Azure resources, VM support, module refactoring, moved blocks, and Terragrunt state isolation.
  • Upgraded the lab into a full production-readiness walkthrough with Load Balancer, Cosmos DB, Storage, App Configuration, Key Vault, user-assigned managed identity, and RBAC role assignments.
  • Replaced VM password authentication with generated SSH keys and UAI wiring.
  • Switched Key Vault to RBAC authorization and added vault host registration for miniblue Key Vault data-plane calls.
  • Added step 6 to validate the end-to-end workload identity chain via IMDS token retrieval and Key Vault secret access.
  • Registered the scenario and added an Azure lab button to the production-ready code chapter.
  • Bumped the shared miniblue image pin to the latest sha-cf2cb7f tag and synced generated references.

Validation

  • npm run build
  • /tmp/terraform fmt -check -recursive terraform-tutorial/terraform-production-ready-azure
  • Sequential terraform init -backend=false + terraform validate for step1-step4 and step5 layer configs
  • CodeQL checker: no analyzable language changes detected

Copilot AI and others added 2 commits May 16, 2026 13:36
Agent-Logs-Url: https://github.com/lonegunmanb/terraform-tutorial/sessions/7985c27b-443f-4090-8211-4b41374fb0d8

Co-authored-by: lonegunmanb <2233414+lonegunmanb@users.noreply.github.com>
Agent-Logs-Url: https://github.com/lonegunmanb/terraform-tutorial/sessions/7985c27b-443f-4090-8211-4b41374fb0d8

Co-authored-by: lonegunmanb <2233414+lonegunmanb@users.noreply.github.com>
@lonegunmanb

Copy link
Copy Markdown
Owner

@copilot 请按下面这份升级方案改 PR #14,把它从"教模块化"升级成"教完整生产姿势"。

上下文(请先读,省你重新探查)

1. 上游 miniblue 现状(已就绪,不用再等)

  • Microsoft.KeyVault/vaults 全 ARM CRUD —— lonegunmanb/miniblue#50 已 merge
  • ✅ 8 个内置 RBAC role,含 Key Vault Secrets User / Storage Blob Data Contributor / App Configuration Data Reader / Cosmos DB Account Reader Role
  • Microsoft.ManagedIdentity/userAssignedIdentities 全 ARM CRUD(principalId/clientId/tenantId 确定性派生)
  • ✅ VM identity {} 块 echo back
  • ✅ IMDS /metadata/identity/oauth2/token
  • ✅ Key Vault data plane https://{vault}.vault.azure.net/secrets/...(TLS 证书已签 *.vault.azure.net
  • ✅ 通过 lonegunmanb/miniblue#53 设计的全部 probes

也就是说:100% Terraform 原生 lab、无需 azlocal 旁路 seed,现在可以做到了。

2. 本仓库现状

  • PR Add production-ready Azure lab with identity chain #14(本 PR,分支 copilot/add-azure-experiment-lab):原始版本,单体 + moved + Terragrunt,但用明文密码、没有 KV/UAI/RBAC
  • PR #15(分支 copilot/add-azure-hands-on-experiment):PR body 误标为 "No code changes",实际包含 4295 行升级代码,每个 step 都加入了 KV/UAI/RBAC/AppConfig + Load Balancer + VM identity 块 + modules/security

PR #15 的代码内容应当合并进 PR #14;PR #15 完成后会被关闭。

你要做的任务

Task 1 — 合并 PR #15 的代码

copilot/add-azure-hands-on-experiment 分支的所有文件改动 rebase / cherry-pick 到当前分支 copilot/add-azure-experiment-lab。重点:

Task 2 — VM 升级为 SSH key + UAI

PR #15assets/stage/step{2,3,4}/modules/web/main.tf 仍然 admin_password = "Miniblue!Pass1" + disable_password_authentication = false。改成:

resource "azurerm_linux_virtual_machine" "app" {
  # ...
  admin_username                  = "azureuser"
  disable_password_authentication = true                    # ✅ 不再有密码

  admin_ssh_key {
    username   = "azureuser"
    public_key = var.web_ssh_public_key                     # 新增 var
  }

  identity {
    type         = "UserAssigned"
    identity_ids = [var.app_identity_id]
  }

  lifecycle {
    ignore_changes = [custom_data]                          # 移除原来的 admin_password / identity ignore
  }
}

var.web_ssh_public_key 在各 step 根 main.tftls_private_key 资源生成(避免学员准备 SSH key),传进 module。

Task 3 — KV 改用 RBAC 授权模式

PR #15assets/stage/step{2,3,4}/modules/security/main.tf(step4 才有 modules/security,step2/3 在根 main.tf)里:

resource "azurerm_key_vault" "app" {
  # ...
  enable_rbac_authorization = true                          # ✅ 关键
  # ❌ 删除 access_policy {} 块
}

azurerm_role_assignment.keyvault(授 Key Vault Secrets User 给 UAI)已经存在 —— 保留,它现在成为唯一的授权路径。这与 enable_rbac_authorization = true 的真实 Azure 语义一致,也与 miniblue#50 的设计意图一致。

Task 4 — setup-common.sh 加 *.vault.azure.net hosts

azurerm_key_vault_secret 走 data plane URL https://{vault}.vault.azure.net/secrets/...。Killercoda 容器里需要把这些主机名解析到 127.0.0.1。

assets/setup-common.shstart_miniblue 函数 return 0 之前加:

# Resolve *.vault.azure.net to local miniblue so that
# azurerm_key_vault_secret data-plane calls land on the right service.
write_vault_hosts() {
  for v in "$@"; do
    grep -q "${v}.vault.azure.net" /etc/hosts \
      || echo "127.0.0.1 ${v}.vault.azure.net" >> /etc/hosts
  done
}

然后在 foreground.sh 启动末尾调用:

# Pre-register the vault names this lab will create.
# Pattern matches `${app_name}-${env}-kv` truncated to 24 chars
write_vault_hosts "webapp-dev-kv" "webapp-dev-lab-kv"

由于 app_name 里有一个 random_string.suffix(来自 PR #15 的 step main.tf),完整 vault 名要等 apply 之后才知道。两种处理方式选一种:

  • (a) 推荐:在 step5 的 setup-stage.sh(如果有)里,apply 完成后再 write_vault_hosts $(terraform output -raw key_vault_name)
  • (b) 妥协:把 random_string.suffix 改成固定值(比如 "lab"),这样 vault 名可预测,setup 阶段就能写好 hosts。考虑到这是教学用,(b) 更稳,建议直接采用

如果走 (b),记得把 step2/3/4 的 random_string.suffix.result 全替换成 "lab" 字面量。

Task 5 — 新增 step 6:运行时身份链验证(教学高潮)

新增文件:

terraform-tutorial/terraform-production-ready-azure/step6/text.md

# 第六步:验证工作负载身份链端到端

前五步完成了模块化拆分和状态隔离。这一步不写新代码,而是手动跑一遍**运行时身份链**——看 step 4 用 Terraform 声明的 UAI + role_assignment + KV + secret 在数据面是不是真的能串起来。

## 1. 取出 vault 名和 secret 名

```bash
cd /root/stage/step5
VAULT=$(terragrunt --terragrunt-working-dir security output -raw key_vault_name)
SECRET=$(terragrunt --terragrunt-working-dir security output -raw db_credentials_secret_name)
echo "Vault=$VAULT  Secret=$SECRET"
```

## 2. 模拟"在 VM 内部"——从 IMDS 拿 token

```bash
TOKEN=$(curl -s -H "Metadata: true" \
  "http://localhost:4566/metadata/identity/oauth2/token?resource=https://vault.azure.net/" \
  | jq -r .access_token)
echo "Got token: ${TOKEN:0:24}..."
```

## 3. 用 token 调 Key Vault data plane 读 secret

```bash
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://${VAULT}.vault.azure.net/secrets/${SECRET}?api-version=7.4" | jq .
```

返回值就是 step 4 中 `azurerm_key_vault_secret.db_credentials` 写入的 JSON 凭证。**整条链路完全由 Terraform 声明,运行时模拟真实 Azure VM 内的工作负载行为**## 思考题

如果把 step 4 的 `azurerm_role_assignment.keyvault` 删掉,第 3 步还会成功吗?

**答案**:在 miniblue 上会,因为它不强制鉴权([miniblue RBAC docs](https://github.com/lonegunmanb/miniblue/blob/main/website/docs/services/rbac.md));在真实 Azure 上不会,会返回 `403 Forbidden`。这正是为什么生产代码必须把 `role_assignment` 作为架构的一等公民——miniblue 让你**练习写对的代码**,真实 Azure 才**惩罚你写错的代码**

Copilot AI commented May 16, 2026

Copy link
Copy Markdown
Contributor Author

@copilot 请按下面这份升级方案改 PR #14,把它从"教模块化"升级成"教完整生产姿势"。

上下文(请先读,省你重新探查)

...

已在 e5ec40e 完成:合入 PR #15 场景升级,VM 改为生成 SSH key + UAI,Key Vault 改为 RBAC 授权,补充 vault host 注册,并新增 step 6 端到端身份链验证。已跑 Terraform fmt/validate、npm run build 和 CodeQL checker。

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • checkpoint-api.hashicorp.com
    • Triggering command: /tmp/terraform /tmp/terraform version (dns block)
    • Triggering command: /tmp/terraform /tmp/terraform fmt -recursive terraform-tutorial/terraform-production-ready-azure (dns block)
    • Triggering command: /tmp/terraform /tmp/terraform init -backend=false -input=false (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Add Azure version of production-ready lab Add production-ready Azure lab with identity chain May 16, 2026
@lonegunmanb
lonegunmanb marked this pull request as ready for review May 16, 2026 23:46
@lonegunmanb
lonegunmanb merged commit 210f530 into main May 16, 2026
1 check passed
@lonegunmanb
lonegunmanb deleted the copilot/add-azure-experiment-lab branch May 16, 2026 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants