Giter Site home page Giter Site logo

terraform-azurerm-vnet's Introduction

terraform-azurerm-vnet

Create a basic virtual network in Azure

This Terraform module deploys a Virtual Network in Azure with a subnet or a set of subnets passed in as input parameters.

The module does not create nor expose a network security group. This would need to be defined separately as additional security rules on subnets in the deployed network.

Notice to contributor

Thanks for your contribution! This module was created before Terraform introduce for_each, and according to the document:

If your instances are almost identical, count is appropriate. If some of their arguments need distinct values that can't be directly derived from an integer, it's safer to use for_each.

This module contains resources with count meta-argument, but if we change count to for_each directly, it would require heavily manually state move operations with extremely caution, or the users who are maintaining existing infrastructure would face potential breaking change.

This module replicated a new azurerm_subnet which used for_each, and we provide a new toggle variable named use_for_each, this toggle is a switcher between count set and for_each set. Now user can set var.use_for_each to true to use for_each, and users who're maintaining existing resources could keep this toggle false to avoid potential breaking change. If you'd like to make changes to subnet resource, make sure that you've change both resource blocks. Thanks for your cooperation.

Notice on Upgrade to V4.x

In v4.0.0, we would make var.use_for_each a required variable so the users must set the value explicitly. For whom are maintaining the existing infrastructure that was created with count should use false, for those who are creating a new stack, we encourage them to use true.

V4.0.0 is a major version upgrade. Extreme caution must be taken during the upgrade to avoid resource replacement and downtime by accident.

Running the terraform plan first to inspect the plan is strongly advised.

Notice on Upgrade to V3.x

We've added a CI pipeline for this module to speed up our code review and to enforce a high code quality standard, if you want to contribute by submitting a pull request, please read Pre-Commit & Pr-Check & Test section, or your pull request might be rejected by CI pipeline.

A pull request will be reviewed when it has passed Pre Pull Request Check in the pipeline, and will be merged when it has passed the acceptance tests. Once the ci Pipeline failed, please read the pipeline's output, thanks for your cooperation.

V3.0.0 is a major version upgrade. Extreme caution must be taken during the upgrade to avoid resource replacement and downtime by accident.

Running the terraform plan first to inspect the plan is strongly advised.

We kept most code untouched, but the following breaking changes might affect your stack:

  • var.vnet_location now is required. #72
  • var.resource_group_name now cannot be set to null. #72
  • var.subnet_prefixes's default value now is ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]. #73

Terraform and terraform-provider-azurerm version restrictions

Now Terraform core's version is v1.x and terraform-provider-azurerm's version is v3.x.

Example Usage

Please refer to the sub folders under examples folder. You can execute terraform apply command in examples's sub folder to try the module. These examples are tested against every PR with the E2E Test.

Enable or disable tracing tags

We're using BridgeCrew Yor and yorbox to help manage tags consistently across infrastructure as code (IaC) frameworks. In this module you might see tags like:

resource "azurerm_resource_group" "rg" {
  location = "eastus"
  name     = random_pet.name
  tags = merge(var.tags, (/*<box>*/ (var.tracing_tags_enabled ? { for k, v in /*</box>*/ {
    avm_git_commit           = "3077cc6d0b70e29b6e106b3ab98cee6740c916f6"
    avm_git_file             = "main.tf"
    avm_git_last_modified_at = "2023-05-05 08:57:54"
    avm_git_org              = "lonegunmanb"
    avm_git_repo             = "terraform-yor-tag-test-module"
    avm_yor_trace            = "a0425718-c57d-401c-a7d5-f3d88b2551a4"
  } /*<box>*/ : replace(k, "avm_", var.tracing_tags_prefix) => v } : {}) /*</box>*/))
}

To enable tracing tags, set the variable to true:

module "example" {
  source               = "{module_source}"
  ...
  tracing_tags_enabled = true
}

The tracing_tags_enabled is default to false.

To customize the prefix for your tracing tags, set the tracing_tags_prefix variable value in your Terraform configuration:

module "example" {
  source              = "{module_source}"
  ...
  tracing_tags_prefix = "custom_prefix_"
}

The actual applied tags would be:

{
  custom_prefix_git_commit           = "3077cc6d0b70e29b6e106b3ab98cee6740c916f6"
  custom_prefix_git_file             = "main.tf"
  custom_prefix_git_last_modified_at = "2023-05-05 08:57:54"
  custom_prefix_git_org              = "lonegunmanb"
  custom_prefix_git_repo             = "terraform-yor-tag-test-module"
  custom_prefix_yor_trace            = "a0425718-c57d-401c-a7d5-f3d88b2551a4"
}

Pre-Commit & Pr-Check & Test

Configurations

We assumed that you have setup service principal's credentials in your environment variables like below:

export ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
export ARM_TENANT_ID="<azure_subscription_tenant_id>"
export ARM_CLIENT_ID="<service_principal_appid>"
export ARM_CLIENT_SECRET="<service_principal_password>"

On Windows Powershell:

$env:ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
$env:ARM_TENANT_ID="<azure_subscription_tenant_id>"
$env:ARM_CLIENT_ID="<service_principal_appid>"
$env:ARM_CLIENT_SECRET="<service_principal_password>"

We provide a docker image to run the pre-commit checks and tests for you: mcr.microsoft.com/azterraform:latest

To run the pre-commit task, we can run the following command:

$ docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make pre-commit

On Windows Powershell:

$ docker run --rm -v ${pwd}:/src -w /src mcr.microsoft.com/azterraform:latest make pre-commit

In pre-commit task, we will:

  1. Run terraform fmt -recursive command for your Terraform code.
  2. Run terrafmt fmt -f command for markdown files and go code files to ensure that the Terraform code embedded in these files are well formatted.
  3. Run go mod tidy and go mod vendor for test folder to ensure that all the dependencies have been synced.
  4. Run gofmt for all go code files.
  5. Run gofumpt for all go code files.
  6. Run terraform-docs on README.md file, then run markdown-table-formatter to format markdown tables in README.md.

Then we can run the pr-check task to check whether our code meets our pipeline's requirement(We strongly recommend you run the following command before you commit):

$ docker run --rm -v $(pwd):/src -w /src -e TFLINT_CONFIG=.tflint_alt.hcl mcr.microsoft.com/azterraform:latest make pr-check

On Windows Powershell:

$ docker run --rm -v ${pwd}:/src -w /src -e TFLINT_CONFIG=.tflint_alt.hcl mcr.microsoft.com/azterraform:latest make pr-check

To run the e2e-test, we can run the following command:

docker run --rm -v $(pwd):/src -w /src -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_CLIENT_SECRET mcr.microsoft.com/azterraform:latest make e2e-test

On Windows Powershell:

docker run --rm -v ${pwd}:/src -w /src -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_CLIENT_SECRET mcr.microsoft.com/azterraform:latest make e2e-test

Prerequisites

Authors

Originally created by Eugene Chuvyrov

License

MIT

Requirements

Name Version
terraform >= 1.2
azurerm >= 3.11, < 4.0

Providers

Name Version
azurerm >= 3.11, < 4.0

Modules

No modules.

Resources

Name Type
azurerm_subnet.subnet_count resource
azurerm_subnet.subnet_for_each resource
azurerm_subnet_network_security_group_association.vnet resource
azurerm_subnet_route_table_association.vnet resource
azurerm_virtual_network.vnet resource

Inputs

Name Description Type Default Required
address_space The address space that is used by the virtual network. list(string)
[
"10.0.0.0/16"
]
no
bgp_community (Optional) The BGP community attribute in format <as-number>:<community-value>. string null no
ddos_protection_plan The set of DDoS protection plan configuration
object({
enable = bool
id = string
})
null no
dns_servers The DNS servers to be used with vNet. list(string) [] no
nsg_ids A map of subnet name to Network Security Group IDs map(string) {} no
resource_group_name Name of the resource group to be imported. string n/a yes
route_tables_ids A map of subnet name to Route table ids map(string) {} no
subnet_delegation A map of subnet name to delegation block on the subnet map(map(any)) {} no
subnet_enforce_private_link_endpoint_network_policies A map of subnet name to enable/disable private link endpoint network policies on the subnet. map(bool) {} no
subnet_enforce_private_link_service_network_policies A map of subnet name to enable/disable private link service network policies on the subnet. map(bool) {} no
subnet_names A list of public subnets inside the vNet. list(string)
[
"subnet1",
"subnet2",
"subnet3"
]
no
subnet_prefixes The address prefix to use for the subnet. list(string)
[
"10.0.1.0/24",
"10.0.2.0/24",
"10.0.3.0/24"
]
no
subnet_service_endpoints A map of subnet name to service endpoints to add to the subnet. map(any) {} no
tags The tags to associate with your network and subnets. map(string)
{
"ENV": "test"
}
no
tracing_tags_enabled Whether enable tracing tags that generated by BridgeCrew Yor. bool false no
tracing_tags_prefix Default prefix for generated tracing tags string "avm_" no
use_for_each Use for_each instead of count to create multiple resource instances. bool n/a yes
vnet_location The location of the vnet to create. string n/a yes
vnet_name Name of the vnet to create string "acctvnet" no

Outputs

Name Description
vnet_address_space The address space of the newly created vNet
vnet_guid The GUID of the newly created vNet
vnet_id The id of the newly created vNet
vnet_location The location of the newly created vNet
vnet_name The Name of the newly created vNet
vnet_subnets The ids of subnets created inside the newly created vNet
vnet_subnets_name_id Can be queried subnet-id by subnet name by using lookup(module.vnet.vnet_subnets_name_id, subnet1)

terraform-azurerm-vnet's People

Contributors

allengeer avatar bamaralf avatar dennizz avatar dependabot[bot] avatar foreverxzc avatar github-actions[bot] avatar jiaweitao001 avatar jmapro avatar kangjk1017 avatar lonegunmanb avatar mathsnunes avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar mrparkers avatar msftgits avatar pumpkin-3906 avatar radzag avatar rguthriemsft avatar sionsmith avatar stanleyz avatar stephaneclavel avatar vaijanathb avatar vinshetty avatar yupwei68 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-azurerm-vnet's Issues

Circular dependency on resource group

I have a circular dependency with this module whereby on a new deployment it fails to find the resource group. On closer inspection this is due to the data lookup to find the vnet location from the resource group location. I have worked around this by adding a dependency to the calling modules on the resource group, however as its a hard dependency a tag change for example on the resource group causes the attempted destruction of the virtual network and everything else that relies on it.

I have seen the issue #43 but the reason I am creating my own issue is because I potentially have a way to fix this without causing a braking change.

