Skip to content

Commit 95f74d8

Browse files
feat: add Azure VM extension and run command modules (#1) (#158)
merge branch for external contributions
1 parent c47eeb6 commit 95f74d8

23 files changed

Lines changed: 1365 additions & 141 deletions

README.md

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ The following resources are used by this module:
5353
- [azurerm_role_assignment.this_virtual_machine](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
5454
- [azurerm_virtual_machine_data_disk_attachment.this_linux](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_data_disk_attachment) (resource)
5555
- [azurerm_virtual_machine_data_disk_attachment.this_windows](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_data_disk_attachment) (resource)
56-
- [azurerm_virtual_machine_extension.this_extension](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) (resource)
57-
- [azurerm_virtual_machine_extension.this_extension_1](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) (resource)
58-
- [azurerm_virtual_machine_extension.this_extension_2](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_extension) (resource)
59-
- [azurerm_virtual_machine_run_command.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_run_command) (resource)
6056
- [azurerm_windows_virtual_machine.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_virtual_machine) (resource)
6157
- [modtm_telemetry.telemetry](https://registry.terraform.io/providers/Azure/modtm/latest/docs/resources/telemetry) (resource)
6258
- [random_password.admin_password](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) (resource)
@@ -742,6 +738,7 @@ Description: This map of objects is used to create additional `azurerm_virtual_m
742738
- `secret_url` (Required) - The Secret URL of a Key Vault Certificate. This can be sourced from the `secret_id` field within the `azurerm_key_vault_certificate` Resource.
743739
- `source_vault_id` (Required) - the Azure resource ID of the key vault holding the secret
744740
- `tags` (Optional) - A mapping of tags to assign to the extension resource.
741+
- `timeouts` (Optional): Timeouts for the extension resource.
745742

746743
Example Inputs:
747744

@@ -808,6 +805,13 @@ map(object({
808805
secret_url = string
809806
source_vault_id = string
810807
}))
808+
timeouts = optional(object({
809+
create = optional(string)
810+
delete = optional(string)
811+
update = optional(string)
812+
read = optional(string)
813+
})
814+
)
811815
}))
812816
```
813817

@@ -1305,13 +1309,14 @@ The following arguments are supported:
13051309

13061310
- `location` (Required): The Azure Region where the Virtual Machine Run Command should exist. Changing this forces a new Virtual Machine Run Command to be created.
13071311
- `name` (Required): Specifies the name of this Virtual Machine Run Command. Changing this forces a new Virtual Machine Run Command to be created.
1308-
- `source` (Required): A source block as defined below. The source of the run command script.
1312+
- `script_source` (Required): A source block as defined below. The source of the run command script.
13091313
- `error_blob_managed_identity` (Optional): An error\_blob\_managed\_identity block as defined below. User-assigned managed Identity that has access to errorBlobUri storage blob.
13101314
- `error_blob_uri` (Optional): Specifies the Azure storage blob where script error stream will be uploaded.
13111315
- `output_blob_managed_identity` (Optional): An output\_blob\_managed\_identity block as defined below. User-assigned managed Identity that has access to outputBlobUri storage blob.
13121316
- `output_blob_uri` (Optional): Specifies the Azure storage blob where script output stream will be uploaded. It can be basic blob URI with SAS token.
13131317
- `parameter` (Optional): A list of parameter blocks as defined below. The parameters used by the script.
13141318
- `protected_parameter` (Optional): A list of protected\_parameter blocks as defined below. The protected parameters used by the script.
1319+
- `timeouts` (Optional): Timeouts for each run command.
13151320
- `tags` (Optional): A mapping of tags which should be assigned to the Virtual Machine Run Command.
13161321

13171322
An error\_blob\_managed\_identity block supports the following arguments:
@@ -1340,9 +1345,10 @@ Type:
13401345

13411346
```hcl
13421347
map(object({
1343-
location = string
1344-
name = string
1345-
source = object({
1348+
location = string
1349+
name = string
1350+
deploy_sequence = optional(number, 3)
1351+
script_source = object({
13461352
command_id = optional(string)
13471353
script = optional(string)
13481354
script_uri = optional(string)
@@ -1366,6 +1372,14 @@ map(object({
13661372
value = string
13671373
})), [])
13681374
1375+
timeouts = optional(object({
1376+
create = optional(string)
1377+
delete = optional(string)
1378+
update = optional(string)
1379+
read = optional(string)
1380+
})
1381+
)
1382+
13691383
tags = optional(map(string))
13701384
}))
13711385
```
@@ -1601,6 +1615,43 @@ object({
16011615

16021616
Default: `null`
16031617

1618+
### <a name="input_timeouts"></a> [timeouts](#input\_timeouts)
1619+
1620+
Description: A map of timeouts to apply to the creation and destruction of resources.
1621+
If using retry, the maximum elapsed retry time is governed by this value.
1622+
1623+
The object has attributes for each resource type, with the following optional attributes:
1624+
1625+
- `create` - (Optional) The timeout for creating the resource.
1626+
- `delete` - (Optional) The timeout for deleting the resource.
1627+
- `update` - (Optional) The timeout for updating the resource.
1628+
- `read` - (Optional) The timeout for reading the resource.
1629+
1630+
Each time duration is parsed using this function: <https://pkg.go.dev/time#ParseDuration>.
1631+
1632+
Type:
1633+
1634+
```hcl
1635+
object({
1636+
azurerm_virtual_machine_extension = optional(object({
1637+
create = optional(string, "30m")
1638+
delete = optional(string, "30m")
1639+
update = optional(string, "30m")
1640+
read = optional(string, "5m")
1641+
}), {}
1642+
)
1643+
azurerm_virtual_machine_run_command = optional(object({
1644+
create = optional(string, "30m")
1645+
delete = optional(string, "30m")
1646+
update = optional(string, "30m")
1647+
read = optional(string, "5m")
1648+
}), {}
1649+
)
1650+
})
1651+
```
1652+
1653+
Default: `{}`
1654+
16041655
### <a name="input_timezone"></a> [timezone](#input\_timezone)
16051656

16061657
Description: (Optional) Specifies the Time Zone which should be used by the Windows Virtual Machine, [the possible values are defined here](https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/). Changing this forces a new resource to be created.
@@ -1767,7 +1818,43 @@ Description: The default attributes exported by the azurerm provider. These
17671818
17681819
## Modules
17691820
1770-
No modules.
1821+
The following Modules are called:
1822+
1823+
### <a name="module_extension"></a> [extension](#module\_extension)
1824+
1825+
Source: ./modules/extension
1826+
1827+
Version:
1828+
1829+
### <a name="module_extension_1"></a> [extension\_1](#module\_extension\_1)
1830+
1831+
Source: ./modules/extension
1832+
1833+
Version:
1834+
1835+
### <a name="module_extension_2"></a> [extension\_2](#module\_extension\_2)
1836+
1837+
Source: ./modules/extension
1838+
1839+
Version:
1840+
1841+
### <a name="module_run_command"></a> [run\_command](#module\_run\_command)
1842+
1843+
Source: ./modules/run-command
1844+
1845+
Version:
1846+
1847+
### <a name="module_run_command_1"></a> [run\_command\_1](#module\_run\_command\_1)
1848+
1849+
Source: ./modules/run-command
1850+
1851+
Version:
1852+
1853+
### <a name="module_run_command_2"></a> [run\_command\_2](#module\_run\_command\_2)
1854+
1855+
Source: ./modules/run-command
1856+
1857+
Version:
17711858
17721859
<!-- markdownlint-disable-next-line MD041 -->
17731860
## Data Collection

examples/windows_w_run_command/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ module "testvm" {
311311
test_example_simple = {
312312
location = azurerm_resource_group.this_rg.location
313313
name = "example-command"
314-
source = {
314+
script_source = {
315315
script = "echo Hello World"
316316
}
317317
@@ -323,7 +323,7 @@ module "testvm" {
323323
name = "example-command-storage"
324324
error_blob_uri = azurerm_storage_blob.example3.url
325325
output_blob_uri = azurerm_storage_blob.example2.url
326-
source = {
326+
script_source = {
327327
script_uri = azurerm_storage_blob.example1.url
328328
}
329329

examples/windows_w_run_command/main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ module "testvm" {
292292
test_example_simple = {
293293
location = azurerm_resource_group.this_rg.location
294294
name = "example-command"
295-
source = {
295+
script_source = {
296296
script = "echo Hello World"
297297
}
298298

@@ -304,7 +304,7 @@ module "testvm" {
304304
name = "example-command-storage"
305305
error_blob_uri = azurerm_storage_blob.example3.url
306306
output_blob_uri = azurerm_storage_blob.example2.url
307-
source = {
307+
script_source = {
308308
script_uri = azurerm_storage_blob.example1.url
309309
}
310310

main.extensions.tf

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,104 @@
1-
resource "azurerm_virtual_machine_extension" "this_extension" {
1+
module "extension" {
2+
source = "./modules/extension"
3+
24
for_each = toset([for k, v in nonsensitive(var.extensions) : k if v.deploy_sequence >= 3]) #forcing to use the map key to address terraform limitation around sensitive values in the map (https://developer.hashicorp.com/terraform/language/meta-arguments/for_each#limitations-on-values-used-in-for_each)
35

46
#using explicit references using the for_each key to get around the secrets issue in the above link
5-
name = var.extensions[each.key].name
6-
publisher = var.extensions[each.key].publisher
7-
type = var.extensions[each.key].type
8-
type_handler_version = var.extensions[each.key].type_handler_version
9-
virtual_machine_id = local.virtualmachine_resource_id
10-
auto_upgrade_minor_version = var.extensions[each.key].auto_upgrade_minor_version
11-
automatic_upgrade_enabled = var.extensions[each.key].automatic_upgrade_enabled
12-
failure_suppression_enabled = var.extensions[each.key].failure_suppression_enabled
13-
protected_settings = var.extensions[each.key].protected_settings
14-
provision_after_extensions = var.extensions[each.key].provision_after_extensions
15-
settings = var.extensions[each.key].settings
16-
tags = var.extensions[each.key].tags != null && var.extensions[each.key].tags != {} ? var.extensions[each.key].tags : local.tags
17-
18-
dynamic "protected_settings_from_key_vault" {
19-
for_each = var.extensions[each.key].protected_settings_from_key_vault != null ? [each.key] : []
20-
21-
content {
22-
secret_url = var.extensions[each.key].protected_settings_from_key_vault.secret_url
23-
source_vault_id = var.extensions[each.key].protected_settings_from_key_vault.source_vault_id
24-
}
7+
name = var.extensions[each.key].name
8+
publisher = var.extensions[each.key].publisher
9+
type = var.extensions[each.key].type
10+
type_handler_version = var.extensions[each.key].type_handler_version
11+
virtualmachine_resource_id = local.virtualmachine_resource_id
12+
auto_upgrade_minor_version = var.extensions[each.key].auto_upgrade_minor_version
13+
automatic_upgrade_enabled = var.extensions[each.key].automatic_upgrade_enabled
14+
failure_suppression_enabled = var.extensions[each.key].failure_suppression_enabled
15+
protected_settings = var.extensions[each.key].protected_settings
16+
provision_after_extensions = var.extensions[each.key].provision_after_extensions
17+
settings = var.extensions[each.key].settings
18+
protected_settings_from_key_vault = var.extensions[each.key].protected_settings_from_key_vault
19+
20+
timeouts = {
21+
create = coalesce(try(var.extensions[each.key].timeouts.create, null), var.timeouts.azurerm_virtual_machine_extension.create)
22+
delete = coalesce(try(var.extensions[each.key].timeouts.delete, null), var.timeouts.azurerm_virtual_machine_extension.delete)
23+
read = coalesce(try(var.extensions[each.key].timeouts.read, null), var.timeouts.azurerm_virtual_machine_extension.read)
24+
update = coalesce(try(var.extensions[each.key].timeouts.update, null), var.timeouts.azurerm_virtual_machine_extension.update)
2525
}
2626

27+
tags = var.extensions[each.key].tags != null && var.extensions[each.key].tags != {} ? var.extensions[each.key].tags : local.tags
28+
2729
depends_on = [
2830
azurerm_virtual_machine_data_disk_attachment.this_linux,
2931
azurerm_virtual_machine_data_disk_attachment.this_windows,
30-
azurerm_virtual_machine_extension.this_extension_1,
31-
azurerm_virtual_machine_extension.this_extension_2
32+
module.extension_1,
33+
module.extension_2
3234
]
3335
}
3436

35-
resource "azurerm_virtual_machine_extension" "this_extension_1" {
37+
module "extension_1" {
38+
source = "./modules/extension"
39+
3640
for_each = toset([for k, v in nonsensitive(var.extensions) : k if v.deploy_sequence == 1]) #forcing to use the map key to address terraform limitation around sensitive values in the map (https://developer.hashicorp.com/terraform/language/meta-arguments/for_each#limitations-on-values-used-in-for_each)
3741

3842
#using explicit references using the for_each key to get around the secrets issue in the above link
39-
name = var.extensions[each.key].name
40-
publisher = var.extensions[each.key].publisher
41-
type = var.extensions[each.key].type
42-
type_handler_version = var.extensions[each.key].type_handler_version
43-
virtual_machine_id = local.virtualmachine_resource_id
44-
auto_upgrade_minor_version = var.extensions[each.key].auto_upgrade_minor_version
45-
automatic_upgrade_enabled = var.extensions[each.key].automatic_upgrade_enabled
46-
failure_suppression_enabled = var.extensions[each.key].failure_suppression_enabled
47-
protected_settings = var.extensions[each.key].protected_settings
48-
provision_after_extensions = var.extensions[each.key].provision_after_extensions
49-
settings = var.extensions[each.key].settings
50-
tags = var.extensions[each.key].tags != null && var.extensions[each.key].tags != {} ? var.extensions[each.key].tags : local.tags
51-
52-
dynamic "protected_settings_from_key_vault" {
53-
for_each = var.extensions[each.key].protected_settings_from_key_vault != null ? [each.key] : []
54-
55-
content {
56-
secret_url = var.extensions[each.key].protected_settings_from_key_vault.secret_url
57-
source_vault_id = var.extensions[each.key].protected_settings_from_key_vault.source_vault_id
58-
}
43+
name = var.extensions[each.key].name
44+
publisher = var.extensions[each.key].publisher
45+
type = var.extensions[each.key].type
46+
type_handler_version = var.extensions[each.key].type_handler_version
47+
virtualmachine_resource_id = local.virtualmachine_resource_id
48+
auto_upgrade_minor_version = var.extensions[each.key].auto_upgrade_minor_version
49+
automatic_upgrade_enabled = var.extensions[each.key].automatic_upgrade_enabled
50+
failure_suppression_enabled = var.extensions[each.key].failure_suppression_enabled
51+
protected_settings = var.extensions[each.key].protected_settings
52+
provision_after_extensions = var.extensions[each.key].provision_after_extensions
53+
settings = var.extensions[each.key].settings
54+
protected_settings_from_key_vault = var.extensions[each.key].protected_settings_from_key_vault
55+
56+
timeouts = {
57+
create = coalesce(try(var.extensions[each.key].timeouts.create, null), var.timeouts.azurerm_virtual_machine_extension.create)
58+
delete = coalesce(try(var.extensions[each.key].timeouts.delete, null), var.timeouts.azurerm_virtual_machine_extension.delete)
59+
read = coalesce(try(var.extensions[each.key].timeouts.read, null), var.timeouts.azurerm_virtual_machine_extension.read)
60+
update = coalesce(try(var.extensions[each.key].timeouts.update, null), var.timeouts.azurerm_virtual_machine_extension.update)
5961
}
6062

63+
tags = var.extensions[each.key].tags != null && var.extensions[each.key].tags != {} ? var.extensions[each.key].tags : local.tags
64+
6165
depends_on = [
6266
azurerm_virtual_machine_data_disk_attachment.this_linux,
63-
azurerm_virtual_machine_data_disk_attachment.this_windows
67+
azurerm_virtual_machine_data_disk_attachment.this_windows,
6468
]
6569
}
6670

67-
resource "azurerm_virtual_machine_extension" "this_extension_2" {
71+
module "extension_2" {
72+
source = "./modules/extension"
73+
6874
for_each = toset([for k, v in nonsensitive(var.extensions) : k if v.deploy_sequence == 2]) #forcing to use the map key to address terraform limitation around sensitive values in the map (https://developer.hashicorp.com/terraform/language/meta-arguments/for_each#limitations-on-values-used-in-for_each)
6975

7076
#using explicit references using the for_each key to get around the secrets issue in the above link
71-
name = var.extensions[each.key].name
72-
publisher = var.extensions[each.key].publisher
73-
type = var.extensions[each.key].type
74-
type_handler_version = var.extensions[each.key].type_handler_version
75-
virtual_machine_id = local.virtualmachine_resource_id
76-
auto_upgrade_minor_version = var.extensions[each.key].auto_upgrade_minor_version
77-
automatic_upgrade_enabled = var.extensions[each.key].automatic_upgrade_enabled
78-
failure_suppression_enabled = var.extensions[each.key].failure_suppression_enabled
79-
protected_settings = var.extensions[each.key].protected_settings
80-
provision_after_extensions = var.extensions[each.key].provision_after_extensions
81-
settings = var.extensions[each.key].settings
82-
tags = var.extensions[each.key].tags != null && var.extensions[each.key].tags != {} ? var.extensions[each.key].tags : local.tags
83-
84-
dynamic "protected_settings_from_key_vault" {
85-
for_each = var.extensions[each.key].protected_settings_from_key_vault != null ? [each.key] : []
86-
87-
content {
88-
secret_url = var.extensions[each.key].protected_settings_from_key_vault.secret_url
89-
source_vault_id = var.extensions[each.key].protected_settings_from_key_vault.source_vault_id
90-
}
77+
name = var.extensions[each.key].name
78+
publisher = var.extensions[each.key].publisher
79+
type = var.extensions[each.key].type
80+
type_handler_version = var.extensions[each.key].type_handler_version
81+
virtualmachine_resource_id = local.virtualmachine_resource_id
82+
auto_upgrade_minor_version = var.extensions[each.key].auto_upgrade_minor_version
83+
automatic_upgrade_enabled = var.extensions[each.key].automatic_upgrade_enabled
84+
failure_suppression_enabled = var.extensions[each.key].failure_suppression_enabled
85+
protected_settings = var.extensions[each.key].protected_settings
86+
provision_after_extensions = var.extensions[each.key].provision_after_extensions
87+
settings = var.extensions[each.key].settings
88+
protected_settings_from_key_vault = var.extensions[each.key].protected_settings_from_key_vault
89+
90+
timeouts = {
91+
create = coalesce(try(var.extensions[each.key].timeouts.create, null), var.timeouts.azurerm_virtual_machine_extension.create)
92+
delete = coalesce(try(var.extensions[each.key].timeouts.delete, null), var.timeouts.azurerm_virtual_machine_extension.delete)
93+
read = coalesce(try(var.extensions[each.key].timeouts.read, null), var.timeouts.azurerm_virtual_machine_extension.read)
94+
update = coalesce(try(var.extensions[each.key].timeouts.update, null), var.timeouts.azurerm_virtual_machine_extension.update)
9195
}
9296

97+
tags = var.extensions[each.key].tags != null && var.extensions[each.key].tags != {} ? var.extensions[each.key].tags : local.tags
98+
9399
depends_on = [
94100
azurerm_virtual_machine_data_disk_attachment.this_linux,
95101
azurerm_virtual_machine_data_disk_attachment.this_windows,
96-
azurerm_virtual_machine_extension.this_extension_1
102+
module.extension_1
97103
]
98-
}
104+
}

0 commit comments

Comments
 (0)