Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .trivyignore

This file was deleted.

30 changes: 2 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ As documented on the [image](#input_image) input variable, it is possible to use
This example demonstrates the usage of the virtual machine module with default settings. It sets up all necessary dependencies, including a resource group, virtual network, subnet, recovery services vault, backup policy, and key vault, to ensure seamless deployment.

> [!TIP]
> Our module intentionally keeps password-based login available for Linux virtual machines through the `authentication_type` input variable. Where your security policy requires SSH-only access, set `authentication_type = "SSH"`. When you intentionally allow Linux password authentication and need to suppress the corresponding [Trivy](https://trivy.dev) warning, add the comment `#trivy:ignore:AVD-AZU-0039` directly above the Terraform module definition, as shown in the example below.
> Our module enables password-based login for Linux virtual machines, configurable via the `authentication_type` input variable. If the [`disable_password_authentication`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine.html#disable_password_authentication-1) setting on the [`azurerm_linux_virtual_machine`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine) resource within this module is not explicitly set to `false`, [Trivy](https://trivy.dev) will flag a high-severity warning. To suppress this warning, add the comment `#trivy:ignore:avd-azu-0039` directly above the Terraform module definition, as shown in the example below.

```hcl
resource "azurerm_resource_group" "example" {
Expand Down Expand Up @@ -94,9 +94,7 @@ resource "azurerm_key_vault" "example" {
}
}

# Linux password authentication remains an explicit module feature controlled by authentication_type.
# Prefer SSH-only authentication where organizational policy requires it.
#trivy:ignore:AVD-AZU-0039
#trivy:ignore:avd-azu-0039
module "example" {
source = "cloudeteer/vm/azurerm"

Expand Down Expand Up @@ -136,8 +134,6 @@ The following resources are used by this module:
- [azurerm_linux_virtual_machine.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine) (resource)
- [azurerm_managed_disk.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_disk) (resource)
- [azurerm_network_interface.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) (resource)
- [azurerm_network_interface_security_group_association.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_security_group_association) (resource)
- [azurerm_network_security_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group) (resource)
- [azurerm_public_ip.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) (resource)
- [azurerm_role_assignment.entra_id_login_admin](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
- [azurerm_role_assignment.entra_id_login_user](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource)
Expand Down Expand Up @@ -630,17 +626,6 @@ Type: `string`

Default: `null`

### <a name="input_key_vault_secret_expiration_date"></a> [key\_vault\_secret\_expiration\_date](#input\_key\_vault\_secret\_expiration\_date)

Description: The RFC3339 timestamp to assign as `expiration_date` on generated Azure Key Vault secrets.

- Applies only when `store_secret_in_key_vault` is `true`.
- Leave as `null` to keep generated secrets without an explicit expiry date.

Type: `string`

Default: `null`

### <a name="input_license_type"></a> [license\_type](#input\_license\_type)

Description: Specifies the license type to be used for this Virtual Machine.
Expand All @@ -662,17 +647,6 @@ Type: `list(string)`

Default: `null`

### <a name="input_network_security_group_id"></a> [network\_security\_group\_id](#input\_network\_security\_group\_id)

Description: The resource ID of an existing Azure Network Security Group to associate with the network interface created by this module.

- Applies only when `create_network_interface` is `true`.
- If omitted and `create_network_interface` is `true`, this module creates and associates a default Network Security Group.

Type: `string`

Default: `null`

### <a name="input_operating_system"></a> [operating\_system](#input\_operating\_system)

Description: The virtual machine's operating system. Valid values are `Linux` or `Windows`. The default is `null`, which determines the operating system to use based on the virtual machine image offering.
Expand Down
4 changes: 1 addition & 3 deletions examples/domain_join/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,7 @@ data "azurerm_key_vault_secret" "domain_join_user" {
}


# Linux password authentication remains an explicit module feature controlled by authentication_type.
# Prefer SSH-only authentication where organizational policy requires it.
#trivy:ignore:AVD-AZU-0039
#trivy:ignore:avd-azu-0039
module "example" {
source = "cloudeteer/vm/azurerm"

Expand Down
4 changes: 1 addition & 3 deletions examples/external_key_vault/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ variable "location" {
type = string
}

# Linux password authentication remains an explicit module feature controlled by authentication_type.
# Prefer SSH-only authentication where organizational policy requires it.
#trivy:ignore:AVD-AZU-0039
#trivy:ignore:avd-azu-0039
module "example" {
source = "cloudeteer/vm/azurerm"

Expand Down
2 changes: 1 addition & 1 deletion examples/usage/main.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This example demonstrates the usage of the virtual machine module with default settings. It sets up all necessary dependencies, including a resource group, virtual network, subnet, recovery services vault, backup policy, and key vault, to ensure seamless deployment.

> [!TIP]
> Our module intentionally keeps password-based login available for Linux virtual machines through the `authentication_type` input variable. Where your security policy requires SSH-only access, set `authentication_type = "SSH"`. When you intentionally allow Linux password authentication and need to suppress the corresponding [Trivy](https://trivy.dev) warning, add the comment `#trivy:ignore:AVD-AZU-0039` directly above the Terraform module definition, as shown in the example below.
> Our module enables password-based login for Linux virtual machines, configurable via the `authentication_type` input variable. If the [`disable_password_authentication`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine.html#disable_password_authentication-1) setting on the [`azurerm_linux_virtual_machine`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_virtual_machine) resource within this module is not explicitly set to `false`, [Trivy](https://trivy.dev) will flag a high-severity warning. To suppress this warning, add the comment `#trivy:ignore:avd-azu-0039` directly above the Terraform module definition, as shown in the example below.
4 changes: 1 addition & 3 deletions examples/usage/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ resource "azurerm_key_vault" "example" {
}
}

# Linux password authentication remains an explicit module feature controlled by authentication_type.
# Prefer SSH-only authentication where organizational policy requires it.
#trivy:ignore:AVD-AZU-0039
#trivy:ignore:avd-azu-0039
module "example" {
source = "cloudeteer/vm/azurerm"

Expand Down
15 changes: 6 additions & 9 deletions r-authentication.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,15 @@ resource "tls_private_key" "this" {
rsa_bits = var.admin_ssh_key_algorithm == "RSA" ? 4096 : null
}

# Generated secrets may intentionally remain non-expiring when rotation is managed externally.
# Set var.key_vault_secret_expiration_date to enforce an explicit expiry date on generated secrets.
#trivy:ignore:AVD-AZU-0017
#trivy:ignore:AVD-AZU-0013
#trivy:ignore:avd-azu-0017
#trivy:ignore:avd-azu-0013
resource "azurerm_key_vault_secret" "this" {
for_each = toset([
for element in split(", ", var.authentication_type) : element if var.store_secret_in_key_vault
])

name = "${var.name}-${var.admin_username}-${lower(each.key)}"
content_type = var.authentication_type
expiration_date = var.key_vault_secret_expiration_date
key_vault_id = var.key_vault_id
value = coalesce(local.admin_password, local.admin_ssh_private_key)
name = "${var.name}-${var.admin_username}-${lower(each.key)}"
content_type = var.authentication_type
key_vault_id = var.key_vault_id
value = coalesce(local.admin_password, local.admin_ssh_private_key)
}
22 changes: 0 additions & 22 deletions r-network.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,7 @@ locals {
azurerm_network_interface.this[*].id,
(var.network_interface_ids != null ? var.network_interface_ids : [])
)
network_security_group_id = (
var.network_security_group_id != null ?
var.network_security_group_id :
try(one(azurerm_network_security_group.this[*].id), null)
)

}

resource "azurerm_network_security_group" "this" {

count = var.create_network_interface && var.network_security_group_id == null ? 1 : 0

name = "nsg-${trimprefix(var.name, "vm-")}"
location = var.location
resource_group_name = var.resource_group_name
tags = var.tags
}

resource "azurerm_network_interface" "this" {
Expand All @@ -44,13 +29,6 @@ resource "azurerm_network_interface" "this" {
}
}

resource "azurerm_network_interface_security_group_association" "this" {
count = var.create_network_interface ? 1 : 0

network_interface_id = azurerm_network_interface.this[0].id
network_security_group_id = local.network_security_group_id
}

resource "azurerm_public_ip" "this" {
count = var.create_public_ip_address ? 1 : 0

Expand Down
8 changes: 1 addition & 7 deletions r-vm.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ locals {
)
}

# Module-managed NICs are associated with an NSG in r-network.tf; externally supplied NICs remain consumer-managed.
#trivy:ignore:AVD-AZU-0068
# Linux password authentication remains an explicit module feature controlled by var.authentication_type.
# Prefer SSH-only authentication where organizational policy requires it.
#trivy:ignore:AVD-AZU-0039
# trivy:ignore:avd-azu-0039
resource "azurerm_linux_virtual_machine" "this" {
count = local.is_linux ? 1 : 0

Expand Down Expand Up @@ -117,8 +113,6 @@ resource "azurerm_linux_virtual_machine" "this" {
}

resource "azurerm_windows_virtual_machine" "this" {
# Module-managed NICs are associated with an NSG in r-network.tf; externally supplied NICs remain consumer-managed.
#trivy:ignore:AVD-AZU-0068
count = local.is_windows ? 1 : 0

name = var.name
Expand Down

This file was deleted.

This file was deleted.

28 changes: 0 additions & 28 deletions tests/local/input_key_vault_id.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,3 @@ run "should_add_key_vault_id_as_tag_to_virtual_machine" {
error_message = "Expected to add key vault id as tag to virtual machine"
}
}

run "should_set_key_vault_secret_expiration_date" {
command = plan

variables {
authentication_type = "SSH"
image = "Ubuntu2204"
key_vault_secret_expiration_date = "2030-01-01T00:00:00Z"
operating_system = "Linux"
}

assert {
condition = one(values(azurerm_key_vault_secret.this)).expiration_date == var.key_vault_secret_expiration_date
error_message = "Expected generated Key Vault secrets to use the configured expiration date."
}
}

run "should_fail_with_invalid_key_vault_secret_expiration_date" {
command = plan

variables {
key_vault_secret_expiration_date = "not-a-timestamp"
}

expect_failures = [
var.key_vault_secret_expiration_date,
]
}
29 changes: 0 additions & 29 deletions tests/local/input_network.tftest.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@ run "should_use_subnet_id" {
condition = azurerm_network_interface.this[0].ip_configuration[0].subnet_id == var.subnet_id
error_message = "Expected to create network interface and use subnet id vom variable input"
}

assert {
condition = length(azurerm_network_security_group.this) == 1
error_message = "Expected the module to create a default network security group when no network_security_group_id is provided."
}

assert {
condition = length(azurerm_network_interface_security_group_association.this) == 1
error_message = "Expected the created network interface to have a network security group association."
}
}

run "should_fail_with_no_subnet_id" {
Expand Down Expand Up @@ -62,25 +52,6 @@ run "should_use_network_interface_ids_from_input_only" {
}
}

run "should_use_existing_network_security_group_for_created_network_interface" {
command = plan

variables {
network_security_group_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg/providers/Microsoft.Network/networkSecurityGroups/nsg-existing"
subnet_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/snet"
}

assert {
condition = length(azurerm_network_security_group.this) == 0
error_message = "Expected no network security group to be created when network_security_group_id is provided."
}

assert {
condition = length(azurerm_network_interface_security_group_association.this) == 1
error_message = "Expected the created network interface to have a network security group association when network_security_group_id is provided."
}
}


run "should_assert_three_network_interfaces" {
command = plan
Expand Down

This file was deleted.

5 changes: 0 additions & 5 deletions tests/local/mocks/azurerm_network_security_group.tfmock.hcl

This file was deleted.

34 changes: 0 additions & 34 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -473,28 +473,6 @@ variable "key_vault_id" {
}
}

variable "key_vault_secret_expiration_date" {
description = <<-EOT
The RFC3339 timestamp to assign as `expiration_date` on generated Azure Key Vault secrets.

- Applies only when `store_secret_in_key_vault` is `true`.
- Leave as `null` to keep generated secrets without an explicit expiry date.
EOT

default = null
type = string

validation {
condition = var.key_vault_secret_expiration_date == null ? true : var.store_secret_in_key_vault
error_message = "key_vault_secret_expiration_date can only be set when store_secret_in_key_vault is true."
}

validation {
condition = var.key_vault_secret_expiration_date == null ? true : can(formatdate("", var.key_vault_secret_expiration_date))
error_message = "key_vault_secret_expiration_date must be a valid RFC3339 timestamp, for example 2030-01-01T00:00:00Z."
}
}

variable "license_type" {
description = <<-EOT
Specifies the license type to be used for this Virtual Machine.
Expand Down Expand Up @@ -539,18 +517,6 @@ variable "network_interface_ids" {
type = list(string)
}

variable "network_security_group_id" {
description = <<-EOT
The resource ID of an existing Azure Network Security Group to associate with the network interface created by this module.

- Applies only when `create_network_interface` is `true`.
- If omitted and `create_network_interface` is `true`, this module creates and associates a default Network Security Group.
EOT

default = null
type = string
}

variable "operating_system" {
default = null
description = "The virtual machine's operating system. Valid values are `Linux` or `Windows`. The default is `null`, which determines the operating system to use based on the virtual machine image offering."
Expand Down
Loading