If we make the data lookup happen only if the vnet_location variable is not defined:

data "azurerm_resource_group" "vnet" {
  count = var.vnet_location != null ? 0 : 1
  name = var.resource_group_name
}

We can then specify the resource group name explicitly (remove the data source) and only use it if the vnet_location is not defined:

resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  resource_group_name = var.resource_group_name
  location            = var.vnet_location != null ? var.vnet_location : data.azurerm_resource_group.vnet[0].location
[...]
}

resource "azurerm_subnet" "subnet" {
  count                                          = length(var.subnet_names)
  name                                           = var.subnet_names[count.index]
  resource_group_name                            = var.resource_group_name
[...]
}

To be clear I prefer the suggested solution in #43 but wanted to suggest a possible way forward that didn't involve a breaking change.

Subnet delegation syntax

Would like to add a service delegation to my subnet but do not know the syntax to associate a subnet to a subnet delegation ? Thank you

Modification of Tags forces rebuild of VNET

The following code will successfully deploy a VNET with one Subnet and a Security Group with 4 tags

`terraform {
required_version = "> 0.13.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 2.49.0"
}
}
}

provider "azurerm" {

subscription_id = var.subscription_id
client_id = var.client_id
client_secret = var.client_secret
tenant_id = var.tenant_id

features {}
}

locals {
common_tags = {
Environment = "Production"
Product = "MRCProduct"
Product_Organization = "MRC"
Datacenter = "Azure East US"
}
}

resource "azurerm_resource_group" "mgmt" {
name = "mrc-mgmt-rg01"
location = "East US"

tags = local.common_tags
}

module "mgmt-network" {
source = "Azure/vnet/azurerm"
version = "2.4.0"
vnet_name = "mrc-mgmt-vnet"
resource_group_name = azurerm_resource_group.mgmt.name
address_space = ["10.10.0.0/23"]
subnet_prefixes = ["10.10.0.0/27"]
subnet_names = ["mrc-mgmt-ad"]
dns_servers = []

nsg_ids = {
"mrc-mgmt-ad" = azurerm_network_security_group.ad.id
}

tags = local.common_tags

depends_on = [azurerm_resource_group.mgmt]
}

resource "azurerm_network_security_group" "ad" {
name = "mrc-mgmt-ad-nsg"
resource_group_name = azurerm_resource_group.mgmt.name
location = azurerm_resource_group.mgmt.location

tags = local.common_tags
}`

Unfortunately if I try to re-run this code updating or changing the Tags I recieve the following result that wants to rebuild the VNET

module.mgmt-network.azurerm_virtual_network.vnet must be replaced

-/+ resource "azurerm_virtual_network" "vnet" {
~ guid = "9d834e0d-7801-4032-b0c7-4bc0b29c3d8e" -> (known after apply)
~ id = "/subscriptions/22fa4733-0585-4e85-9962-e4242aaf829f/resourceGroups/mrc-mgmt-rg01/providers/Microsoft.Network/virtualNetworks/mrc-mgmt-vnet" -> (known after apply)
~ location = "eastus" -> (known after apply) # forces replacement
name = "mrc-mgmt-vnet"
~ subnet = [
- {
- address_prefix = "10.10.0.0/27"
- id = "/subscriptions/22fa4733-0585-4e85-9962-e4242aaf829f/resourceGroups/mrc-mgmt-rg01/providers/Microsoft.Network/virtualNetworks/mrc-mgmt-vnet/subnets/mrc-mgmt-ad"
- name = "mrc-mgmt-ad"
- security_group = "/subscriptions/22fa4733-0585-4e85-9962-e4242aaf829f/resourceGroups/mrc-mgmt-rg01/providers/Microsoft.Network/networkSecurityGroups/mrc-mgmt-ad-nsg"
},
] -> (known after apply)
~ tags = {
~ "Datacenter" = "Azure West US" -> "Azure East US"
# (3 unchanged elements hidden)
}
# (4 unchanged attributes hidden)
}

Plan: 1 to add, 2 to change, 1 to destroy.


Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

enforce_private_link_endpoint_network_policies Deprecation warning when using azurerm v3.24.0

When using azurerm v3.24.0 we get the following deprecation warning when running a plan with this module:

│ Warning: Argument is deprecated

│ with module.firewall.module.network.azurerm_subnet.subnet,
│ on .terraform\modules\firewall.network\main.tf line 22, in resource "azurerm_subnet" "subnet":
│ 22: enforce_private_link_endpoint_network_policies = lookup(var.subnet_enforce_private_link_endpoint_network_policies, var.subnet_names[count.index], false)

enforce_private_link_endpoint_network_policies will be removed in favour of the property
private_endpoint_network_policies_enabled in version 4.0 of the AzureRM Provider

Second run after a modification results in the network group not applying

I'm using the example right off the web page. subnet1 is assigned the network security group "ssh".

I was calling this module from within another module that I own. It worked fine the first time. But I'm re-orging some of terrform into separate files and it triggered a change, and it is removing the "ssh" security group.

