@swovohq/fuel 0.2.2-alpha.9 → 0.2.2-alpha.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -69
- package/dist/bin/fuel.js +77 -31
- package/dist/bin/fuel.js.map +1 -1
- package/dist/cleanup/finalize.d.ts.map +1 -1
- package/dist/cleanup/finalize.js +11 -3
- package/dist/cleanup/finalize.js.map +1 -1
- package/dist/commands/config-verify.d.ts.map +1 -1
- package/dist/commands/config-verify.js +14 -6
- package/dist/commands/config-verify.js.map +1 -1
- package/dist/commands/create-app.d.ts.map +1 -1
- package/dist/commands/create-app.js +41 -7
- package/dist/commands/create-app.js.map +1 -1
- package/dist/commands/infra-deploy.d.ts +15 -1
- package/dist/commands/infra-deploy.d.ts.map +1 -1
- package/dist/commands/infra-deploy.js +164 -18
- package/dist/commands/infra-deploy.js.map +1 -1
- package/dist/commands/infra-destroy.d.ts.map +1 -1
- package/dist/commands/infra-destroy.js +3 -3
- package/dist/commands/infra-destroy.js.map +1 -1
- package/dist/commands/infra-init.d.ts +91 -0
- package/dist/commands/infra-init.d.ts.map +1 -1
- package/dist/commands/infra-init.js +644 -113
- package/dist/commands/infra-init.js.map +1 -1
- package/dist/commands/infra-pull.d.ts +8 -0
- package/dist/commands/infra-pull.d.ts.map +1 -0
- package/dist/commands/infra-pull.js +81 -0
- package/dist/commands/infra-pull.js.map +1 -0
- package/dist/commands/list-modules.d.ts.map +1 -1
- package/dist/commands/list-modules.js +10 -3
- package/dist/commands/list-modules.js.map +1 -1
- package/dist/engines/convention.d.ts +2 -2
- package/dist/engines/convention.d.ts.map +1 -1
- package/dist/engines/convention.js +8 -6
- package/dist/engines/convention.js.map +1 -1
- package/dist/engines/dependencies.d.ts +2 -0
- package/dist/engines/dependencies.d.ts.map +1 -1
- package/dist/engines/dependencies.js.map +1 -1
- package/dist/engines/monorepo.d.ts.map +1 -1
- package/dist/engines/monorepo.js.map +1 -1
- package/dist/engines/template-source.d.ts.map +1 -1
- package/dist/engines/template-source.js +3 -1
- package/dist/engines/template-source.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infra/azure-defaults.d.ts +49 -0
- package/dist/infra/azure-defaults.d.ts.map +1 -0
- package/dist/infra/azure-defaults.js +52 -0
- package/dist/infra/azure-defaults.js.map +1 -0
- package/dist/infra/azure-keyvault-client.d.ts +4 -0
- package/dist/infra/azure-keyvault-client.d.ts.map +1 -0
- package/dist/infra/azure-keyvault-client.js +57 -0
- package/dist/infra/azure-keyvault-client.js.map +1 -0
- package/dist/infra/azure-rbac.d.ts +11 -0
- package/dist/infra/azure-rbac.d.ts.map +1 -0
- package/dist/infra/azure-rbac.js +49 -0
- package/dist/infra/azure-rbac.js.map +1 -0
- package/dist/infra/azure-state-storage.d.ts +20 -0
- package/dist/infra/azure-state-storage.d.ts.map +1 -0
- package/dist/infra/azure-state-storage.js +229 -0
- package/dist/infra/azure-state-storage.js.map +1 -0
- package/dist/infra/config-loader.d.ts.map +1 -1
- package/dist/infra/config-loader.js.map +1 -1
- package/dist/infra/config-writer.js +1 -1
- package/dist/infra/credentials.d.ts +2 -2
- package/dist/infra/credentials.d.ts.map +1 -1
- package/dist/infra/credentials.js +8 -4
- package/dist/infra/credentials.js.map +1 -1
- package/dist/infra/dependency-checker.d.ts.map +1 -1
- package/dist/infra/dependency-checker.js.map +1 -1
- package/dist/infra/deployment-detect.d.ts +9 -0
- package/dist/infra/deployment-detect.d.ts.map +1 -0
- package/dist/infra/deployment-detect.js +53 -0
- package/dist/infra/deployment-detect.js.map +1 -0
- package/dist/infra/git-client.d.ts.map +1 -1
- package/dist/infra/git-client.js +6 -10
- package/dist/infra/git-client.js.map +1 -1
- package/dist/infra/github-client.d.ts +7 -0
- package/dist/infra/github-client.d.ts.map +1 -1
- package/dist/infra/github-client.js +47 -7
- package/dist/infra/github-client.js.map +1 -1
- package/dist/infra/github-secrets-client.d.ts.map +1 -1
- package/dist/infra/github-secrets-client.js +2 -2
- package/dist/infra/github-secrets-client.js.map +1 -1
- package/dist/infra/github-token-link.d.ts +4 -0
- package/dist/infra/github-token-link.d.ts.map +1 -0
- package/dist/infra/github-token-link.js +32 -0
- package/dist/infra/github-token-link.js.map +1 -0
- package/dist/infra/orchestrator.d.ts +4 -1
- package/dist/infra/orchestrator.d.ts.map +1 -1
- package/dist/infra/orchestrator.js +218 -63
- package/dist/infra/orchestrator.js.map +1 -1
- package/dist/infra/port-utils.d.ts.map +1 -1
- package/dist/infra/port-utils.js.map +1 -1
- package/dist/infra/preflight.d.ts.map +1 -1
- package/dist/infra/preflight.js +25 -11
- package/dist/infra/preflight.js.map +1 -1
- package/dist/infra/remote-secret.d.ts +14 -0
- package/dist/infra/remote-secret.d.ts.map +1 -0
- package/dist/infra/remote-secret.js +42 -0
- package/dist/infra/remote-secret.js.map +1 -0
- package/dist/infra/s3-state-bucket.d.ts.map +1 -1
- package/dist/infra/s3-state-bucket.js +8 -4
- package/dist/infra/s3-state-bucket.js.map +1 -1
- package/dist/infra/secrets-manager-client.d.ts.map +1 -1
- package/dist/infra/secrets-manager-client.js +8 -5
- package/dist/infra/secrets-manager-client.js.map +1 -1
- package/dist/infra/subprocess.js +1 -1
- package/dist/infra/template-engine.d.ts +14 -5
- package/dist/infra/template-engine.d.ts.map +1 -1
- package/dist/infra/template-engine.js +157 -39
- package/dist/infra/template-engine.js.map +1 -1
- package/dist/infra/tofu-runner.d.ts +4 -3
- package/dist/infra/tofu-runner.d.ts.map +1 -1
- package/dist/infra/tofu-runner.js +40 -34
- package/dist/infra/tofu-runner.js.map +1 -1
- package/dist/infra/types.d.ts +241 -17
- package/dist/infra/types.d.ts.map +1 -1
- package/dist/infra/types.js +419 -22
- package/dist/infra/types.js.map +1 -1
- package/dist/infra-templates/TODO-azure-prod.md +127 -0
- package/dist/infra-templates/modules/azure-container-app/main.tf +124 -0
- package/dist/infra-templates/modules/azure-container-app/outputs.tf +24 -0
- package/dist/infra-templates/modules/azure-container-app/variables.tf +80 -0
- package/dist/infra-templates/modules/azure-container-apps-environment/main.tf +18 -0
- package/dist/infra-templates/modules/azure-container-apps-environment/outputs.tf +14 -0
- package/dist/infra-templates/modules/azure-container-apps-environment/variables.tf +24 -0
- package/dist/infra-templates/modules/azure-container-registry/main.tf +10 -0
- package/dist/infra-templates/modules/azure-container-registry/outputs.tf +14 -0
- package/dist/infra-templates/modules/azure-container-registry/variables.tf +20 -0
- package/dist/infra-templates/modules/azure-front-door/main.tf +80 -0
- package/dist/infra-templates/modules/azure-front-door/outputs.tf +20 -0
- package/dist/infra-templates/modules/azure-front-door/variables.tf +26 -0
- package/dist/infra-templates/modules/azure-github-oidc/main.tf +48 -0
- package/dist/infra-templates/modules/azure-github-oidc/outputs.tf +9 -0
- package/dist/infra-templates/modules/azure-github-oidc/variables.tf +69 -0
- package/dist/infra-templates/modules/azure-key-vault/main.tf +21 -0
- package/dist/infra-templates/modules/azure-key-vault/outputs.tf +11 -0
- package/dist/infra-templates/modules/azure-key-vault/variables.tf +43 -0
- package/dist/infra-templates/modules/azure-monitor/main.tf +29 -0
- package/dist/infra-templates/modules/azure-monitor/outputs.tf +17 -0
- package/dist/infra-templates/modules/azure-monitor/variables.tf +32 -0
- package/dist/infra-templates/modules/azure-network/main.tf +134 -0
- package/dist/infra-templates/modules/azure-network/outputs.tf +44 -0
- package/dist/infra-templates/modules/azure-network/variables.tf +56 -0
- package/dist/infra-templates/modules/azure-postgresql-flexible/main.tf +34 -0
- package/dist/infra-templates/modules/azure-postgresql-flexible/outputs.tf +20 -0
- package/dist/infra-templates/modules/azure-postgresql-flexible/variables.tf +54 -0
- package/dist/infra-templates/modules/azure-redis-cache/main.tf +32 -0
- package/dist/infra-templates/modules/azure-redis-cache/outputs.tf +15 -0
- package/dist/infra-templates/modules/azure-redis-cache/variables.tf +30 -0
- package/dist/infra-templates/modules/azure-resource-group/main.tf +5 -0
- package/dist/infra-templates/modules/azure-resource-group/outputs.tf +11 -0
- package/dist/infra-templates/modules/azure-resource-group/variables.tf +16 -0
- package/dist/infra-templates/modules/azure-sql-database/main.tf +63 -0
- package/dist/infra-templates/modules/azure-sql-database/outputs.tf +20 -0
- package/dist/infra-templates/modules/azure-sql-database/variables.tf +78 -0
- package/dist/infra-templates/modules/azure-storage-account/main.tf +13 -0
- package/dist/infra-templates/modules/azure-storage-account/outputs.tf +16 -0
- package/dist/infra-templates/modules/azure-storage-account/variables.tf +38 -0
- package/dist/infra-templates/modules/cloud-watch/event-bridge.tf +15 -0
- package/dist/infra-templates/modules/cloud-watch/lambda.tf +84 -0
- package/dist/infra-templates/modules/cloud-watch/lambda_function.zip +0 -0
- package/dist/infra-templates/modules/cloud-watch/lambda_function_deploy.zip +0 -0
- package/dist/infra-templates/modules/cloud-watch/main.tf +156 -0
- package/dist/infra-templates/modules/cloud-watch/sns.tf +3 -0
- package/dist/infra-templates/modules/cloud-watch/variables.tf +38 -0
- package/dist/infra-templates/modules/ecs-core/alb.tf +126 -0
- package/dist/infra-templates/modules/ecs-core/cloudwatch.tf +48 -0
- package/dist/infra-templates/modules/ecs-core/iam.tf +95 -0
- package/dist/infra-templates/modules/ecs-core/main.tf +12 -0
- package/dist/infra-templates/modules/ecs-core/outputs.tf +44 -0
- package/dist/infra-templates/modules/ecs-core/secrets.tf +9 -0
- package/dist/infra-templates/modules/ecs-core/security_groups.tf +73 -0
- package/dist/infra-templates/modules/ecs-core/variables.tf +96 -0
- package/dist/infra-templates/modules/ecs-service/ecs_autoscaling.tf +51 -0
- package/dist/infra-templates/modules/ecs-service/ecs_service.tf +39 -0
- package/dist/infra-templates/modules/ecs-service/ecs_task_definition.tf +56 -0
- package/dist/infra-templates/modules/ecs-service/variables.tf +170 -0
- package/dist/infra-templates/modules/elastic-container-registry/main.tf +32 -0
- package/dist/infra-templates/modules/elastic-container-registry/outputs.tf +9 -0
- package/dist/infra-templates/modules/elastic-container-registry/variables.tf +25 -0
- package/dist/infra-templates/modules/github-oidc-role/main.tf +46 -0
- package/dist/infra-templates/modules/github-oidc-role/outputs.tf +4 -0
- package/dist/infra-templates/modules/github-oidc-role/variables.tf +11 -0
- package/dist/infra-templates/modules/guardduty/main.tf +8 -0
- package/dist/infra-templates/modules/iam/main.tf +205 -0
- package/dist/infra-templates/modules/iam/outputs.tf +3 -0
- package/dist/infra-templates/modules/iam/variables.tf +4 -0
- package/dist/infra-templates/modules/random-key/main.tf +11 -0
- package/dist/infra-templates/modules/random-key/outputs.tf +4 -0
- package/dist/infra-templates/modules/random-key/variables.tf +10 -0
- package/dist/infra-templates/modules/redis/main.tf +47 -0
- package/dist/infra-templates/modules/redis/outputs.tf +8 -0
- package/dist/infra-templates/modules/redis/variables.tf +20 -0
- package/dist/infra-templates/modules/relational-database-service/main.tf +44 -0
- package/dist/infra-templates/modules/relational-database-service/outputs.tf +13 -0
- package/dist/infra-templates/modules/relational-database-service/security-group.tf +15 -0
- package/dist/infra-templates/modules/relational-database-service/variables.tf +50 -0
- package/dist/infra-templates/modules/secret/main.tf +14 -0
- package/dist/infra-templates/modules/secret/outputs.tf +3 -0
- package/dist/infra-templates/modules/secret/variables.tf +8 -0
- package/dist/infra-templates/modules/simple-storage-service/main.tf +28 -0
- package/dist/infra-templates/modules/simple-storage-service/variables.tf +4 -0
- package/dist/infra-templates/modules/vpc/data.tf +2 -0
- package/dist/infra-templates/modules/vpc/main.tf +76 -0
- package/dist/infra-templates/modules/vpc/outputs.tf +23 -0
- package/dist/infra-templates/modules/vpc/variables.tf +5 -0
- package/dist/infra-templates/package.json +6 -0
- package/dist/infra-templates/templates/azure/MANUAL_DEPLOY.md +168 -0
- package/dist/infra-templates/templates/azure/backend.tf +8 -0
- package/dist/infra-templates/templates/azure/data.tf +21 -0
- package/dist/infra-templates/templates/azure/default.tfvars +0 -0
- package/dist/infra-templates/templates/azure/locals.tf +116 -0
- package/dist/infra-templates/templates/azure/main.tf +421 -0
- package/dist/infra-templates/templates/azure/outputs.tf +40 -0
- package/dist/infra-templates/templates/azure/providers.tf +65 -0
- package/dist/infra-templates/templates/azure/variables.tf +69 -0
- package/dist/infra-templates/templates/azure/workflows/build_and_deploy.yml +155 -0
- package/dist/infra-templates/templates/azure/workflows/tests.yml +63 -0
- package/dist/infra-templates/templates/ecs/README.md +235 -0
- package/dist/infra-templates/templates/ecs/backend.tf +7 -0
- package/dist/infra-templates/templates/ecs/data.tf +6 -0
- package/dist/infra-templates/templates/ecs/default.tfvars +1 -0
- package/dist/infra-templates/templates/ecs/locals.tf +97 -0
- package/dist/infra-templates/templates/ecs/main.tf +185 -0
- package/dist/infra-templates/templates/ecs/outputs.tf +42 -0
- package/dist/infra-templates/templates/ecs/providers.tf +21 -0
- package/dist/infra-templates/templates/ecs/variables.tf +105 -0
- package/dist/infra-templates/templates/ecs/workflows/build_and_deploy.yml +188 -0
- package/dist/infra-templates/templates/ecs/workflows/tests.yml +65 -0
- package/package.json +10 -2
- package/schema/fuel.schema.json +570 -91
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# NOTE on `registry` + identity auth: a resource cannot reference its own
|
|
2
|
+
# computed attributes (e.g. azurerm_container_app.this.identity[0].principal_id)
|
|
3
|
+
# from within its own configuration - that's a circular reference and won't
|
|
4
|
+
# plan. `registry.identity = "System"` is the documented way to tell the
|
|
5
|
+
# platform "use this container app's own system-assigned identity" (same
|
|
6
|
+
# convention as `secret.identity`). The ACR pull role assignment (created by
|
|
7
|
+
# the parent template, against this module's `principal_id` output) necessarily
|
|
8
|
+
# happens AFTER this resource exists (it needs the identity's principal ID).
|
|
9
|
+
# Configuring `registry` here anyway made Container Apps try to validate that
|
|
10
|
+
# credential during the very first create, before the role assignment exists —
|
|
11
|
+
# the provisioning call hangs and times out ("Operation expired") regardless of
|
|
12
|
+
# which image is actually being pulled. So: no `registry` block here at all: CI
|
|
13
|
+
# wires it up with `az containerapp registry set` once the role assignment is
|
|
14
|
+
# already in place (see build_and_deploy.yml), and ignore_changes below stops
|
|
15
|
+
# `tofu apply` from ever trying to remove what CI configured.
|
|
16
|
+
locals {
|
|
17
|
+
# Container App secret names must be lowercase alphanumeric + '-'; env var names keep
|
|
18
|
+
# the caller's original casing (e.g. STRIPE_SECRET_KEY) via secret_name lookup below.
|
|
19
|
+
secret_names = { for k, v in var.secrets : k => lower(replace(k, "_", "-")) }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
resource "azurerm_container_app" "this" {
|
|
23
|
+
name = var.name
|
|
24
|
+
resource_group_name = var.resource_group_name
|
|
25
|
+
container_app_environment_id = var.container_app_environment_id
|
|
26
|
+
revision_mode = "Single"
|
|
27
|
+
# Matches the "Consumption" profile module.azure-container-apps-environment always declares —
|
|
28
|
+
# explicit so `plan` doesn't perpetually diff against what Azure reports back.
|
|
29
|
+
workload_profile_name = "Consumption"
|
|
30
|
+
|
|
31
|
+
identity {
|
|
32
|
+
type = "SystemAssigned"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
template {
|
|
36
|
+
min_replicas = var.min_replicas
|
|
37
|
+
max_replicas = var.max_replicas
|
|
38
|
+
|
|
39
|
+
container {
|
|
40
|
+
name = var.name
|
|
41
|
+
image = var.image
|
|
42
|
+
cpu = var.cpu
|
|
43
|
+
memory = var.memory
|
|
44
|
+
|
|
45
|
+
dynamic "env" {
|
|
46
|
+
for_each = var.env_vars
|
|
47
|
+
content {
|
|
48
|
+
name = env.key
|
|
49
|
+
value = env.value
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
dynamic "env" {
|
|
54
|
+
for_each = var.secrets
|
|
55
|
+
content {
|
|
56
|
+
name = env.key
|
|
57
|
+
secret_name = local.secret_names[env.key]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# HTTP concurrency-based autoscaling only makes sense for apps that
|
|
63
|
+
# actually receive ingress traffic; workers have no ingress to scale on.
|
|
64
|
+
dynamic "http_scale_rule" {
|
|
65
|
+
for_each = var.external_ingress ? [1] : []
|
|
66
|
+
content {
|
|
67
|
+
name = "${var.name}-http-scale"
|
|
68
|
+
concurrent_requests = var.concurrent_requests
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
dynamic "secret" {
|
|
74
|
+
for_each = var.secrets
|
|
75
|
+
content {
|
|
76
|
+
name = local.secret_names[secret.key]
|
|
77
|
+
value = secret.value
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# Workers (external_ingress = false) get no ingress block at all.
|
|
82
|
+
dynamic "ingress" {
|
|
83
|
+
for_each = var.external_ingress ? [1] : []
|
|
84
|
+
content {
|
|
85
|
+
external_enabled = true
|
|
86
|
+
target_port = var.target_port
|
|
87
|
+
|
|
88
|
+
traffic_weight {
|
|
89
|
+
latest_revision = true
|
|
90
|
+
percentage = 100
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Every public app is fronted by Front Door (custom domain + eventually WAF) — direct
|
|
94
|
+
# hits to the *.azurecontainerapps.io hostname would bypass it entirely. Restrict inbound
|
|
95
|
+
# to Front Door's published backend range (Microsoft's documented pattern for this;
|
|
96
|
+
# resolved to real CIDRs by the caller since this field validates as strict CIDR, not a
|
|
97
|
+
# service tag name). Doesn't stop another tenant's Front Door from proxying through (same
|
|
98
|
+
# shared IP range) — the app itself should also check the X-Azure-FDID header against
|
|
99
|
+
# this project's Front Door ID for that.
|
|
100
|
+
dynamic "ip_security_restriction" {
|
|
101
|
+
for_each = var.front_door_backend_cidrs
|
|
102
|
+
content {
|
|
103
|
+
name = "allow-front-door-${replace(ip_security_restriction.value, "/", "-")}"
|
|
104
|
+
action = "Allow"
|
|
105
|
+
ip_address_range = ip_security_restriction.value
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# var.image is only ever meaningful on the very first create — the ACR tag it
|
|
112
|
+
# points at doesn't exist yet (the CI pipeline that pushes it depends on this same
|
|
113
|
+
# apply having already created the GitHub OIDC identity/repo secrets). Ignore drift
|
|
114
|
+
# on it so a later `az containerapp update` (done by CI once it has a real image)
|
|
115
|
+
# never gets clobbered back by a subsequent `tofu apply`/`--regenerate`.
|
|
116
|
+
lifecycle {
|
|
117
|
+
ignore_changes = [template[0].container[0].image, registry]
|
|
118
|
+
|
|
119
|
+
precondition {
|
|
120
|
+
condition = !var.external_ingress || length(var.front_door_backend_cidrs) > 0
|
|
121
|
+
error_message = "front_door_backend_cidrs must not be empty when external_ingress is true — an empty list removes every ip_security_restriction rule, exposing this Container App directly to the internet instead of only through Front Door."
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
output "id" {
|
|
2
|
+
value = azurerm_container_app.this.id
|
|
3
|
+
description = "The ID of the Container App"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "name" {
|
|
7
|
+
value = azurerm_container_app.this.name
|
|
8
|
+
description = "The name of the Container App"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "fqdn" {
|
|
12
|
+
value = try(azurerm_container_app.this.ingress[0].fqdn, "")
|
|
13
|
+
description = "The FQDN of the Container App ingress, or an empty string when external_ingress is false"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
output "principal_id" {
|
|
17
|
+
value = azurerm_container_app.this.identity[0].principal_id
|
|
18
|
+
description = "Principal ID of the system-assigned managed identity, used by the parent template to grant AcrPull"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
output "latest_revision_name" {
|
|
22
|
+
value = azurerm_container_app.this.latest_revision_name
|
|
23
|
+
description = "The name of the latest Container App revision"
|
|
24
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
variable "name" {
|
|
2
|
+
type = string
|
|
3
|
+
description = "Name of the Container App"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "resource_group_name" {
|
|
7
|
+
type = string
|
|
8
|
+
description = "Name of the resource group in which to create the Container App"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "container_app_environment_id" {
|
|
12
|
+
type = string
|
|
13
|
+
description = "ID of the (Consumption) Container App Environment this app belongs to"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "image" {
|
|
17
|
+
type = string
|
|
18
|
+
description = "Full image reference to run, e.g. \"myacr.azurecr.io/app:latest\""
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
variable "target_port" {
|
|
22
|
+
type = number
|
|
23
|
+
description = "Port the container listens on"
|
|
24
|
+
default = 8080
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
variable "external_ingress" {
|
|
28
|
+
type = bool
|
|
29
|
+
description = "Whether to expose external ingress. Set to false for workers (no ingress block is created)"
|
|
30
|
+
default = true
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
variable "cpu" {
|
|
34
|
+
type = number
|
|
35
|
+
description = "vCPU allocated to the container"
|
|
36
|
+
default = 1
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
variable "memory" {
|
|
40
|
+
type = string
|
|
41
|
+
description = "Memory allocated to the container, e.g. \"2Gi\""
|
|
42
|
+
default = "2Gi"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
variable "min_replicas" {
|
|
46
|
+
type = number
|
|
47
|
+
description = "Minimum number of replicas"
|
|
48
|
+
default = 0
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
variable "max_replicas" {
|
|
52
|
+
type = number
|
|
53
|
+
description = "Maximum number of replicas"
|
|
54
|
+
default = 3
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
variable "concurrent_requests" {
|
|
58
|
+
type = number
|
|
59
|
+
description = "Number of concurrent HTTP requests that triggers scaling. Only relevant when external_ingress is true"
|
|
60
|
+
default = 20
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
variable "env_vars" {
|
|
64
|
+
type = map(string)
|
|
65
|
+
description = "Plain (non-secret) environment variables for the container"
|
|
66
|
+
default = {}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
variable "secrets" {
|
|
70
|
+
type = map(string)
|
|
71
|
+
description = "Name/value pairs exposed as Container App secrets, referenceable via secretRef in env vars"
|
|
72
|
+
default = {}
|
|
73
|
+
sensitive = true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
variable "front_door_backend_cidrs" {
|
|
77
|
+
type = list(string)
|
|
78
|
+
description = "CIDR ranges to allow through ingress (Front Door's backend range) when external_ingress is true. Empty list means no restriction is applied."
|
|
79
|
+
default = []
|
|
80
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
resource "azurerm_container_app_environment" "this" {
|
|
2
|
+
name = var.name
|
|
3
|
+
resource_group_name = var.resource_group_name
|
|
4
|
+
location = var.location
|
|
5
|
+
log_analytics_workspace_id = var.log_analytics_workspace_id
|
|
6
|
+
infrastructure_subnet_id = var.infrastructure_subnet_id
|
|
7
|
+
|
|
8
|
+
# Azure implicitly attaches this default profile to every environment regardless of what's
|
|
9
|
+
# declared here (there's no more "Consumption-only, no workload profile at all" environment
|
|
10
|
+
# type) — leaving it undeclared just meant every plan showed a perpetual diff against the
|
|
11
|
+
# real state. Declare it explicitly so plan reflects reality. Adding a Dedicated/GP profile
|
|
12
|
+
# here later doesn't change this app's plan — that's controlled per-app via
|
|
13
|
+
# azurerm_container_app.workload_profile_name.
|
|
14
|
+
workload_profile {
|
|
15
|
+
name = "Consumption"
|
|
16
|
+
workload_profile_type = "Consumption"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
output "id" {
|
|
2
|
+
value = azurerm_container_app_environment.this.id
|
|
3
|
+
description = "ID of the Container Apps Environment"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "name" {
|
|
7
|
+
value = azurerm_container_app_environment.this.name
|
|
8
|
+
description = "Name of the Container Apps Environment"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "default_domain" {
|
|
12
|
+
value = azurerm_container_app_environment.this.default_domain
|
|
13
|
+
description = "Default domain of the Container Apps Environment"
|
|
14
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
variable "name" {
|
|
2
|
+
description = "Name of the Container Apps Environment"
|
|
3
|
+
type = string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "resource_group_name" {
|
|
7
|
+
description = "Name of the resource group where the environment will be created"
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "location" {
|
|
12
|
+
description = "Azure region where the environment will be created"
|
|
13
|
+
type = string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "log_analytics_workspace_id" {
|
|
17
|
+
description = "ID of the Log Analytics workspace used for Container Apps diagnostics"
|
|
18
|
+
type = string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
variable "infrastructure_subnet_id" {
|
|
22
|
+
description = "Delegated subnet for VNet integration. Egress-only: ingress stays public so Front Door can still reach apps directly."
|
|
23
|
+
type = string
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
resource "azurerm_container_registry" "this" {
|
|
2
|
+
name = var.name
|
|
3
|
+
resource_group_name = var.resource_group_name
|
|
4
|
+
location = var.location
|
|
5
|
+
sku = var.sku
|
|
6
|
+
|
|
7
|
+
# Admin credentials are disabled on purpose: pulls are done via managed
|
|
8
|
+
# identity + role assignment (AcrPull), configured by the parent template.
|
|
9
|
+
admin_enabled = false
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
output "id" {
|
|
2
|
+
value = azurerm_container_registry.this.id
|
|
3
|
+
description = "The ID of the Container Registry"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "login_server" {
|
|
7
|
+
value = azurerm_container_registry.this.login_server
|
|
8
|
+
description = "The URL used to log into the Container Registry"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "name" {
|
|
12
|
+
value = azurerm_container_registry.this.name
|
|
13
|
+
description = "The name of the Container Registry"
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
variable "name" {
|
|
2
|
+
type = string
|
|
3
|
+
description = "Globally unique name for the Container Registry (5-50 alphanumeric characters). Uniqueness is the caller's responsibility."
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "resource_group_name" {
|
|
7
|
+
type = string
|
|
8
|
+
description = "Name of the resource group in which to create the Container Registry"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "location" {
|
|
12
|
+
type = string
|
|
13
|
+
description = "Azure region in which to create the Container Registry"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "sku" {
|
|
17
|
+
type = string
|
|
18
|
+
description = "SKU for the Container Registry"
|
|
19
|
+
default = "Basic"
|
|
20
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
resource "azurerm_cdn_frontdoor_profile" "this" {
|
|
2
|
+
name = var.name
|
|
3
|
+
resource_group_name = var.resource_group_name
|
|
4
|
+
sku_name = var.sku_name
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
resource "azurerm_cdn_frontdoor_endpoint" "this" {
|
|
8
|
+
name = "${var.name}-endpoint"
|
|
9
|
+
cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.this.id
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
resource "azurerm_cdn_frontdoor_origin_group" "this" {
|
|
13
|
+
for_each = var.origins
|
|
14
|
+
|
|
15
|
+
name = "${each.key}-og"
|
|
16
|
+
cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.this.id
|
|
17
|
+
|
|
18
|
+
load_balancing {
|
|
19
|
+
sample_size = 4
|
|
20
|
+
successful_samples_required = 3
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
health_probe {
|
|
24
|
+
protocol = "Https"
|
|
25
|
+
request_type = "HEAD"
|
|
26
|
+
path = "/"
|
|
27
|
+
interval_in_seconds = 100
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
resource "azurerm_cdn_frontdoor_origin" "this" {
|
|
32
|
+
for_each = var.origins
|
|
33
|
+
|
|
34
|
+
name = "${each.key}-origin"
|
|
35
|
+
cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.this[each.key].id
|
|
36
|
+
|
|
37
|
+
host_name = each.value.host_name
|
|
38
|
+
# Without this, Front Door forwards the client's original Host header (the custom domain)
|
|
39
|
+
# straight through to the origin. Container Apps routes ingress by Host header and has no
|
|
40
|
+
# idea about the custom domain (only Front Door's custom domain resource knows it) — it
|
|
41
|
+
# responds "This Container App is stopped or does not exist" for an unrecognized host.
|
|
42
|
+
# Rewrite to the origin's own *.azurecontainerapps.io hostname so it always matches.
|
|
43
|
+
origin_host_header = each.value.host_name
|
|
44
|
+
certificate_name_check_enabled = true
|
|
45
|
+
http_port = each.value.http_port
|
|
46
|
+
https_port = each.value.https_port
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
resource "azurerm_cdn_frontdoor_custom_domain" "this" {
|
|
50
|
+
for_each = { for k, v in var.origins : k => v if v.custom_domain != null }
|
|
51
|
+
|
|
52
|
+
name = "${each.key}-domain"
|
|
53
|
+
cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.this.id
|
|
54
|
+
host_name = each.value.custom_domain
|
|
55
|
+
|
|
56
|
+
tls {
|
|
57
|
+
certificate_type = "ManagedCertificate"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
resource "azurerm_cdn_frontdoor_route" "this" {
|
|
62
|
+
for_each = var.origins
|
|
63
|
+
|
|
64
|
+
name = "${each.key}-route"
|
|
65
|
+
cdn_frontdoor_endpoint_id = azurerm_cdn_frontdoor_endpoint.this.id
|
|
66
|
+
cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.this[each.key].id
|
|
67
|
+
cdn_frontdoor_origin_ids = [azurerm_cdn_frontdoor_origin.this[each.key].id]
|
|
68
|
+
cdn_frontdoor_custom_domain_ids = each.value.custom_domain != null ? [azurerm_cdn_frontdoor_custom_domain.this[each.key].id] : []
|
|
69
|
+
|
|
70
|
+
supported_protocols = ["Http", "Https"]
|
|
71
|
+
patterns_to_match = ["/*"]
|
|
72
|
+
forwarding_protocol = "HttpsOnly"
|
|
73
|
+
https_redirect_enabled = true
|
|
74
|
+
|
|
75
|
+
# All routes share one Front Door endpoint/profile — every route linking to the shared
|
|
76
|
+
# default *.azurefd.net domain with the same "/*" pattern collides the moment a second
|
|
77
|
+
# app is added ("this combination already exists in Route <other-app>-route"). Only fall
|
|
78
|
+
# back to the default domain when an app has no custom domain of its own to route on.
|
|
79
|
+
link_to_default_domain = each.value.custom_domain == null
|
|
80
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
output "endpoint_hostname" {
|
|
2
|
+
value = azurerm_cdn_frontdoor_endpoint.this.host_name
|
|
3
|
+
description = "Hostname of the Front Door endpoint shared by all apps/origins"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "profile_id" {
|
|
7
|
+
value = azurerm_cdn_frontdoor_profile.this.id
|
|
8
|
+
description = "ID of the Front Door profile"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "custom_domain_validation" {
|
|
12
|
+
description = "Per-domain DNS records the domain owner must create: a TXT record at _dnsauth.<host_name> with value validation_token (proves ownership so Azure can issue the managed certificate), and a CNAME from host_name to the shared endpoint_hostname above."
|
|
13
|
+
value = {
|
|
14
|
+
for k, d in azurerm_cdn_frontdoor_custom_domain.this : d.host_name => {
|
|
15
|
+
txt_record_name = "_dnsauth.${d.host_name}"
|
|
16
|
+
txt_record_value = d.validation_token
|
|
17
|
+
cname_target = azurerm_cdn_frontdoor_endpoint.this.host_name
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
variable "name" {
|
|
2
|
+
description = "Name of the Front Door profile"
|
|
3
|
+
type = string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "resource_group_name" {
|
|
7
|
+
description = "Name of the resource group where the Front Door profile will be created"
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "sku_name" {
|
|
12
|
+
description = "SKU for the Front Door profile"
|
|
13
|
+
type = string
|
|
14
|
+
default = "Standard_AzureFrontDoor"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
variable "origins" {
|
|
18
|
+
description = "Map of apps/origins to expose behind the shared Front Door profile/endpoint. The map key is used as the app name and as a suffix for the origin group/origin/route resources of that app."
|
|
19
|
+
type = map(object({
|
|
20
|
+
host_name = string
|
|
21
|
+
http_port = optional(number, 80)
|
|
22
|
+
https_port = optional(number, 443)
|
|
23
|
+
custom_domain = optional(string)
|
|
24
|
+
}))
|
|
25
|
+
default = {}
|
|
26
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
resource "azuread_application" "this" {
|
|
2
|
+
count = var.enabled && var.existing_client_id == null ? 1 : 0
|
|
3
|
+
|
|
4
|
+
display_name = "${var.project_name}-github-actions"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
resource "azuread_service_principal" "this" {
|
|
8
|
+
count = var.enabled && var.existing_client_id == null ? 1 : 0
|
|
9
|
+
|
|
10
|
+
client_id = azuread_application.this[0].client_id
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
resource "azuread_application_federated_identity_credential" "this" {
|
|
14
|
+
for_each = var.enabled && var.existing_client_id == null ? toset(var.branches) : toset([])
|
|
15
|
+
|
|
16
|
+
application_id = azuread_application.this[0].id
|
|
17
|
+
display_name = "github-${each.value}"
|
|
18
|
+
audiences = ["api://AzureADTokenExchange"]
|
|
19
|
+
issuer = "https://token.actions.githubusercontent.com"
|
|
20
|
+
subject = "repo:${var.github_organization}/${var.github_repo_name}:ref:refs/heads/${each.value}"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Looked up (not created) when the app/SP/federated credential were set up out-of-band by a
|
|
24
|
+
# tenant admin — see variables.tf for why. Skipped entirely when the caller already supplies
|
|
25
|
+
# existing_principal_id: the lookup needs Directory.Read.All/Application.Read.All on the
|
|
26
|
+
# deploying SP, which a lot of tenants won't grant just to resolve one known object ID.
|
|
27
|
+
data "azuread_service_principal" "existing" {
|
|
28
|
+
count = var.enabled && var.existing_client_id != null && var.existing_principal_id == null ? 1 : 0
|
|
29
|
+
|
|
30
|
+
client_id = var.existing_client_id
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
locals {
|
|
34
|
+
# null when disabled — the parent template must guard any reference to outputs on `var.enabled`.
|
|
35
|
+
principal_id = var.enabled ? (
|
|
36
|
+
var.existing_principal_id != null ? var.existing_principal_id : (
|
|
37
|
+
var.existing_client_id == null ? azuread_service_principal.this[0].object_id : data.azuread_service_principal.existing[0].object_id
|
|
38
|
+
)
|
|
39
|
+
) : null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
resource "azurerm_role_assignment" "contributor" {
|
|
43
|
+
count = var.enabled && var.manage_role_assignment ? 1 : 0
|
|
44
|
+
|
|
45
|
+
scope = var.role_assignment_scope
|
|
46
|
+
role_definition_name = "Contributor"
|
|
47
|
+
principal_id = local.principal_id
|
|
48
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
output "client_id" {
|
|
2
|
+
value = var.enabled ? (var.existing_client_id != null ? var.existing_client_id : azuread_application.this[0].client_id) : null
|
|
3
|
+
description = "Client ID of the Azure AD application used by GitHub Actions to authenticate via OIDC. Null when disabled."
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "principal_id" {
|
|
7
|
+
value = local.principal_id
|
|
8
|
+
description = "Object ID of the service principal, used by the parent template to grant additional roles (e.g. AcrPush/AcrPull). Null when disabled."
|
|
9
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
variable "project_name" {
|
|
2
|
+
description = "Project name used as prefix for resource names"
|
|
3
|
+
type = string
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "github_organization" {
|
|
7
|
+
description = "GitHub organization name for the OIDC trust subject"
|
|
8
|
+
type = string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "github_repo_name" {
|
|
12
|
+
description = "GitHub repository name for the OIDC trust subject"
|
|
13
|
+
type = string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "branches" {
|
|
17
|
+
description = "Branches allowed to assume the Azure AD application via OIDC. One federated credential is created per branch."
|
|
18
|
+
type = list(string)
|
|
19
|
+
default = ["main"]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
variable "role_assignment_scope" {
|
|
23
|
+
description = "Scope for the Contributor role assignment, typically the resource group ID"
|
|
24
|
+
type = string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
variable "existing_client_id" {
|
|
28
|
+
description = <<-EOT
|
|
29
|
+
Client ID of an app registration + service principal + federated identity credential(s)
|
|
30
|
+
already created out-of-band by a tenant admin. Set this when the deploying SP lacks the
|
|
31
|
+
Entra ID "Application Administrator" role (creating an app registration requires it,
|
|
32
|
+
regardless of subscription-level RBAC) — the module then looks up and reuses that identity
|
|
33
|
+
instead of creating a new one. The Contributor role assignment is still managed by this
|
|
34
|
+
module either way, since that only needs "User Access Administrator" on the subscription.
|
|
35
|
+
EOT
|
|
36
|
+
type = string
|
|
37
|
+
default = null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
variable "existing_principal_id" {
|
|
41
|
+
description = <<-EOT
|
|
42
|
+
Object ID (principal ID) of the service principal identified by existing_client_id, when
|
|
43
|
+
that's already known. Set this to skip looking it up via Microsoft Graph entirely — the
|
|
44
|
+
lookup (data.azuread_service_principal.existing) needs Directory.Read.All or
|
|
45
|
+
Application.Read.All on the deploying SP, which many tenant admins won't grant just to
|
|
46
|
+
resolve one known object. Whoever created the app out-of-band can get this by running
|
|
47
|
+
`az ad sp show --id <existing_client_id> --query id -o tsv`.
|
|
48
|
+
EOT
|
|
49
|
+
type = string
|
|
50
|
+
default = null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
variable "manage_role_assignment" {
|
|
54
|
+
description = <<-EOT
|
|
55
|
+
Whether Terraform should create/manage the Contributor role assignment for this identity.
|
|
56
|
+
Set to false when it was already granted out-of-band alongside existing_client_id (e.g. a
|
|
57
|
+
tenant admin's onboarding runbook already ran `az role assignment create ... --role
|
|
58
|
+
Contributor`) — otherwise Terraform tries to create it again on every apply and fails with
|
|
59
|
+
RoleAssignmentExists.
|
|
60
|
+
EOT
|
|
61
|
+
type = bool
|
|
62
|
+
default = true
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
variable "enabled" {
|
|
66
|
+
description = "Set to false to skip this module entirely (no app, no SP, no role assignment). Use to unblock testing while waiting on a tenant admin for Application Administrator or an existing_client_id."
|
|
67
|
+
type = bool
|
|
68
|
+
default = true
|
|
69
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Application Key Vault (RBAC-based), used by apps to read secrets at runtime.
|
|
2
|
+
# Distinct from the bootstrap vault created by the CLI via SDK.
|
|
3
|
+
resource "azurerm_key_vault" "this" {
|
|
4
|
+
name = var.name
|
|
5
|
+
resource_group_name = var.resource_group_name
|
|
6
|
+
location = var.location
|
|
7
|
+
tenant_id = var.tenant_id
|
|
8
|
+
sku_name = var.sku_name
|
|
9
|
+
|
|
10
|
+
rbac_authorization_enabled = true
|
|
11
|
+
purge_protection_enabled = false
|
|
12
|
+
soft_delete_retention_days = 7
|
|
13
|
+
|
|
14
|
+
public_network_access_enabled = length(var.ip_rules) > 0 ? true : var.public_network_access_enabled
|
|
15
|
+
|
|
16
|
+
network_acls {
|
|
17
|
+
bypass = "AzureServices"
|
|
18
|
+
default_action = var.network_acls_default_action
|
|
19
|
+
ip_rules = var.ip_rules
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
variable "name" {
|
|
2
|
+
type = string
|
|
3
|
+
description = "Key Vault name"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "resource_group_name" {
|
|
7
|
+
type = string
|
|
8
|
+
description = "Resource group where the Key Vault is created"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
variable "location" {
|
|
12
|
+
type = string
|
|
13
|
+
description = "Azure region"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
variable "tenant_id" {
|
|
17
|
+
type = string
|
|
18
|
+
description = "Azure AD tenant ID"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
variable "sku_name" {
|
|
22
|
+
type = string
|
|
23
|
+
description = "Key Vault SKU"
|
|
24
|
+
default = "standard"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
variable "public_network_access_enabled" {
|
|
28
|
+
type = bool
|
|
29
|
+
description = "Allow access from the public internet. Defaults to false: this vault isn't read by anything at runtime today (no VNet/private-endpoint consumer wired up yet), so there's no reason to expose it publicly."
|
|
30
|
+
default = false
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
variable "network_acls_default_action" {
|
|
34
|
+
type = string
|
|
35
|
+
description = "Default action for requests not matched by an IP/VNet rule. Defaults to \"Deny\" — flip to \"Allow\" (or add a private endpoint) only once something outside the vault's own resource group needs to read from it."
|
|
36
|
+
default = "Deny"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
variable "ip_rules" {
|
|
40
|
+
type = list(string)
|
|
41
|
+
description = "Public IPs/CIDRs allowed through the firewall (e.g. the operator machine running `tofu apply`, which needs data-plane access to write secrets). Forces public_network_access_enabled on when non-empty, since Azure ignores network_acls entirely while public access is off."
|
|
42
|
+
default = []
|
|
43
|
+
}
|