From 3479691ff82cd7cb2414b2d2b4635615174ae2fd Mon Sep 17 00:00:00 2001 From: Alex Shemyakin Date: Tue, 19 Aug 2025 10:31:55 +0200 Subject: [PATCH 1/4] upgrade versions and ip list --- .../vnet-for-ingress-egress-gw/versions.tf | 6 +++--- main.tf | 20 +++++++++++++++++++ versions.tf | 4 ++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/examples/vnet-for-ingress-egress-gw/versions.tf b/examples/vnet-for-ingress-egress-gw/versions.tf index 33b28df..eb3b017 100644 --- a/examples/vnet-for-ingress-egress-gw/versions.tf +++ b/examples/vnet-for-ingress-egress-gw/versions.tf @@ -4,15 +4,15 @@ terraform { required_providers { random = { source = "hashicorp/random" - version = ">=3.0" + version = ">=3.7.2" } volterra = { source = "volterraedge/volterra" - version = "=0.11.26" + version = "=0.11.44" } azurerm = { source = "hashicorp/azurerm" - version = ">=4.4.0" + version = ">=4.39.0" } } } diff --git a/main.tf b/main.tf index af289ae..d3026eb 100644 --- a/main.tf +++ b/main.tf @@ -28,6 +28,9 @@ locals { "185.94.143.0/25", "159.60.190.0/24", "159.60.168.0/24", + "159.60.180.0/24", + "159.60.174.0/24", + "159.60.176.0/24", ] europe_tcp_80_443_range = [ "5.182.213.0/25", @@ -39,6 +42,8 @@ locals { "159.60.160.0/24", "159.60.162.0/24", "159.60.188.0/24", + "159.60.182.0/24", + "159.60.178.0/24", ] asia_tcp_80_443_range = [ "103.135.56.0/25", @@ -50,6 +55,11 @@ locals { "159.60.189.0/24", "159.60.166.0/24", "159.60.164.0/24", + "159.60.170.0/24", + "159.60.172.0/24", + "159.60.191.0/24", + "159.60.184.0/24", + "159.60.186.0/24", ] americas_udp_4500_range = [ "5.182.215.0/25", @@ -59,6 +69,10 @@ locals { "185.94.142.0/25", "185.94.143.0/25", "159.60.190.0/24", + "159.60.168.0/24", + "159.60.180.0/24", + "159.60.174.0/24", + "159.60.176.0/24", ] europe_udp_4500_range = [ "5.182.213.0/25", @@ -70,6 +84,8 @@ locals { "159.60.160.0/24", "159.60.162.0/24", "159.60.188.0/24", + "159.60.182.0/24", + "159.60.178.0/24", ] asia_udp_4500_range = [ "103.135.56.0/25", @@ -81,6 +97,10 @@ locals { "159.60.189.0/24", "159.60.166.0/24", "159.60.164.0/24", + "159.60.170.0/24", + "159.60.172.0/24", + "159.60.184.0/24", + "159.60.186.0/24", ] } diff --git a/versions.tf b/versions.tf index 910b32f..e7be11b 100644 --- a/versions.tf +++ b/versions.tf @@ -4,11 +4,11 @@ terraform { required_providers { random = { source = "hashicorp/random" - version = ">=3.0.0" + version = ">=3.7.2" } azurerm = { source = "hashicorp/azurerm" - version = ">= 4.4.0" + version = ">= 4.39.0" } } } From 08b99a9f9c0b055feb9db5d51a88367df6316838 Mon Sep 17 00:00:00 2001 From: Alex Shemyakin Date: Tue, 19 Aug 2025 10:39:23 +0200 Subject: [PATCH 2/4] add linter --- .github/workflows/terraform-lint.yml | 69 +++++++++ .tflint.hcl | 61 ++++++++ .vscode/extensions.json | 5 + .vscode/settings.json | 27 ++++ .vscode/tasks.json | 121 ++++++++++++++++ examples/vnet-for-ingress-egress-gw/main.tf | 10 +- .../vnet-for-ingress-egress-gw/versions.tf | 2 +- main.tf | 132 ++++-------------- modules/azure-nsg-rules/main.tf | 116 ++++++++------- modules/azure-nsg-rules/variables.tf | 8 +- modules/azure-nsg-rules/versions.tf | 2 +- outputs.tf | 22 +-- variables.tf | 20 +-- versions.tf | 2 +- 14 files changed, 402 insertions(+), 195 deletions(-) create mode 100644 .github/workflows/terraform-lint.yml create mode 100644 .tflint.hcl create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json diff --git a/.github/workflows/terraform-lint.yml b/.github/workflows/terraform-lint.yml new file mode 100644 index 0000000..867ca0a --- /dev/null +++ b/.github/workflows/terraform-lint.yml @@ -0,0 +1,69 @@ +name: Terraform Lint + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main ] + +jobs: + tflint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Cache plugin dir + uses: actions/cache@v3 + with: + path: ~/.tflint.d/plugins + key: ${{ hashFiles('.tflint.hcl') }} + + - uses: terraform-linters/setup-tflint@v4 + with: + tflint_version: v0.50.3 + + - name: Show version + run: tflint --version + + - name: Init TFLint + run: tflint --init + + - name: Run TFLint + run: tflint --format compact + + - name: Run TFLint on modules + run: | + find . -name "*.tf" -exec dirname {} \; | sort -u | while read dir; do + echo "Linting $dir" + (cd "$dir" && tflint --format compact) + done + + terraform-fmt: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: "1.8.0" + + - name: Terraform Format Check + run: terraform fmt -check -recursive -diff + + terraform-validate: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: "1.8.0" + + - name: Terraform Init + run: terraform init -backend=false + + - name: Terraform Validate + run: terraform validate diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000..787bbc0 --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,61 @@ +plugin "terraform" { + enabled = true + preset = "recommended" +} + +plugin "aws" { + enabled = true + version = "0.29.0" + source = "github.com/terraform-linters/tflint-ruleset-aws" +} + +rule "terraform_deprecated_interpolation" { + enabled = true +} + +rule "terraform_unused_declarations" { + enabled = true +} + +rule "terraform_comment_syntax" { + enabled = true +} + +rule "terraform_documented_outputs" { + enabled = true +} + +rule "terraform_documented_variables" { + enabled = true +} + +rule "terraform_typed_variables" { + enabled = true +} + +rule "terraform_module_pinned_source" { + enabled = true +} + +rule "terraform_naming_convention" { + enabled = true + format = "snake_case" +} + +rule "terraform_standard_module_structure" { + enabled = true +} + +# AWS-specific rules +rule "aws_resource_missing_tags" { + enabled = true + tags = ["Name", "Environment"] +} + +rule "aws_instance_invalid_type" { + enabled = true +} + +rule "aws_security_group_rule_invalid_protocol" { + enabled = true +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..445eef6 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "hashicorp.terraform" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4d87e2f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,27 @@ +{ + "terraform.validation.enableEnhancedValidation": true, + "terraform.languageServer.enable": true, + "terraform.codelens.referenceCount": true, + "files.associations": { + "*.tf": "terraform", + "*.tfvars": "terraform", + "*.tfvars.example": "terraform", + ".tflint.hcl": "hcl" + }, + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.formatDocument": "explicit" + }, + "[terraform]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.insertSpaces": true, + "editor.tabSize": 2 + }, + "[hcl]": { + "editor.defaultFormatter": "hashicorp.terraform", + "editor.formatOnSave": true, + "editor.insertSpaces": true, + "editor.tabSize": 2 + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..25a452f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,121 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Terraform: Format", + "type": "shell", + "command": "terraform", + "args": [ + "fmt", + "-recursive" + ], + "group": "build", + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "Terraform: Validate", + "type": "shell", + "command": "terraform", + "args": [ + "validate" + ], + "group": "test", + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + }, + "dependsOn": "Terraform: Init (no backend)" + }, + { + "label": "Terraform: Init (no backend)", + "type": "shell", + "command": "terraform", + "args": [ + "init", + "-backend=false" + ], + "group": "build", + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "TFLint: Initialize", + "type": "shell", + "command": "tflint", + "args": [ + "--init" + ], + "group": "build", + "presentation": { + "echo": true, + "reveal": "silent", + "focus": false, + "panel": "shared" + }, + "problemMatcher": [] + }, + { + "label": "TFLint: Run", + "type": "shell", + "command": "tflint", + "args": [ + "--format", + "compact" + ], + "group": "test", + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + }, + "dependsOn": "TFLint: Initialize", + "problemMatcher": [ + { + "owner": "tflint", + "fileLocation": "relative", + "pattern": { + "regexp": "^([^:]+):(\\d+):(\\d+):\\s+(Error|Warning|Notice):\\s+(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + } + ] + }, + { + "label": "Terraform: Full Lint Check", + "dependsOrder": "sequence", + "dependsOn": [ + "Terraform: Format", + "Terraform: Validate", + "TFLint: Run" + ], + "group": { + "kind": "test", + "isDefault": true + }, + "presentation": { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + } + } + ] +} \ No newline at end of file diff --git a/examples/vnet-for-ingress-egress-gw/main.tf b/examples/vnet-for-ingress-egress-gw/main.tf index 2b1b8bd..e299309 100644 --- a/examples/vnet-for-ingress-egress-gw/main.tf +++ b/examples/vnet-for-ingress-egress-gw/main.tf @@ -11,9 +11,9 @@ module "azure_vnet" { source = "../.." create_resource_group = false - resource_group_name = "azure_terraform_demo" - location = var.azure_rg_location - vnet_cidr = "192.168.0.0/16" - outside_subnets = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"] - inside_subnets = ["192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"] + resource_group_name = "azure_terraform_demo" + location = var.azure_rg_location + vnet_cidr = "192.168.0.0/16" + outside_subnets = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"] + inside_subnets = ["192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"] } diff --git a/examples/vnet-for-ingress-egress-gw/versions.tf b/examples/vnet-for-ingress-egress-gw/versions.tf index eb3b017..8270ba6 100644 --- a/examples/vnet-for-ingress-egress-gw/versions.tf +++ b/examples/vnet-for-ingress-egress-gw/versions.tf @@ -1,6 +1,6 @@ terraform { required_version = ">= 1.4.0" - + required_providers { random = { source = "hashicorp/random" diff --git a/main.tf b/main.tf index d3026eb..ee012f7 100644 --- a/main.tf +++ b/main.tf @@ -6,102 +6,18 @@ resource "random_string" "random" { } locals { - create_outside_subnet = local.outside_subnets_len > 0 - create_local_subnet = local.local_subnets_len > 0 - create_inside_subnet = local.inside_subnets_len > 0 - outside_subnets_len = length(var.outside_subnets) - local_subnets_len = length(var.local_subnets) - inside_subnets_len = length(var.inside_subnets) - resource_group_name = var.resource_group_name - create_resource_group = var.create_resource_group - vnet_name = var.name != null ? var.name : format("%s-vnet", random_string.random.result) - vnet_id = var.create_vnet ? azurerm_virtual_network.this[0].id : data.azurerm_virtual_network.this[0].id - vnet_cidr = var.create_vnet ? tolist(azurerm_virtual_network.this[0].address_space)[0] : tolist(data.azurerm_virtual_network.this[0].address_space)[0] - existing_vnet_name = var.create_vnet ? azurerm_virtual_network.this[0].name : local.vnet_name - az_names = slice(["1","2","3"], 0, max(local.outside_subnets_len, local.local_subnets_len, local.inside_subnets_len)) - americas_tcp_80_443_range = [ - "5.182.215.0/25", - "84.54.61.0/25", - "23.158.32.0/25", - "84.54.62.0/25", - "185.94.142.0/25", - "185.94.143.0/25", - "159.60.190.0/24", - "159.60.168.0/24", - "159.60.180.0/24", - "159.60.174.0/24", - "159.60.176.0/24", - ] - europe_tcp_80_443_range = [ - "5.182.213.0/25", - "5.182.212.0/25", - "5.182.213.128/25", - "5.182.214.0/25", - "84.54.60.0/25", - "185.56.154.0/25", - "159.60.160.0/24", - "159.60.162.0/24", - "159.60.188.0/24", - "159.60.182.0/24", - "159.60.178.0/24", - ] - asia_tcp_80_443_range = [ - "103.135.56.0/25", - "103.135.57.0/25", - "103.135.56.128/25", - "103.135.59.0/25", - "103.135.58.128/25", - "103.135.58.0/25", - "159.60.189.0/24", - "159.60.166.0/24", - "159.60.164.0/24", - "159.60.170.0/24", - "159.60.172.0/24", - "159.60.191.0/24", - "159.60.184.0/24", - "159.60.186.0/24", - ] - americas_udp_4500_range = [ - "5.182.215.0/25", - "84.54.61.0/25", - "23.158.32.0/25", - "84.54.62.0/25", - "185.94.142.0/25", - "185.94.143.0/25", - "159.60.190.0/24", - "159.60.168.0/24", - "159.60.180.0/24", - "159.60.174.0/24", - "159.60.176.0/24", - ] - europe_udp_4500_range = [ - "5.182.213.0/25", - "5.182.212.0/25", - "5.182.213.128/25", - "5.182.214.0/25", - "84.54.60.0/25", - "185.56.154.0/25", - "159.60.160.0/24", - "159.60.162.0/24", - "159.60.188.0/24", - "159.60.182.0/24", - "159.60.178.0/24", - ] - asia_udp_4500_range = [ - "103.135.56.0/25", - "103.135.57.0/25", - "103.135.56.128/25", - "103.135.59.0/25", - "103.135.58.128/25", - "103.135.58.0/25", - "159.60.189.0/24", - "159.60.166.0/24", - "159.60.164.0/24", - "159.60.170.0/24", - "159.60.172.0/24", - "159.60.184.0/24", - "159.60.186.0/24", - ] + create_outside_subnet = local.outside_subnets_len > 0 + create_local_subnet = local.local_subnets_len > 0 + create_inside_subnet = local.inside_subnets_len > 0 + outside_subnets_len = length(var.outside_subnets) + local_subnets_len = length(var.local_subnets) + inside_subnets_len = length(var.inside_subnets) + resource_group_name = var.resource_group_name + vnet_name = var.name != null ? var.name : format("%s-vnet", random_string.random.result) + vnet_id = var.create_vnet ? azurerm_virtual_network.this[0].id : data.azurerm_virtual_network.this[0].id + vnet_cidr = var.create_vnet ? tolist(azurerm_virtual_network.this[0].address_space)[0] : tolist(data.azurerm_virtual_network.this[0].address_space)[0] + existing_vnet_name = var.create_vnet ? azurerm_virtual_network.this[0].name : local.vnet_name + az_names = slice(["1", "2", "3"], 0, max(local.outside_subnets_len, local.local_subnets_len, local.inside_subnets_len)) } resource "azurerm_resource_group" "this" { @@ -121,17 +37,17 @@ data "azurerm_virtual_network" "this" { resource "azurerm_virtual_network" "this" { count = var.create_vnet ? 1 : 0 - name = local.vnet_name - address_space = [var.vnet_cidr] + name = local.vnet_name + address_space = [var.vnet_cidr] location = var.location resource_group_name = local.resource_group_name tags = var.tags - depends_on = [ + depends_on = [ azurerm_resource_group.this - ] + ] } resource "azurerm_subnet" "local" { @@ -142,7 +58,7 @@ resource "azurerm_subnet" "local" { virtual_network_name = local.existing_vnet_name address_prefixes = [element(var.local_subnets, count.index)] - depends_on = [ + depends_on = [ azurerm_virtual_network.this ] } @@ -155,7 +71,7 @@ resource "azurerm_subnet" "outside" { virtual_network_name = local.existing_vnet_name address_prefixes = [element(var.outside_subnets, count.index)] - depends_on = [ + depends_on = [ azurerm_virtual_network.this ] } @@ -168,7 +84,7 @@ resource "azurerm_subnet" "inside" { virtual_network_name = local.existing_vnet_name address_prefixes = [element(var.inside_subnets, count.index)] - depends_on = [ + depends_on = [ azurerm_virtual_network.this ] } @@ -182,7 +98,7 @@ resource "azurerm_network_security_group" "outside" { tags = var.tags - depends_on = [ + depends_on = [ azurerm_resource_group.this, azurerm_virtual_network.this ] @@ -198,7 +114,7 @@ module "outside_nsg_rules" { outside_subnets = var.outside_subnets local_subnets = var.local_subnets - depends_on = [ + depends_on = [ azurerm_resource_group.this, azurerm_network_security_group.outside ] @@ -210,10 +126,10 @@ resource "azurerm_network_security_group" "inside" { name = format("%s-inside-nsg", local.vnet_name) location = var.location resource_group_name = local.resource_group_name - + tags = var.tags - depends_on = [ + depends_on = [ azurerm_virtual_network.this ] } @@ -249,7 +165,7 @@ resource "azurerm_route_table" "inside" { tags = var.tags - depends_on = [ + depends_on = [ azurerm_virtual_network.this ] } diff --git a/modules/azure-nsg-rules/main.tf b/modules/azure-nsg-rules/main.tf index 608daaa..a2ff303 100644 --- a/modules/azure-nsg-rules/main.tf +++ b/modules/azure-nsg-rules/main.tf @@ -13,6 +13,9 @@ locals { "185.94.143.0/25", "159.60.190.0/24", "159.60.168.0/24", + "159.60.180.0/24", + "159.60.174.0/24", + "159.60.176.0/24", ] europe_tcp_80_443_range = [ "5.182.213.0/25", @@ -24,6 +27,8 @@ locals { "159.60.160.0/24", "159.60.162.0/24", "159.60.188.0/24", + "159.60.182.0/24", + "159.60.178.0/24", ] asia_tcp_80_443_range = [ "103.135.56.0/25", @@ -35,6 +40,11 @@ locals { "159.60.189.0/24", "159.60.166.0/24", "159.60.164.0/24", + "159.60.170.0/24", + "159.60.172.0/24", + "159.60.191.0/24", + "159.60.184.0/24", + "159.60.186.0/24", ] americas_udp_4500_range = [ "5.182.215.0/25", @@ -44,6 +54,10 @@ locals { "185.94.142.0/25", "185.94.143.0/25", "159.60.190.0/24", + "159.60.168.0/24", + "159.60.180.0/24", + "159.60.174.0/24", + "159.60.176.0/24", ] europe_udp_4500_range = [ "5.182.213.0/25", @@ -55,6 +69,8 @@ locals { "159.60.160.0/24", "159.60.162.0/24", "159.60.188.0/24", + "159.60.182.0/24", + "159.60.178.0/24", ] asia_udp_4500_range = [ "103.135.56.0/25", @@ -66,6 +82,10 @@ locals { "159.60.189.0/24", "159.60.166.0/24", "159.60.164.0/24", + "159.60.170.0/24", + "159.60.172.0/24", + "159.60.184.0/24", + "159.60.186.0/24", ] } @@ -79,8 +99,8 @@ resource "azurerm_network_security_rule" "americas_tcp_80_443_range" { destination_port_ranges = ["80", "443"] source_address_prefixes = local.americas_tcp_80_443_range destination_address_prefixes = setunion(var.outside_subnets, var.local_subnets) - resource_group_name = var.resource_group_name - network_security_group_name = var.network_security_group_name + resource_group_name = var.resource_group_name + network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "europe_tcp_80_443_range" { @@ -93,8 +113,8 @@ resource "azurerm_network_security_rule" "europe_tcp_80_443_range" { destination_port_ranges = ["80", "443"] source_address_prefixes = local.europe_tcp_80_443_range destination_address_prefixes = setunion(var.outside_subnets, var.local_subnets) - resource_group_name = var.resource_group_name - network_security_group_name = var.network_security_group_name + resource_group_name = var.resource_group_name + network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "asia_tcp_80_443_range" { @@ -107,12 +127,12 @@ resource "azurerm_network_security_rule" "asia_tcp_80_443_range" { destination_port_ranges = ["80", "443"] source_address_prefixes = local.asia_tcp_80_443_range destination_address_prefixes = setunion(var.outside_subnets, var.local_subnets) - resource_group_name = var.resource_group_name - network_security_group_name = var.network_security_group_name + resource_group_name = var.resource_group_name + network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "americas_udp_4500_range" { - count = var.create_udp_security_group_rules ? 1 : 0 + count = var.create_udp_security_group_rules ? 1 : 0 name = "AllowAmericasUdp-4500" priority = sum([var.priority_start, 3]) @@ -123,12 +143,12 @@ resource "azurerm_network_security_rule" "americas_udp_4500_range" { destination_port_range = "4500" source_address_prefixes = local.americas_udp_4500_range destination_address_prefixes = setunion(var.outside_subnets, var.local_subnets) - resource_group_name = var.resource_group_name - network_security_group_name = var.network_security_group_name + resource_group_name = var.resource_group_name + network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "europe_udp_4500_range" { - count = var.create_udp_security_group_rules ? 1 : 0 + count = var.create_udp_security_group_rules ? 1 : 0 name = "AllowEuropeUdp-4500" priority = sum([var.priority_start, 4]) @@ -139,12 +159,12 @@ resource "azurerm_network_security_rule" "europe_udp_4500_range" { destination_port_range = "4500" source_address_prefixes = local.europe_udp_4500_range destination_address_prefixes = setunion(var.outside_subnets, var.local_subnets) - resource_group_name = var.resource_group_name - network_security_group_name = var.network_security_group_name + resource_group_name = var.resource_group_name + network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "asia_udp_4500_range" { - count = var.create_udp_security_group_rules ? 1 : 0 + count = var.create_udp_security_group_rules ? 1 : 0 name = "AllowAsiaUdp-4500" priority = sum([var.priority_start, 5]) @@ -155,56 +175,56 @@ resource "azurerm_network_security_rule" "asia_udp_4500_range" { destination_port_range = "4500" source_address_prefixes = local.asia_udp_4500_range destination_address_prefixes = setunion(var.outside_subnets, var.local_subnets) - resource_group_name = var.resource_group_name - network_security_group_name = var.network_security_group_name + resource_group_name = var.resource_group_name + network_security_group_name = var.network_security_group_name } ## Default rules to prevent traffic from being passed through the default "140 - all" rule created by XC Cloud. resource "azurerm_network_security_rule" "vnet" { - count = var.create_default_rules ? 1 : 0 - - name = "AllowVnetInBound" - priority = sum([var.priority_start, 10]) - direction = "Inbound" - access = "Allow" - protocol = "*" - source_port_range = "*" - destination_port_range = "*" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "VirtualNetwork" + count = var.create_default_rules ? 1 : 0 + + name = "AllowVnetInBound" + priority = sum([var.priority_start, 10]) + direction = "Inbound" + access = "Allow" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "VirtualNetwork" resource_group_name = var.resource_group_name network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "load_balancer" { - count = var.create_default_rules ? 1 : 0 - - name = "AllowAzureLoadBalancerInBound" - priority = sum([var.priority_start, 11]) - direction = "Inbound" - access = "Allow" - protocol = "*" - source_port_range = "*" - destination_port_range = "*" - source_address_prefix = "AzureLoadBalancer" - destination_address_prefix = "*" + count = var.create_default_rules ? 1 : 0 + + name = "AllowAzureLoadBalancerInBound" + priority = sum([var.priority_start, 11]) + direction = "Inbound" + access = "Allow" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "AzureLoadBalancer" + destination_address_prefix = "*" resource_group_name = var.resource_group_name network_security_group_name = var.network_security_group_name } resource "azurerm_network_security_rule" "deny_other" { - count = var.create_default_rules ? 1 : 0 - - name = "DenyOther" - priority = sum([var.priority_start, 12]) - direction = "Inbound" - access = "Deny" - protocol = "*" - source_port_range = "*" - destination_port_range = "*" - source_address_prefix = "*" - destination_address_prefix = "*" + count = var.create_default_rules ? 1 : 0 + + name = "DenyOther" + priority = sum([var.priority_start, 12]) + direction = "Inbound" + access = "Deny" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "*" resource_group_name = var.resource_group_name network_security_group_name = var.network_security_group_name } \ No newline at end of file diff --git a/modules/azure-nsg-rules/variables.tf b/modules/azure-nsg-rules/variables.tf index a46d8e8..c653af8 100644 --- a/modules/azure-nsg-rules/variables.tf +++ b/modules/azure-nsg-rules/variables.tf @@ -1,13 +1,13 @@ variable "resource_group_name" { description = "The name of the resource group in which to create the VNET. Changing this forces a new resource to be created." - type = string - nullable = false + type = string + nullable = false } variable "network_security_group_name" { description = "The name of the network security group in which to create the rules. Changing this forces a new resource to be created." - type = string - nullable = false + type = string + nullable = false } variable "create_udp_security_group_rules" { diff --git a/modules/azure-nsg-rules/versions.tf b/modules/azure-nsg-rules/versions.tf index ee64e34..e8e6b0c 100644 --- a/modules/azure-nsg-rules/versions.tf +++ b/modules/azure-nsg-rules/versions.tf @@ -1,6 +1,6 @@ terraform { required_version = ">= 1.4.0" - + required_providers { azurerm = { source = "hashicorp/azurerm" diff --git a/outputs.tf b/outputs.tf index db9f658..25304ca 100644 --- a/outputs.tf +++ b/outputs.tf @@ -24,56 +24,56 @@ output "vnet_cidr" { } output "outside_subnet_ids" { - value = azurerm_subnet.outside.*.id + value = azurerm_subnet.outside[*].id description = "The IDs of the outside subnets." } output "inside_subnet_ids" { - value = azurerm_subnet.inside.*.id + value = azurerm_subnet.inside[*].id description = "The IDs of the inside subnets." } output "local_subnet_ids" { - value = azurerm_subnet.local.*.id + value = azurerm_subnet.local[*].id description = "The IDs of the local subnets." } output "outside_subnet_names" { - value = azurerm_subnet.outside.*.name + value = azurerm_subnet.outside[*].name description = "The Names of the outside subnets." } output "inside_subnet_names" { - value = azurerm_subnet.inside.*.name + value = azurerm_subnet.inside[*].name description = "The Names of the inside subnets." } output "local_subnet_names" { - value = azurerm_subnet.local.*.name + value = azurerm_subnet.local[*].name description = "The Names of the local subnets." } output "inside_route_table_ids" { - value = azurerm_route_table.inside.*.id + value = azurerm_route_table.inside[*].id description = "The IDs of the inside route tables." } output "inside_route_table_names" { - value = azurerm_route_table.inside.*.name + value = azurerm_route_table.inside[*].name description = "The names of the inside route tables." } output "outside_security_group_name" { - value = azurerm_network_security_group.outside.*.name + value = azurerm_network_security_group.outside[*].name description = "The Name of the outside security group." } output "inside_security_group_name" { - value = azurerm_network_security_group.inside.*.name + value = azurerm_network_security_group.inside[*].name description = "The Name of the inside security group." } output "az_names" { value = local.az_names description = "Availability zones." -} \ No newline at end of file +} diff --git a/variables.tf b/variables.tf index 121a369..c1fe002 100644 --- a/variables.tf +++ b/variables.tf @@ -7,13 +7,13 @@ variable "name" { variable "location" { description = "The location/region where the VNET will be created. Changing this forces a new resource to be created." type = string - nullable = false + nullable = false } variable "resource_group_name" { description = "The name of the resource group in which to create the VNET. Changing this forces a new resource to be created." - type = string - nullable = false + type = string + nullable = false } variable "create_vnet" { @@ -28,12 +28,6 @@ variable "create_resource_group" { default = true } -variable "create_outside_route_table" { - description = "Whether to create an outside route table for the outside or local subnets." - type = bool - default = true -} - variable "create_outside_security_group" { description = "Whether to create an outside security group." type = bool @@ -52,12 +46,6 @@ variable "create_inside_security_group" { default = true } -variable "create_udp_security_group_rules" { - description = "Whether to create UDP security group rules." - type = bool - default = true -} - variable "tags" { description = "A map of tags to add to all resources." type = map(string) @@ -92,4 +80,4 @@ variable "bgp_route_propagation_enabled" { description = "Whether to enable BGP route propagation." type = bool default = true -} \ No newline at end of file +} diff --git a/versions.tf b/versions.tf index e7be11b..75c6156 100644 --- a/versions.tf +++ b/versions.tf @@ -1,6 +1,6 @@ terraform { required_version = ">= 1.4.0" - + required_providers { random = { source = "hashicorp/random" From e1aadae5f3bc3d09591c870159b6e684153d332e Mon Sep 17 00:00:00 2001 From: Alex Shemyakin Date: Tue, 19 Aug 2025 11:01:06 +0200 Subject: [PATCH 3/4] update readmes --- README.md | 112 +++++++++- examples/vnet-for-ingress-egress-gw/README.md | 207 +++++++++++++++++- .../vnet-for-ingress-egress-gw/versions.tf | 4 - modules/azure-nsg-rules/README.md | 82 +++++++ modules/azure-nsg-rules/versions.tf | 2 +- 5 files changed, 382 insertions(+), 25 deletions(-) create mode 100644 modules/azure-nsg-rules/README.md diff --git a/README.md b/README.md index 7a7e0e0..d9a49d6 100644 --- a/README.md +++ b/README.md @@ -2,32 +2,120 @@ This Terraform module provisions an Azure VNET that is required for XC Cloud Azure VNET Site. It creates a VNET, subnets, route tables, and network security groups with whitelisted IP ranges. +> **Note**: This module is developed and maintained by the [F5 DevCentral](https://github.com/f5devcentral) community. You can use this module as an example for your own development projects. + +## Features + +- Creates Azure Virtual Network with configurable CIDR blocks +- Supports multiple subnet types: outside, inside, and local subnets +- Configurable network security groups with customizable rules +- Route tables for inside subnets with BGP route propagation control +- Multi-availability zone support +- Flexible resource group management (create new or use existing) +- Comprehensive tagging support + ## Requirements -| Name | Version | -|------|---------| -| [terraform](https://github.com/hashicorp/terraform) | >= 1.0 | -| [azurerm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) | >= 4.4.0 | -| [random](https://registry.terraform.io/providers/hashicorp/random/latest/docs) | >= 3.0 | +| Name | Version | +| ------------------------------------------------------------------------------------------------------------------- | --------- | +| [terraform](https://github.com/hashicorp/terraform) | >= 1.4.0 | +| [azurerm](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) | >= 4.39.0 | +| [random](https://registry.terraform.io/providers/hashicorp/random/latest/docs) | >= 3.7.2 | ## Usage +### Basic Example -To use this module and create a Azure VNET configured for XC Cloud Azure VNET Site, include the following code in your Terraform configuration: +To use this module and create an Azure VNET configured for XC Cloud Azure VNET Site, include the following code in your Terraform configuration: ```hcl module "azure_vnet" { - source = "f5devcentral/azure-vnet-site-networking/volterra" - version = "0.0.3" + source = "f5devcentral/azure-vnet-site-networking/xc" + version = "0.0.4" resource_group_name = "azure_terraform_demo" - location = var.azure_rg_location - vnet_cidr = "192.168.0.0/16" - outside_subnets = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"] - inside_subnets = ["192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"] + location = "East US" + vnet_cidr = "192.168.0.0/16" + outside_subnets = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"] + inside_subnets = ["192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"] + local_subnets = ["192.168.31.0/24", "192.168.32.0/24", "192.168.33.0/24"] + + tags = { + Environment = "production" + Project = "xc-azure-site" + } +} +``` + +### Using Existing Resource Group + +```hcl +module "azure_vnet" { + source = "f5devcentral/azure-vnet-site-networking/xc" + version = "0.0.4" + + create_resource_group = false + resource_group_name = "existing-rg" + location = "West US 2" + name = "my-xc-vnet" + vnet_cidr = "10.0.0.0/16" + outside_subnets = ["10.0.1.0/24", "10.0.2.0/24"] + inside_subnets = ["10.0.11.0/24", "10.0.12.0/24"] } ``` +## Inputs + +| Name | Description | Type | Default | +| ----------------------------- | -------------------------------------------------------------------------------------------------------------- | -------------- | ------- | +| bgp_route_propagation_enabled | Whether to enable BGP route propagation. | `bool` | `true` | +| create_inside_route_table | Whether to create an inside route table for the inside subnets. | `bool` | `true` | +| create_inside_security_group | Whether to create an inside security group. | `bool` | `true` | +| create_outside_security_group | Whether to create an outside security group. | `bool` | `true` | +| create_resource_group | Whether to create a new resource group for the VNET. Changing this forces a new resource to be created. | `bool` | `true` | +| create_vnet | Whether to create a new VNET. Changing this forces a new resource to be created. | `bool` | `true` | +| inside_subnets | Inside Subnet CIDR Blocks. | `list(string)` | `[]` | +| local_subnets | Local Subnet CIDR Blocks. | `list(string)` | `[]` | +| location | The location/region where the VNET will be created. Changing this forces a new resource to be created. | `string` | n/a | +| name | The name of the VNET. | `string` | `null` | +| outside_subnets | Outside Subnet CIDR Blocks. | `list(string)` | `[]` | +| resource_group_name | The name of the resource group in which to create the VNET. Changing this forces a new resource to be created. | `string` | n/a | +| tags | A map of tags to add to all resources. | `map(string)` | `{}` | +| vnet_cidr | The Primary IPv4 block cannot be modified. All subnets prefixes in this VNET must be part of this CIDR block. | `string` | `null` | + +## Outputs + +| Name | Description | +| --------------------------- | --------------------------------------- | +| az_names | Availability zones. | +| inside_route_table_ids | The IDs of the inside route tables. | +| inside_route_table_names | The names of the inside route tables. | +| inside_security_group_name | The Name of the inside security group. | +| inside_subnet_ids | The IDs of the inside subnets. | +| inside_subnet_names | The Names of the inside subnets. | +| local_subnet_ids | The IDs of the local subnets. | +| local_subnet_names | The Names of the local subnets. | +| location | The location/region where the VNET. | +| outside_security_group_name | The Name of the outside security group. | +| outside_subnet_ids | The IDs of the outside subnets. | +| outside_subnet_names | The Names of the outside subnets. | +| resource_group_name | The name of the resource group. | +| vnet_cidr | The CIDR block of the VNET. | +| vnet_id | The ID of the VNET. | +| vnet_name | The name of the VNET. | + +## Examples + +For detailed examples, please check the `examples/` directory: + +- [vnet-for-ingress-egress-gw](./examples/vnet-for-ingress-egress-gw/) - Example for creating a VNET for XC Cloud Ingress/Egress Gateway + +## Modules + +This module includes the following sub-modules: + +- `azure-nsg-rules` - Creates and manages Network Security Group rules for the outside subnets + ## Contributing Contributions to this module are welcome! Please see the contribution guidelines for more information. diff --git a/examples/vnet-for-ingress-egress-gw/README.md b/examples/vnet-for-ingress-egress-gw/README.md index 2582356..94ab107 100644 --- a/examples/vnet-for-ingress-egress-gw/README.md +++ b/examples/vnet-for-ingress-egress-gw/README.md @@ -1,16 +1,207 @@ -# Azure VNET for F5 XC Cloud Ingress/Egress GW Azure VNET Site +# Azure VNET for F5 XC Cloud Ingress/Egress Gateway Site -The following example will create an Azure VNET with 3 AZs, 3 subnets per AZ, and a security group. The security groups will be configured with whitelisted IP ranges for the XC Cloud Ingress/Egress GW Azure VNET Site. +This example demonstrates how to create an Azure Virtual Network (VNET) optimized for F5 Distributed Cloud (XC) Ingress/Egress Gateway deployments. It provisions a complete networking foundation with multi-availability zone support and pre-configured security groups. + +## Architecture Overview + +This example creates: + +- **Azure VNET**: A virtual network with configurable CIDR blocks +- **Outside Subnets**: 3 subnets across availability zones for external traffic +- **Inside Subnets**: 3 subnets across availability zones for internal traffic +- **Network Security Groups**: Pre-configured with F5 XC IP ranges +- **Multi-AZ Design**: Distributed across 3 availability zones for high availability + +## Prerequisites + +1. **Azure Subscription**: Active Azure subscription with appropriate permissions +2. **Terraform**: Version >= 1.4.0 +3. **Azure CLI**: Configured with appropriate credentials (optional if using service principal) +4. **Existing Resource Group**: This example uses an existing resource group + +## Configuration + +### 1. Authentication + +This example supports two authentication methods: + +#### Option A: Azure CLI (Recommended for development) +```bash +az login +az account set --subscription "your-subscription-id" +``` + +#### Option B: Service Principal (Recommended for CI/CD) +Configure the variables in `terraform.tfvars`: +```hcl +azure_subscription_id = "your-subscription-id" +azure_subscription_tenant_id = "your-tenant-id" +azure_service_principal_appid = "your-app-id" +azure_service_principal_password = "your-password" +``` + +### 2. Variables Configuration + +Copy the example variables file: +```bash +cp terraform.tfvars.example terraform.tfvars +``` + +Edit `terraform.tfvars` with your values: +```hcl +azure_subscription_id = "12345678-1234-1234-1234-123456789abc" +azure_subscription_tenant_id = "87654321-4321-4321-4321-cba987654321" +azure_rg_location = "West US 2" +``` + +## Usage + +### Quick Start + +1. **Initialize Terraform**: + ```bash + terraform init + ``` + +2. **Review the plan**: + ```bash + terraform plan + ``` + +3. **Apply the configuration**: + ```bash + terraform apply + ``` + +4. **Clean up** (when done): + ```bash + terraform destroy + ``` + +### Example Configuration ```hcl module "azure_vnet" { source = "../.." create_resource_group = false - resource_group_name = "azure_terraform_demo" - location = var.azure_rg_location - vnet_cidr = "192.168.0.0/16" - outside_subnets = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"] - inside_subnets = ["192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"] + resource_group_name = "azure_terraform_demo" + location = var.azure_rg_location + vnet_cidr = "192.168.0.0/16" + outside_subnets = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"] + inside_subnets = ["192.168.21.0/24", "192.168.22.0/24", "192.168.23.0/24"] + + tags = { + Environment = "demo" + Project = "f5-xc-gateway" + Example = "ingress-egress-gw" + } +} +``` + +## Network Design + +### Subnets + +| Subnet Type | CIDR Blocks | Purpose | Availability Zones | +| ----------- | ----------------------------------------------------- | -------------------------------- | ------------------ | +| Outside | 192.168.11.0/24
192.168.12.0/24
192.168.13.0/24 | External traffic, load balancers | AZ1, AZ2, AZ3 | +| Inside | 192.168.21.0/24
192.168.22.0/24
192.168.23.0/24 | Internal applications, workloads | AZ1, AZ2, AZ3 | + +### Security Groups + +The module automatically creates Network Security Groups with: +- **F5 XC Regional Access**: Allow traffic from F5 Distributed Cloud IP ranges +- **VNET Communication**: Allow internal communication between subnets +- **Default Deny**: Block all other inbound traffic + +## Outputs + +After deployment, the following outputs are available: + +| Output | Description | +| --------------------- | ----------------------------------------- | +| `vnet_name` | Name of the created VNET | +| `vnet_id` | Azure resource ID of the VNET | +| `vnet_cidr` | CIDR block of the VNET | +| `outside_subnet_ids` | List of outside subnet IDs | +| `inside_subnet_ids` | List of inside subnet IDs | +| `location` | Azure region where resources were created | +| `resource_group_name` | Resource group name | + +### Accessing Outputs + +```bash +# Get all outputs +terraform output + +# Get specific output +terraform output vnet_name +terraform output outside_subnet_ids +``` + +## Customization + +### Different Regions + +To deploy in a different Azure region: + +```hcl +variable "azure_rg_location" { + type = string + default = "East US" # Change to your preferred region } -``` \ No newline at end of file +``` + +### Custom CIDR Blocks + +To use different IP ranges: + +```hcl +vnet_cidr = "10.0.0.0/16" +outside_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] +inside_subnets = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"] +``` + +### Additional Subnets + +To add local subnets: + +```hcl +local_subnets = ["192.168.31.0/24", "192.168.32.0/24", "192.168.33.0/24"] +``` + +## Validation + +### Verify Resources + +1. **Check VNET creation**: + ```bash + az network vnet list --resource-group azure_terraform_demo --output table + ``` + +2. **Verify subnets**: + ```bash + az network vnet subnet list --resource-group azure_terraform_demo --vnet-name --output table + ``` + +3. **Check security groups**: + ```bash + az network nsg list --resource-group azure_terraform_demo --output table + ``` + +### Test Connectivity + +After deployment, you can: +1. Deploy F5 XC Site instances in the outside subnets +2. Deploy application workloads in the inside subnets +3. Verify connectivity according to your F5 XC site configuration + +## Next Steps + +After deploying this networking foundation: + +1. **Deploy F5 XC Site**: Use the created subnets for your F5 Distributed Cloud site +2. **Configure Applications**: Deploy your applications in the inside subnets +3. **Set up Monitoring**: Configure Azure Monitor and Network Watcher +4. **Implement Additional Security**: Add custom NSG rules if needed diff --git a/examples/vnet-for-ingress-egress-gw/versions.tf b/examples/vnet-for-ingress-egress-gw/versions.tf index 8270ba6..bbbcfae 100644 --- a/examples/vnet-for-ingress-egress-gw/versions.tf +++ b/examples/vnet-for-ingress-egress-gw/versions.tf @@ -6,10 +6,6 @@ terraform { source = "hashicorp/random" version = ">=3.7.2" } - volterra = { - source = "volterraedge/volterra" - version = "=0.11.44" - } azurerm = { source = "hashicorp/azurerm" version = ">=4.39.0" diff --git a/modules/azure-nsg-rules/README.md b/modules/azure-nsg-rules/README.md new file mode 100644 index 0000000..d5ecddc --- /dev/null +++ b/modules/azure-nsg-rules/README.md @@ -0,0 +1,82 @@ +# Azure NSG Rules Module for F5 Distributed Cloud + +This submodule creates Azure Network Security Group (NSG) rules specifically designed for F5 Distributed Cloud (XC) connectivity. It applies pre-configured security rules that allow traffic from F5 XC regional data centers while maintaining security best practices. + +## Purpose + +This module is designed to be used internally by the parent `azure-vnet-site-networking` module. It creates the necessary NSG rules to allow F5 Distributed Cloud traffic while blocking unauthorized access. + +## Security Rules Created + +The module creates the following types of security rules: + +### F5 XC Regional Traffic Rules +- **Americas TCP 80/443**: Allows HTTP/HTTPS traffic from F5 XC Americas region +- **Europe TCP 80/443**: Allows HTTP/HTTPS traffic from F5 XC Europe region +- **Asia TCP 80/443**: Allows HTTP/HTTPS traffic from F5 XC Asia region +- **Americas UDP 4500**: Allows IPSec/IKE traffic from F5 XC Americas region +- **Europe UDP 4500**: Allows IPSec/IKE traffic from F5 XC Europe region +- **Asia UDP 4500**: Allows IPSec/IKE traffic from F5 XC Asia region + +### Default Traffic Rules +- **VNET Communication**: Allows communication within the VNET subnets +- **Load Balancer Access**: Allows Azure Load Balancer health probes +- **Deny All Other**: Denies all other inbound traffic (default deny) + +## Requirements + +| Name | Version | +| --------- | --------- | +| terraform | >= 1.4.0 | +| azurerm | >= 4.39.0 | + +## Usage + +This module is typically used internally by the parent module, but can be used standalone: + +```hcl +module "nsg_rules" { + source = "./modules/azure-nsg-rules" + + resource_group_name = "my-resource-group" + network_security_group_name = "my-nsg" + outside_subnets = ["10.0.1.0/24", "10.0.2.0/24"] + local_subnets = ["10.0.10.0/24", "10.0.11.0/24"] + create_udp_security_group_rules = true + priority_start = 120 +} +``` + +## Inputs + +| Name | Description | Type | Default | +| ------------------------------- | -------------------------------------------------------- | -------------- | ------- | +| resource_group_name | The name of the resource group containing the NSG | `string` | n/a | +| network_security_group_name | The name of the network security group to add rules to | `string` | n/a | +| outside_subnets | A list of CIDR blocks for the outside subnets | `list(string)` | `[]` | +| local_subnets | A list of CIDR blocks for the local subnets | `list(string)` | `[]` | +| create_udp_security_group_rules | Whether to create UDP security group rules for IPSec/IKE | `bool` | `true` | +| priority_start | The starting priority for the security rules | `number` | `120` | +| create_default_rules | Whether to create default VNET and deny rules | `bool` | `true` | + +## Outputs + +This module does not expose any outputs. + +## F5 XC IP Ranges + +The module includes F5 Distributed Cloud IP ranges for all regions (Americas, Europe, and Asia) for both TCP (80/443) and UDP (4500) traffic. + +For the current and complete list of F5 Distributed Cloud IP ranges, please refer to the official documentation: + +**[F5 Distributed Cloud Network Reference](https://docs.cloud.f5.com/docs-v2/platform/reference/network-cloud-ref)** + +> **Note**: F5 XC IP ranges may change over time. This module contains the IP ranges that were current at the time of release. For the most up-to-date ranges, always consult the official F5 documentation above. + +## Maintenance + +This module requires periodic updates to maintain current F5 XC IP ranges. Monitor F5 documentation for any changes to regional IP ranges. + +## License + +This module is licensed under the Apache 2.0 License. diff --git a/modules/azure-nsg-rules/versions.tf b/modules/azure-nsg-rules/versions.tf index e8e6b0c..08fdd79 100644 --- a/modules/azure-nsg-rules/versions.tf +++ b/modules/azure-nsg-rules/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = ">= 4.4.0" + version = ">= 4.39.0" } } } From a7cb50f158da7e6688742faec2555dae12140848 Mon Sep 17 00:00:00 2001 From: Alex Shemyakin Date: Fri, 22 Aug 2025 16:48:03 +0200 Subject: [PATCH 4/4] update linter --- .tflint.hcl | 16 ++++----------- main.tf | 35 +++++++++++++++++++++++++++++---- modules/azure-nsg-rules/main.tf | 5 ----- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/.tflint.hcl b/.tflint.hcl index 787bbc0..a7b6284 100644 --- a/.tflint.hcl +++ b/.tflint.hcl @@ -3,10 +3,10 @@ plugin "terraform" { preset = "recommended" } -plugin "aws" { +plugin "azurerm" { enabled = true version = "0.29.0" - source = "github.com/terraform-linters/tflint-ruleset-aws" + source = "github.com/terraform-linters/tflint-ruleset-azurerm" } rule "terraform_deprecated_interpolation" { @@ -46,16 +46,8 @@ rule "terraform_standard_module_structure" { enabled = true } -# AWS-specific rules -rule "aws_resource_missing_tags" { +# Azure-specific rules +rule "azurerm_resource_missing_tags" { enabled = true tags = ["Name", "Environment"] } - -rule "aws_instance_invalid_type" { - enabled = true -} - -rule "aws_security_group_rule_invalid_protocol" { - enabled = true -} diff --git a/main.tf b/main.tf index ee012f7..7fa13e2 100644 --- a/main.tf +++ b/main.tf @@ -18,6 +18,11 @@ locals { vnet_cidr = var.create_vnet ? tolist(azurerm_virtual_network.this[0].address_space)[0] : tolist(data.azurerm_virtual_network.this[0].address_space)[0] existing_vnet_name = var.create_vnet ? azurerm_virtual_network.this[0].name : local.vnet_name az_names = slice(["1", "2", "3"], 0, max(local.outside_subnets_len, local.local_subnets_len, local.inside_subnets_len)) + + common_tags = merge(var.tags, { + Name = local.vnet_name + Environment = lookup(var.tags, "Environment", "dev") + }) } resource "azurerm_resource_group" "this" { @@ -25,6 +30,12 @@ resource "azurerm_resource_group" "this" { name = local.resource_group_name location = var.location + + tags = local.common_tags + + lifecycle { + ignore_changes = [tags] + } } data "azurerm_virtual_network" "this" { @@ -43,7 +54,11 @@ resource "azurerm_virtual_network" "this" { location = var.location resource_group_name = local.resource_group_name - tags = var.tags + tags = local.common_tags + + lifecycle { + ignore_changes = [tags] + } depends_on = [ azurerm_resource_group.this @@ -96,7 +111,11 @@ resource "azurerm_network_security_group" "outside" { location = var.location resource_group_name = local.resource_group_name - tags = var.tags + tags = local.common_tags + + lifecycle { + ignore_changes = [tags] + } depends_on = [ azurerm_resource_group.this, @@ -127,7 +146,11 @@ resource "azurerm_network_security_group" "inside" { location = var.location resource_group_name = local.resource_group_name - tags = var.tags + tags = local.common_tags + + lifecycle { + ignore_changes = [tags] + } depends_on = [ azurerm_virtual_network.this @@ -163,7 +186,11 @@ resource "azurerm_route_table" "inside" { resource_group_name = local.resource_group_name bgp_route_propagation_enabled = var.bgp_route_propagation_enabled - tags = var.tags + tags = local.common_tags + + lifecycle { + ignore_changes = [tags] + } depends_on = [ azurerm_virtual_network.this diff --git a/modules/azure-nsg-rules/main.tf b/modules/azure-nsg-rules/main.tf index a2ff303..a7b7b93 100644 --- a/modules/azure-nsg-rules/main.tf +++ b/modules/azure-nsg-rules/main.tf @@ -1,8 +1,3 @@ -data "azurerm_network_security_group" "this" { - name = var.network_security_group_name - resource_group_name = var.resource_group_name -} - locals { americas_tcp_80_443_range = [ "5.182.215.0/25",