`

Create the resource group and network

module "network" {
source = "Azure/network/azurerm"
resource_group_name = "${var.resource_group}"
location = "westus"
address_space = "10.0.0.0/16"
subnet_prefixes = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
subnet_names = ["subnet1", "subnet2", "subnet3"]
vnet_name = "${var.vnet_name}"

tags = {
environment = "${var.environment_tag}"
terraform = "true"
}
}

resource "azurerm_subnet" "subnet" {
name = "subnet1"
depends_on = ["azurerm_network_security_group.ssh"]
address_prefix = "10.0.1.0/24"
resource_group_name = "${var.resource_group}"
virtual_network_name = "${var.vnet_name}"
network_security_group_id = "${azurerm_network_security_group.ssh.id}"
}

resource "azurerm_network_security_group" "ssh" {

name = "ssh"
location = "westus"
resource_group_name = "${var.resource_group}"

security_rule {
name = "test123"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = ""
destination_port_range = "22"
source_address_prefix = "
"
destination_address_prefix = "*"
}
}

output "ssh" {
value = "${azurerm_network_security_group.ssh.name}"
}

output "subnet" {
value = "${azurerm_subnet.subnet.name}"
}

output "subnet_ids" {
value = "${module.network.vnet_subnets}"
}
`

Same code, just re-orged some things and I get this. It is removing the sg, even though my state says it should be there. I have a feeling this is somehow related to the depends_on.

`
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place

Terraform will perform the following actions:

~ module.vnet.azurerm_subnet.subnet
network_security_group_id: "/subscriptions/xxxxxxxx/resourceGroups/DevGroup/providers/Microsoft.Network/networkSecurityGroups/ssh" => "/subscriptions/xxxxx/resourceGroups/terraform-dev/providers/Microsoft.Network/networkSecurityGroups/ssh"

~ module.vnet.module.network.azurerm_subnet.subnet[0]
network_security_group_id: "/subscriptions/xxxxxxxx/resourceGroups/DevGroup/providers/Microsoft.Network/networkSecurityGroups/ssh" => ""

Plan: 0 to add, 2 to change, 0 to destroy.
`

Support for `bgp_community`

Is there an existing issue for this?

  • I have searched the existing issues

Description

As user, we might want to set bgp_community argument for azurerm_virtual_network resource.

New or Affected Resource(s)/Data Source(s)

azurerm_virtual_network

Potential Terraform Configuration

No response

References

No response

The default number of subnet prefixes should be 3

There are 3x subnet names defined as a default variable but only 1x subnet prefix which results in an error if you use this module without specifying any of the optional variables.

I'm calling the module with the following resource block (which should work based on the docs):

module "vnet" {
  source  = "Azure/vnet/azurerm"
  version = "2.6.0"
  resource_group_name = azurerm_resource_group.example.name
  vnet_location = "West Europe"
}

This results in this error (because there should be 3x subnet prefixes in the default vars to match the 3x subnet names):

│ Error: Invalid index
│
│   on .terraform/modules/vnet/main.tf line 20, in resource "azurerm_subnet" "subnet":
│   20:   address_prefixes                               = [var.subnet_prefixes[count.index]]
│     ├────────────────
│     │ count.index is 1
│     │ var.subnet_prefixes is list of string with 1 element
│
│ The given key does not identify an element in this collection value: the given index is greater than or equal to the length of the collection.
╵
╷
│ Error: Invalid index
│
│   on .terraform/modules/vnet/main.tf line 20, in resource "azurerm_subnet" "subnet":
│   20:   address_prefixes                               = [var.subnet_prefixes[count.index]]
│     ├────────────────
│     │ count.index is 2
│     │ var.subnet_prefixes is list of string with 1 element
│
│ The given key does not identify an element in this collection value.

I was going to raise a pull request since it's such an easy fix, but I'm having issues running the tests 😬

Unable to parse network security id error

This is the error message I get using the default settings from the example:

Unable to parse Network Security Group ID "nsgid3": Cannot parse Azure ID: parse nsgid3: invalid URI for request

The code to trigger the error:

resource "azurerm_resource_group" "myresourcegroup" {
  name     = "${var.prefix}-workshop"
  location = var.location
}

module "vnet" {
    source              = "Azure/vnet/azurerm"
    resource_group_name = azurerm_resource_group.myresourcegroup.name
    location            = "centralus"
    address_space       = "10.0.0.0/16"
    subnet_prefixes     = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
    subnet_names        = ["subnet1", "subnet2", "subnet3"]

    tags                = {
                            environment = "dev"
                            costcenter  = "it"
                          }
}

datasource resource group assumes its built outside of the current TF

