Skip to content

Commit 14c18b2

Browse files
committed
fix/make container apps a single instance resource as per AVM
1 parent 693b74a commit 14c18b2

File tree

7 files changed

+98
-85
lines changed

7 files changed

+98
-85
lines changed

README.md

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ The following providers are used by this module:
4949
The following resources are used by this module:
5050

5151
- [azapi_resource.container_app](https://registry.terraform.io/providers/Azure/azapi/1.9.0/docs/resources/resource) (resource)
52+
- [azurerm_management_lock.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock) (resource)
5253
- [azurerm_resource_group_template_deployment.telemetry](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group_template_deployment) (resource)
54+
- [azurerm_role_assignment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
5355
- [random_id.telem](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) (resource)
5456
- [azurerm_resource_group.rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) (data source)
5557

@@ -71,7 +73,7 @@ Description: Specifies the container apps in the managed environment.
7173
Type:
7274

7375
```hcl
74-
list(object({
76+
object({
7577
name = string
7678
revision_mode = optional(string, "Single")
7779
@@ -255,7 +257,7 @@ list(object({
255257
storageType = string
256258
})))
257259
})
258-
}))
260+
})
259261
```
260262

261263
### <a name="input_name"></a> [name](#input\_name)
@@ -292,6 +294,42 @@ Type: `string`
292294

293295
Default: `null`
294296

297+
### <a name="input_lock"></a> [lock](#input\_lock)
298+
299+
Description: The lock level to apply to the Container App. Default is `None`. Possible values are `None`, `CanNotDelete`, and `ReadOnly`.
300+
301+
Type:
302+
303+
```hcl
304+
object({
305+
name = optional(string, null)
306+
kind = optional(string, "None")
307+
308+
})
309+
```
310+
311+
Default: `{}`
312+
313+
### <a name="input_role_assignments"></a> [role\_assignments](#input\_role\_assignments)
314+
315+
Description: required AVM interfaces
316+
317+
Type:
318+
319+
```hcl
320+
map(object({
321+
role_definition_id_or_name = string
322+
principal_id = string
323+
description = optional(string, null)
324+
skip_service_principal_aad_check = optional(bool, true)
325+
condition = optional(string, null)
326+
condition_version = optional(string, "2.0")
327+
delegated_managed_identity_resource_id = optional(string)
328+
}))
329+
```
330+
331+
Default: `{}`
332+
295333
### <a name="input_tags"></a> [tags](#input\_tags)
296334

297335
Description: Custom tags to apply to the resource.

examples/default/README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ module "container_app" {
5656
container_app_environment_resource_id = azurerm_container_app_environment.this.id
5757
5858
workload_profile_name = "Consumption"
59-
container_apps = [{
59+
container_apps = {
6060
name = "helloworld"
6161
configuration = {
6262
ingress = {
@@ -77,8 +77,7 @@ module "container_app" {
7777
maxReplicas = 1
7878
}
7979
}
80-
}
81-
]
80+
}
8281
}
8382
```
8483

examples/default/main.tf

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module "container_app" {
5050
container_app_environment_resource_id = azurerm_container_app_environment.this.id
5151

5252
workload_profile_name = "Consumption"
53-
container_apps = [{
53+
container_apps = {
5454
name = "helloworld"
5555
configuration = {
5656
ingress = {
@@ -71,6 +71,5 @@ module "container_app" {
7171
maxReplicas = 1
7272
}
7373
}
74-
}
75-
]
74+
}
7675
}

locals.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
locals {
2-
location = var.location != null ? var.location : data.azurerm_resource_group.rg.location
2+
location = var.location != null ? var.location : data.azurerm_resource_group.rg.location
3+
role_definition_resource_substring = "/providers/Microsoft.Authorization/roleDefinitions"
34
}

main.tf

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ data "azurerm_resource_group" "rg" {
33
}
44

55
resource "azapi_resource" "container_app" {
6-
for_each = { for app in var.container_apps : app.name => app }
76
type = "Microsoft.App/containerApps@2023-05-01"
87
schema_validation_enabled = false
98
name = var.name
@@ -18,38 +17,38 @@ resource "azapi_resource" "container_app" {
1817
body = jsonencode({
1918
properties = {
2019
configuration = {
21-
activeRevisionsMode = try(each.value.revision_mode, "Single")
22-
dapr = try(each.value.dapr, null)
23-
ingress = try(each.value.ingress, null)
24-
maxInactiveRevisions = try(each.value.maxInactiveRevisions, null)
25-
registries = try(each.value.registries, null)
26-
secrets = try(each.value.secrets, null)
27-
service = try(each.value.service, null)
20+
activeRevisionsMode = try(var.container_apps.revision_mode, "Single")
21+
dapr = try(var.container_apps.dapr, null)
22+
ingress = try(var.container_apps.ingress, null)
23+
maxInactiveRevisions = try(var.container_apps.maxInactiveRevisions, null)
24+
registries = try(var.container_apps.registries, null)
25+
secrets = try(var.container_apps.secrets, null)
26+
service = try(var.container_apps.service, null)
2827
}
2928
environmentId = var.container_app_environment_resource_id
30-
template = each.value.template
29+
template = var.container_apps.template
3130
workloadProfileName = var.workload_profile_name
3231
}
3332
})
3433

3534
response_export_values = ["identity"]
3635
}
3736

38-
# resource "azurerm_management_lock" "this" {
39-
# count = var.lock.kind != "None" ? 1 : 0
40-
# name = coalesce(var.lock.name, "lock-${var.name}")
41-
# scope = azapi_resource.container_app.id
42-
# lock_level = var.lock.kind
43-
# }
37+
resource "azurerm_management_lock" "this" {
38+
count = var.lock.kind != "None" ? 1 : 0
39+
name = coalesce(var.lock.name, "lock-${var.name}")
40+
scope = azapi_resource.container_app.id
41+
lock_level = var.lock.kind
42+
}
4443

45-
# resource "azurerm_role_assignment" "this" {
46-
# for_each = var.role_assignments
47-
# scope = azapi_resource.container_app.id
48-
# role_definition_id = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? each.value.role_definition_id_or_name : null
49-
# role_definition_name = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? null : each.value.role_definition_id_or_name
50-
# principal_id = each.value.principal_id
51-
# condition = each.value.condition
52-
# condition_version = each.value.condition_version
53-
# skip_service_principal_aad_check = each.value.skip_service_principal_aad_check
54-
# delegated_managed_identity_resource_id = each.value.delegated_managed_identity_resource_id
55-
# }
44+
resource "azurerm_role_assignment" "this" {
45+
for_each = var.role_assignments
46+
scope = azapi_resource.container_app.id
47+
role_definition_id = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? each.value.role_definition_id_or_name : null
48+
role_definition_name = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? null : each.value.role_definition_id_or_name
49+
principal_id = each.value.principal_id
50+
condition = each.value.condition
51+
condition_version = each.value.condition_version
52+
skip_service_principal_aad_check = each.value.skip_service_principal_aad_check
53+
delegated_managed_identity_resource_id = each.value.delegated_managed_identity_resource_id
54+
}

variables.containerapps.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ variable "workload_profile_name" {
3434

3535
variable "container_apps" {
3636
description = "Specifies the container apps in the managed environment."
37-
type = list(object({
37+
type = object({
3838
name = string
3939
revision_mode = optional(string, "Single")
4040

@@ -218,5 +218,5 @@ variable "container_apps" {
218218
storageType = string
219219
})))
220220
})
221-
}))
221+
})
222222
}

variables.tf

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,54 +16,31 @@ variable "resource_group_name" {
1616

1717

1818
//required AVM interfaces
19+
variable "role_assignments" {
20+
type = map(object({
21+
role_definition_id_or_name = string
22+
principal_id = string
23+
description = optional(string, null)
24+
skip_service_principal_aad_check = optional(bool, true)
25+
condition = optional(string, null)
26+
condition_version = optional(string, "2.0")
27+
delegated_managed_identity_resource_id = optional(string)
28+
}))
29+
default = {}
30+
}
1931

20-
# variable "diagnostic_settings" {
21-
# type = map(object({
22-
# name = optional(string, null)
23-
# log_categories_and_groups = optional(set(string), ["allLogs"])
24-
# metric_categories = optional(set(string), ["AllMetrics"])
25-
# log_analytics_destination_type = optional(string, "Dedicated")
26-
# workspace_resource_id = optional(string, null)
27-
# storage_account_resource_id = optional(string, null)
28-
# event_hub_authorization_rule_resource_id = optional(string, null)
29-
# event_hub_name = optional(string, null)
30-
# marketplace_partner_resource_id = optional(string, null)
31-
# }))
32-
# default = {}
33-
# nullable = false
34-
35-
# validation {
36-
# condition = alltrue([for _, v in var.diagnostic_settings : contains(["Dedicated", "AzureDiagnostics"], v.log_analytics_destination_type)])
37-
# error_message = "Log analytics destination type must be one of: 'Dedicated', 'AzureDiagnostics'."
38-
# }
39-
# }
40-
41-
42-
# variable "role_assignments" {
43-
# type = map(object({
44-
# role_definition_id_or_name = string
45-
# principal_id = string
46-
# description = optional(string, null)
47-
# skip_service_principal_aad_check = optional(bool, true)
48-
# condition = optional(string, null)
49-
# condition_version = optional(string, "2.0")
50-
# delegated_managed_identity_resource_id = optional(string)
51-
# }))
52-
# default = {}
53-
# }
54-
55-
# variable "lock" {
56-
# type = object({
57-
# name = optional(string, null)
58-
# kind = optional(string, "None")
32+
variable "lock" {
33+
type = object({
34+
name = optional(string, null)
35+
kind = optional(string, "None")
5936

6037

61-
# })
62-
# description = "The lock level to apply to the Container App. Default is `None`. Possible values are `None`, `CanNotDelete`, and `ReadOnly`."
63-
# default = {}
64-
# nullable = false
65-
# validation {
66-
# condition = contains(["CanNotDelete", "ReadOnly", "None"], var.lock.kind)
67-
# error_message = "The lock level must be one of: 'None', 'CanNotDelete', or 'ReadOnly'."
68-
# }
69-
# }
38+
})
39+
description = "The lock level to apply to the Container App. Default is `None`. Possible values are `None`, `CanNotDelete`, and `ReadOnly`."
40+
default = {}
41+
nullable = false
42+
validation {
43+
condition = contains(["CanNotDelete", "ReadOnly", "None"], var.lock.kind)
44+
error_message = "The lock level must be one of: 'None', 'CanNotDelete', or 'ReadOnly'."
45+
}
46+
}

0 commit comments

Comments
 (0)