Error: Error: Resource Group "aks-ricky-test" was not found
  on .terraform/modules/network/main.tf line 2, in data "azurerm_resource_group" "vnet":
   2: data azurerm_resource_group "vnet" {

Unable to use this module if the resource group passed is in the same TF build as per how datasources work.

Get rid of deprecated index syntax in `outputs.tf` file

Is there an existing issue for this?

  • I have searched the existing issues

Description

Currently we have deprecated index syntax in our outputs.tf file and we should replace it with bracket syntax.

New or Affected Resource(s)/Data Source(s)

outputs

Potential Terraform Configuration

No response

References

No response

Support for Private DNS

Is there an existing issue for this?

  • I have searched the existing issues

Description

Hello,

do you think is it worth to implement Private DNS support in this vnet module? I know it's technically different part of azure service, but imo in most cases vnet setup is related to private dns setup. It's needed to allow us to connect to many services over LAN connections.

I can take care about implementation, but question is whether it makes sense?

New or Affected Resource(s)/Data Source(s)

azurerm_private_dns_zone

Potential Terraform Configuration

No response

References

No response

Support for RG name in outputs.tf

Is there an existing issue for this?

  • I have searched the existing issues

Description

Needed when you have to assign the right RG and VNet dynamically during resource creation, and you have to loop over multiple VNets

New or Affected Resource(s)/Data Source(s)

azurerm_virtual_network.vnet.resource_group_name

Potential Terraform Configuration

output "resource_group_name" {
  description = "The name of the resource group in which the virtual network was created"
  value       = azurerm_virtual_network.vnet.resource_group_name
}

References

No response

Missing required argument

Current configuration

(base) ➜  vnet git:(main) ✗ terraform -v  
Terraform v1.0.0
on darwin_amd64
+ provider registry.terraform.io/hashicorp/azurerm v2.0.0

While running terraform plan I am getting this error -

│ Error: Missing required argument
│ 
│   on .terraform/modules/vnet/main.tf line 15, in resource "azurerm_subnet" "subnet":
│   15: resource "azurerm_subnet" "subnet" {
│ 
│ The argument "address_prefix" is required, but no definition was found.
╵
╷
│ Error: Unsupported argument
│ 
│   on .terraform/modules/vnet/main.tf line 20, in resource "azurerm_subnet" "subnet":
│   20:   address_prefixes                               = [var.subnet_prefixes[count.index]]
│ 
│ An argument named "address_prefixes" is not expected here. Did you mean "address_prefix"?

my main.tf file code is

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=2.0.0"
    }
  }
}

provider "azurerm" {
    # version = "=2.0.0"
    subscription_id = var.subscriptionId

    features {}
}

module "vnet" {
  source              = "Azure/vnet/azurerm"
  resource_group_name = var.resourceGroupName
  address_space       = ["10.0.0.0/16"]
  subnet_prefixes     = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  subnet_names        = ["subnet1", "subnet2", "subnet3"]

  subnet_service_endpoints = {
    subnet2 = ["Microsoft.Storage", "Microsoft.Sql"],
    subnet3 = ["Microsoft.AzureActiveDirectory"]
  }

  tags = {
    environment = "dev"
    costcenter  = "it"
  }

  depends_on = [var.resourceGroupName]
}

subnet formatting

Would this project be willing to change the subnet information into a list similar to how the terraform_auzrerm_netowrk_security_group project does their NSG rules?

It makes it so all the subnet information is logically together:

    subnets = [
        {
            subnet_name                     = ...
            resource_group_name       = ...
            virtual_network_name        = ...
            subnet_address_prefix        = ...
            route_table_id                     = ...
            network_security_group_id = ...
        },
        {
            subnet_name                     = ...
            resource_group_name       = ...
            virtual_network_name        = ...
            subnet_address_prefix        = ...
            route_table_id                     = ...
            network_security_group_id = ...
        },
        ...
    ]

instead of:

    subnet_prefixes     = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
    subnet_names        = ["subnet1", "subnet2", "subnet3"]
    nsg_ids = {
        subnet1 = "nsgid1"
        subnet2 = "nsgid2"
        subnet3 = "nsgid3"
    }
    ...

Explicitly passing a provider returns a warning

I'm trying to use this module to create VNets in two different subscriptions. I have provider aliases configured and passing providers to each invocation of the module does provision successfully, however during terraform apply I get the following warning:

╷
│ Warning: Provider azurerm is undefined
│ 
│   on network.tf line 16, in module "sandbox_1_vnet_lab_eastus_001":
│   16:   providers           = { azurerm = azurerm.sandbox_1 }
│ 
│ Module module.sandbox_1_vnet_lab_eastus_001 does not declare a provider named azurerm.
│ If you wish to specify a provider configuration for the module, add an entry for azurerm in the required_providers block within the
│ module.
│ 
│ (and one more similar warning elsewhere)
╵

Here's an adapted version of my Terraform config:

providers.tf

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
    }
  }
}

provider "azurerm" {
  alias           = "sandbox_1"
  subscription_id = "00000000-0000-4fef-a05a-e992397ac169"
  features {}
}

provider "azurerm" {
  alias           = "sandbox_2"
  subscription_id = "00000000-0000-4b42-a4ef-082529c9826c"
  features {}
}

provider "azurerm" {
  alias           = "sandbox_3"
  subscription_id = "00000000-0000-414b-a936-3196a5a9c2a6"
  features {}
}

variables.tf

variable "sandbox_1_vnet_address_space" {
  type        = list(string)
  description = "Address space(s) for the virtual network in CIDR notation"
}

variable "sandbox_1_vnet_subnets" {
  type        = map(string)
  description = "Subnet names and address space (CIDR notation)"
}

variable "sandbox_3_vnet_address_space" {
  type        = list(string)
  description = "Address space(s) for the virtual network in CIDR notation"
}

variable "sandbox_3_vnet_subnets" {
  type        = map(string)
  description = "Subnet names and address space (CIDR notation)"
}

network.tf

resource "azurerm_resource_group" "sandbox_1_rg-lab_net_001" {
  provider = azurerm.sandbox_1
  name     = "rg-lab-net-001"
  location = "East US"
}

resource "azurerm_resource_group" "sandbox_3_rg-lab_net_001" {
  provider = azurerm.sandbox_3
  name     = "rg-lab-net-001"
  location = "East US"
}

module "sandbox_1_vnet_lab_eastus_001" {
  providers           = { azurerm = azurerm.sandbox_1 }
  source              = "Azure/vnet/azurerm"
  vnet_name           = "vnet-lab-eastus-001"
  resource_group_name = azurerm_resource_group.sandbox_1_rg-lab_net_001.name
  address_space       = var.sandbox_1_vnet_address_space
  subnet_prefixes     = values(var.sandbox_1_vnet_subnets)
  subnet_names        = keys(var.sandbox_1_vnet_subnets)
  depends_on = [
    azurerm_resource_group.sandbox_1_rg-lab_net_001
  ]
}

module "sandbox_3_vnet_lab_eastus_001" {
  providers           = { azurerm = azurerm.sandbox_3 }
  source              = "Azure/vnet/azurerm"
  vnet_name           = "vnet-lab-eastus-001"
  resource_group_name = azurerm_resource_group.sandbox_3_rg-lab_net_001.name
  address_space       = var.sandbox_3_vnet_address_space
  subnet_prefixes     = values(var.sandbox_3_vnet_subnets)
  subnet_names        = keys(var.sandbox_3_vnet_subnets)
  depends_on = [
    azurerm_resource_group.sandbox_3_rg-lab_net_001
  ]
}

Subnet resources recreated when network list modified

resource "azurerm_subnet" "subnet" block should use for_each instead of count for creating subnet resources.
With count all subnets are recreated when the provided list of subnets to create is modified, which can be breaking change in live environment.

optional resource group creation

Would this project be open to making the creation of the resource group conditional?

Example:

    resource "azurerm_resource_group" "vnet" {
        count    = "${var.rg_create == "true" ? 1 : 0}"
        name     = "${var.resource_group_name}"
        location = "${var.location}"
    }

Resource Group variable should accept entire resource_group object

Passing in the resource_group name only and relying on depends_on on the module causes lifecycle issues for the resources in this module. E.g., if the tags on the resource group are changed then the subnets will be replaced (because of a new computed location attribute on the resource group data_source in the module).

Martin's recommendation is that:

In current versions of Terraform we generally recommend that a specific configuration should either be managing an object or reading the object using a date resource, but not both at the same time.

He then details what a variable design would be that avoids this issue:

variable "resource_group" {
  type = object({
    name     = string
    location = string
  })
}

Able to be consumed like:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "my-resources"
  location = "West Europe"
}

module "vnet" {
  source              = "Azure/vnet/azurerm"
  resource_group      = azurerm_resource_group.example
  address_space       = ["10.0.0.0/16"]
  subnet_prefixes     = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  subnet_names        = ["subnet1", "subnet2", "subnet3"]

  subnet_service_endpoints = {
    subnet2 = ["Microsoft.Storage", "Microsoft.Sql"],
    subnet3 = ["Microsoft.AzureActiveDirectory"]
  }

  tags = {
    environment = "dev"
    costcenter  = "it"
  }

}

This would obviously be a breaking change to the module (requiring a major version bump), but it wouldn't be hazardous to users: accidental upgrades would cause an error that the new variable is missing, allowing them to update the variable and continue using the module.

Error: Cycle

Running the following code

``provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "example" {
name = "tf-vnet-test-rg"
location = "West Europe"
}

module "vnet" {
source = "Azure/vnet/azurerm"
resource_group_name = azurerm_resource_group.example.name
address_space = ["10.0.0.0/16"]
subnet_prefixes = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
subnet_names = ["subnet1", "subnet2", "subnet3"]

nsg_ids = {
subnet1 = azurerm_network_security_group.ssh.id
subnet2 = azurerm_network_security_group.ssh.id
subnet3 = azurerm_network_security_group.ssh.id
}

tags = {
environment = "dev"
costcenter = "it"
}
}

resource "azurerm_network_security_group" "ssh" {
depends_on = [module.vnet]
name = "ssh"
location = "westus"
resource_group_name = var.resource_group_name

security_rule {
name = "test123"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = ""
destination_port_range = "22"
source_address_prefix = "
"
destination_address_prefix = "*"
}

}
``

getting the following error Error: Cycle: module.vnet.azurerm_subnet_network_security_group_association.vnet, azurerm_network_security_group.ssh, module.vnet.var.nsg_ids, module.vnet.data.azurerm_subnet.import, module.vnet.azurerm_subnet_route_table_association.vnet

Deprecated fields `enforce_private_link_endpoint_network_policies` and `enforce_private_link_service_network_policies` in `azurerm_subnet` resource

Is there an existing issue for this?

  • I have searched the existing issues

Description

Both the azurerm_subnet.subnet_count and azurerm_subnet.subnet_for_each use the enforce_private_link_endpoint_network_policies and enforce_private_link_service_network_policies properties which are deprecated and will be removed in version 4.0 of the AzureRM provider.

The terraform-azurerm-vnet module should be updated to use private_endpoint_network_policies_enabled and private_link_service_network_policies_enabled properties instead.

This deprecation message is shown whenever the terraform-azurerm-vnet module is used.

╷
│ Warning: Argument is deprecated
│ 
│   with module.vnet.azurerm_subnet.subnet_for_each["GatewaySubnet"],
│   on .terraform/modules/vnet/main.tf line 57, in resource "azurerm_subnet" "subnet_for_each":
│   57:   enforce_private_link_endpoint_network_policies = lookup(var.subnet_enforce_private_link_endpoint_network_policies, each.value, false)
│ 
│ `enforce_private_link_endpoint_network_policies` will be removed in favour of the property `private_endpoint_network_policies_enabled` in version 4.0 of the AzureRM Provider
│ 
│ (and one more similar warning elsewhere)

New or Affected Resource(s)/Data Source(s)

azurerm_subnet

Potential Terraform Configuration

No response

References

AzureRM provider PR that deprecated the enforce_private_link_endpoint_network_policies and enforce_private_link_service_network_policies fields: PR 17464

Do not default random tags in a reusable module

Is there an existing issue for this?

  • I have searched the existing issues

Description

Companies use systems to verify resources have tags assigned and this module passes the test as it is setting a default tag. This should be defaulted to {} to ensure users of the module are declaring their own tags.

variable "tags" {
type = map(string)
default = {
ENV = "test"
}
description = "The tags to associate with your network and subnets."
}

New or Affected Resource(s)/Data Source(s)

azurerm_virtual_network

Potential Terraform Configuration

variable "tags" {
  type = map(string)
  default = {}
  description = "The tags to associate with your network and subnets."
}

References

No response

NSG connection is not working as expected

due to the way we are creating the subnets the each.key is not linked to the subnet value.

resource "azurerm_subnet_network_security_group_association" "vnet" {
for_each = var.nsg_ids
subnet_id = local.azurerm_subnets[each.key]
network_security_group_id = each.value
}

Get resource group not found error

Is there an existing issue for this?

  • I have searched the existing issues

Greenfield/Brownfield provisioning

greenfield

Terraform Version

1.3.5

Module Version

3.0.0

AzureRM Provider Version

3.27.0

Affected Resource(s)/Data Source(s)

azurerm_resource_group

Terraform Configuration Files

variable "basename" {
  description = "(Required) Specifies the prefix to prepend to resource groups and resources name."
  type        = string
}

variable "region" {
  description = "the region where the AKS cluster will be deployed."
  type        = string
  default     = "westeurope"
}

variable "spoke_resource_group_name" {
  description = "Specifies the name of the resource group."
  type        = string
  default     = ""
}

variable "spoke_vnet_address_space" {
  description = "the address prefix of the spoke subnet."
  default     = ["10.0.0.0/16"]
  type        = list(string)
}

variable "gateway_subnet_cidr" {
  description = "the cidr of the spoke subnet application gateway is on."
  type        = string
  default     = "10.0.0.0/24"
}

variable "default_node_pool_subnet_cidr" {
  description = "the cidr of the spoke subnet aks default node pool is on."
  type        = string
  default     = "10.0.1.0/24"
}

variable "tags" {
  description = "the map of tags set on the aks cluster."
  type        = map(string)
  default     = {}
}

locals {
  spoke_vnet_name           = "${var.basename}-spoke"
  spoke_resource_group_name = coalesce(var.spoke_resource_group_name, "${var.basename}-spoke-rg")
  base_tags = {
    Deployment = "Terraform"
    Pricing = "pay-as-you-go"
  }
  tags = merge(local.base_tags, var.tags)
}

resource "azurerm_resource_group" "spoke_rg" {
  name     = local.spoke_resource_group_name
  location = var.region
}

module "spokenet" {
  source  = "Azure/vnet/azurerm"
  version = "3.0.0"

  vnet_name           = local.spoke_vnet_name
  vnet_location       = var.region
  resource_group_name = azurerm_resource_group.spoke_rg.name
  address_space       = var.spoke_vnet_address_space
  subnet_names        = ["AzureAppGatewaySubnet", "AzureDefaultNodePoolSubnet"]
  subnet_prefixes     = [var.gateway_subnet_cidr, var.default_node_pool_subnet_cidr]
  tags                = local.tags

  depends_on = [azurerm_resource_group.spoke_rg]
}

tfvars variables values

basename = "capoccione"

Debug Output/Panic Output

https://gist.github.com/fabiomarinetti/0d368b07ab943fa7f8af00f513c70963

Expected Behaviour

I expect the rgroup is correctly created before the datasource query (within module) given the depends_on constraint.

Actual Behaviour

Resource group is not found.

Steps to Reproduce

terraform init
terraform apply

Important Factoids

No response

References

This looks pretty similar to #62 but the provided workaround did not work for me.

Adding subnet forces NSG re-association

Description
When adding a subnet in config, the nsg associations are deleted and re-created.

Recreate issue

  1. Create a resource group, vnet, and a couple of subnets with NSGs in config (NSGs created outside module). Like example below.
  2. Run "terraform apply"
  3. Run "terraform plan" to see that there are no necessary changes after initial apply.
  4. Add "subnet5" with "10.0.4.0/24" in config. No NSG association.
  5. Run "terraform plan".

The plan will most likely include destruction of all NSG associations, and the subnet creation, then creation of all NSG associations again. It does not matter if the added subnet has NSGs associated.

I am using terraform 0.13.3 on Windows in PowerShell and version 2.2.0 of the vnet module.

Is this by design? Am I maybe doing something wrong with the module?

Example code:

module "vnet" {
  source  = "Azure/vnet/azurerm"
  version = "2.2.0"
  resource_group_name = azurerm_resource_group.rg.name
  address_space = ["10.0.0.0/16"]
  vnet_name = "testnet"

  subnet_names = [
    "subnet1", 
    "subnet2", 
    "subnet3",
    "subnet4"
  ]
  
  subnet_prefixes = [
    "10.0.0.0/24", 
    "10.0.1.0/24",
    "10.0.2.0/24",
    "10.0.3.0/24"
  ]

  subnet_service_endpoints = {
    "subnet1"  = ["Microsoft.Storage", "Microsoft.Sql", "Microsoft.KeyVault"],
    "subnet2"  = ["Microsoft.Storage", "Microsoft.Sql", "Microsoft.KeyVault"],
    "subnet3"  = ["Microsoft.Storage", "Microsoft.Sql", "Microsoft.KeyVault"],
    "subnet4"  = ["Microsoft.Storage", "Microsoft.Sql", "Microsoft.KeyVault"]
  }

  nsg_ids = {
    "subnet1"    = azurerm_network_security_group.subnet1-nsg.id
    "subnet2"     = azurerm_network_security_group.subnet2-nsg.id
    "subnet3"    = azurerm_network_security_group.subnet3-nsg.id
    "subnet4" = azurerm_network_security_group.subnet4-nsg.id
  }

  depends_on = [
    azurerm_resource_group.rg
  ]
}

How to import a subnet into for_each configuration?

Is there an existing issue for this?

  • I have searched the existing issues

Greenfield/Brownfield provisioning

brownfield

Terraform Version

1.4.0

Module Version

4.0.0

AzureRM Provider Version

3.61.0

Affected Resource(s)/Data Source(s)

N/A

Terraform Configuration Files

N/A

tfvars variables values

N/A

Debug Output/Panic Output

N/A

Expected Behaviour

I'm trying to import a vnet that was already created with this module in a different terraform state into another terraform state but I can't get terraform import command to work.

I'm trying to run
terraform import module.vnet.azurerm_subnet.subnet_for_each["my_subnet_name"] /subscriptions//resourceGroups//providers/Microsoft.Network/virtualNetworks//subnets/my_subnet_name

and it keeps failing with

│ Error: Index value required

│ on line 1:
│ 1: module.vnet.azurerm_subnet.subnet_for_each[pep-nonprod-01-suk-endpoints]

│ Index brackets must contain either a literal number or a literal string.

Actual Behaviour

No response

Steps to Reproduce

No response

Important Factoids

No response

References

No response

address_space var is cast to string

Resource documentation indicates that address_space can be one or multiple items. Terraform module has the variable evaluated within brackets [], so there is no opportunity to send in a list to the module.

Using `network_security_group_id` on `azurerm_subnet` resources is deprecated

Currently get the following deprecation warnings for every subnet:

Warning: module.vnet.azurerm_subnet.subnet[0]: "network_security_group_id": [DEPRECATED] Use the `azurerm_subnet_network_security_group_association` resource instead.

Module Version

module "vnet" {
  source              = "Azure/vnet/azurerm"
  version             = "1.2.0"

Terraform Version

terraform -v
Terraform v0.11.10
+ provider.aws v1.38.0
+ provider.azurerm v1.17.0
+ provider.random v2.0.0

Module has quoted reference that is deprecated

Description

After upgrading terraform and the azurerm modules the azurerm-vnet module started giving quoted reference deprecated errors.

Terraform version

terraform -v
Terraform v0.12.24

  • provider.azuread v0.8.0
  • provider.azurerm v2.8.0
  • provider.null v2.1.2
  • provider.random v2.2.1
  • provider.vault v2.10.0

Terraform script

module "my-vnet" {
  vnet_name           = "my-vnet"
  source              = "Azure/vnet/azurerm"
  resource_group_name = azurerm_resource_group.my-rg.name
  address_space       = [var.my-vnet-cidr]
  subnet_prefixes     = var.my-vnet-subnets
  subnet_names        = var.my-vnet-subnet-names

  tags = {
    Terraform   = "true"
    Environment = "prod"
    Lab     = "true"
    Pod     = "my-pod"
  }
}

Error

terraform validate

Warning: "address_prefix": [DEPRECATED] Use the `address_prefixes` property instead.

  on .terraform/modules/my-vnet/terraform-azurerm-vnet-2.0.0/main.tf line 15, in resource "azurerm_subnet" "subnet":
  15: resource "azurerm_subnet" "subnet" {



Warning: Quoted references are deprecated

  on .terraform/modules/my-vnet/terraform-azurerm-vnet-2.0.0/main.tf line 29, in data "azurerm_subnet" "import":
  29:   depends_on = ["azurerm_subnet.subnet"]

In this context, references are expected literally rather than in quotes.
Terraform 0.11 and earlier required quotes, but quoted references are now
deprecated and will be removed in a future version of Terraform. Remove the
quotes surrounding this reference to silence this warning.

(and one more similar warning elsewhere)

Success! The configuration is valid, but there were some validation warnings as shown above.

Issue calling modules variables from within a another module

Hello:

NSG Module:
#Module VNET
module "vnet" {
source = "../vnet"
}

#NSG
resource "azurerm_network_security_group" "nsg" {
name = "${element(var.nsg_names, count.index)}"
resource_group_name = "${module.vnet.resource_group}"
location = "${module.vnet.location}"
count = 3
}
I have two modules VNet and NSG and when i try to call out the vnet module from the NSG: i get the following errors:
.....Error: resource 'azurerm_network_security_group.nsg' config: "resource_group" is not a valid output for module "vnet"
.....Error: resource 'azurerm_network_security_group.nsg' config: "location" is not a valid output for module "vnet"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.