From 8dc7d94e659acefbe5c1ffa671a3184edcab69ae Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 15:35:00 -0600 Subject: [PATCH 01/22] Azure vnet flow logs support in tf module --- README.md | 11 +--- cloud_Azure/terraform/module/cloudexport.tf | 10 ++-- .../terraform/module/network_watcher.tf | 60 +++++++------------ cloud_Azure/terraform/module/output.tf | 9 +-- cloud_Azure/terraform/module/roles.tf | 8 +-- .../terraform/module/storage_account.tf | 22 +++++-- cloud_IBM/README.md | 1 - 7 files changed, 50 insertions(+), 71 deletions(-) delete mode 100644 cloud_IBM/README.md diff --git a/README.md b/README.md index ae70ec0..663eb05 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ #### Single VPC, Single Region * [single-vpc](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_AWS/terraform/module/examples/single-vpc) #### All VPC, Single Region -* [all-vpc-from-region](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_AWS/terraform/module/examples/all-vpc-from-region) +* [all-vpc-from-region](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_AWS/terraform/module/examples/all-vpc-from-region) #### Deploy Sock Shop as an example micro-service architecture * [sock-shop-eks](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_AWS/terraform/module/examples/sock-shop-eks) @@ -28,8 +28,6 @@ # Stage 2 - Automate GCP ## Terraform * [Terraform](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_GCP/terraform) -### Demo -* [Terraform Demo](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_GCP/terraform/module/demo) (TODO) ### Examples #### Subnet-list, Single region * [subnet-list](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_GCP/terraform/module/examples/subnet-list) @@ -38,14 +36,10 @@ ## Ansible * [Ansible](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_GCP/terraform) -### Demo -* [Ansible Demo](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_GCP/terraform/module/demo)(TODO) # Stage 3 - Automate Azure ## Terraform * [Tearraform](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_Azure/terraform) -### Demo -* [Terraform Demo](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_Azure/terraform/module/demo) (TODO) ### Examples #### Subnet-list, Single region * [all_nsg](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_Azure/terraform/module/examples/all_nsg) @@ -56,9 +50,6 @@ #### All NSG from resource group * [all_nsg](cloud_Azure/ansible/examples/all_nsg) -# Stage 4 - Automate IBM Cloud -## Timing TBD - # General needs for automation ## Identity and Access Management ## Creation of Storage location diff --git a/cloud_Azure/terraform/module/cloudexport.tf b/cloud_Azure/terraform/module/cloudexport.tf index c531284..8b8ef73 100644 --- a/cloud_Azure/terraform/module/cloudexport.tf +++ b/cloud_Azure/terraform/module/cloudexport.tf @@ -14,9 +14,9 @@ provider "kentik-cloudexport" { # Creates one Kentik CloudExport for every requested Resource Group resource "kentik-cloudexport_item" "azure_export" { - count = length(var.resource_group_names) + for_each = { for rg in var.resource_group_names : rg => rg } - name = "${var.name}-${var.resource_group_names[count.index]}-${var.subscription_id}" # resource group name + subscription id make the name unique + name = "${var.name}-${each.key}-${var.subscription_id}" # resource group name + subscription id make the name unique type = "CLOUD_EXPORT_TYPE_KENTIK_MANAGED" enabled = var.enabled description = var.description @@ -25,8 +25,8 @@ resource "kentik-cloudexport_item" "azure_export" { azure { subscription_id = var.subscription_id location = var.location - resource_group = var.resource_group_names[count.index] - storage_account = azurerm_storage_account.logs_storage_account[count.index].name # storage accounts are mapped to resource groups 1:1 + resource_group = each.key + storage_account = azurerm_storage_account.logs_storage_account[each.key].name # storage accounts are mapped to resource groups 1:1 security_principal_enabled = true } -} \ No newline at end of file +} diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index b2dbca0..a205490 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -5,55 +5,39 @@ data "azurerm_network_watcher" "network_watcher" { resource_group_name = "NetworkWatcherRG" } -# Runs python script to gather network security groups from each requested resource group -# This is required because no Terraform provider exposes such functionality -# Resulting "data.external.nsg_data_source.results" is a map of string -> string, eg. -# { -# "ResourceGroupName1" -> "NetworkSercurityGroupId1,NetworkSecurityGroupId2", -# "ResourceGroupName2" -> "NetworkSercurityGroupId3,NetworkSecurityGroupId4" -# } -data "external" "nsg_data_source" { - program = ["python3", "${path.module}/get_nsg.py"] - query = { - resource_group_names = join(",", var.resource_group_names) - } +# Fetch all VNets for each resource group +data "azurerm_resources" "vnet" { + for_each = toset(var.resource_group_names) + type = "Microsoft.Network/virtualNetworks" + resource_group_name = each.key } -# Convert map of string -> string: -# { -# "ResourceGroupName1" -> "NetworkSercurityGroupId1,NetworkSecurityGroupId2", -# "ResourceGroupName2" -> "NetworkSercurityGroupId3,NetworkSecurityGroupId4" -# } -# to list of objects: -# [ -# {rg = "ResourceGroupName1", nsg = "NetworkSercurityGroupId1"}, -# {rg = "ResourceGroupName1", nsg = "NetworkSercurityGroupId2"}, -# {rg = "ResourceGroupName2", nsg = "NetworkSercurityGroupId3"}, -# {rg = "ResourceGroupName2", nsg = "NetworkSercurityGroupId4"} -# ] +# Map resource group names to their corresponding VNets +# Flatten map to list of objects locals { - flat_nsgs = flatten([ - for rg, nsg_list in data.external.nsg_data_source.result : [ - for nsg in split(",", nsg_list) : { - rg = rg # Resource Group name - nsg = nsg # Network Security Group ID + flat_vnets = flatten([ + for rg in var.resource_group_names : [ + for vnet in data.azurerm_resources.vnet[rg].resources : { + rg = rg + vnet = vnet.name + id = vnet.id } - ] if length(nsg_list) > 0 # filter out Resource Groups that have no Network Security Groups + ] ]) } -# Turns on flow logs for all network security groups in requested resource groups +# Turns on vnet flow logs for all vnets in requested resource groups resource "azurerm_network_watcher_flow_log" "kentik_network_flow_log" { - count = length(local.flat_nsgs) + for_each = { for vnet in local.flat_vnets : vnet.name => vnet } - name = "${var.name}_flow_log_${count.index}" + name = format("${var.name}-flowLogs-%s", each.key) network_watcher_name = data.azurerm_network_watcher.network_watcher.name - resource_group_name = data.azurerm_network_watcher.network_watcher.resource_group_name + resource_group_name = each.value.rg - network_security_group_id = local.flat_nsgs[count.index].nsg - storage_account_id = azurerm_storage_account.logs_storage_account[index(var.resource_group_names, local.flat_nsgs[count.index].rg)].id - enabled = true - version = 2 + target_resource_id = each.value.id + storage_account_id = azurerm_storage_account.logs_storage_account[each.value.rg].id + enabled = true + version = 2 retention_policy { enabled = true days = 7 diff --git a/cloud_Azure/terraform/module/output.tf b/cloud_Azure/terraform/module/output.tf index 743b480..fee51be 100644 --- a/cloud_Azure/terraform/module/output.tf +++ b/cloud_Azure/terraform/module/output.tf @@ -1,8 +1,3 @@ -output "network_security_groups" { - value = [for v in local.flat_nsgs : v.nsg] - description = "Id's of the Network Security Groups which flow logs will be collected" -} - output "subscription_id" { value = var.subscription_id description = "Azure subscription ID" @@ -14,11 +9,11 @@ output "resource_group_names" { } output "storage_accounts" { - value = azurerm_storage_account.logs_storage_account[*].name + value = [for sa in azurerm_storage_account.logs_storage_account : sa.name] description = "Storage Account names where flow logs will be collected" } output "principal_id" { value = local.kentik_nsg_flow_exporter_id description = "Service Principal ID created for Kentik NSG Flow Exporter application" -} \ No newline at end of file +} diff --git a/cloud_Azure/terraform/module/roles.tf b/cloud_Azure/terraform/module/roles.tf index 79b018d..83606a7 100644 --- a/cloud_Azure/terraform/module/roles.tf +++ b/cloud_Azure/terraform/module/roles.tf @@ -1,17 +1,17 @@ # Provide service principal Contributor role to each storage account resource "azurerm_role_assignment" "kentic_role_contributor" { - count = length(azurerm_storage_account.logs_storage_account) + for_each = azurerm_storage_account.logs_storage_account - scope = azurerm_storage_account.logs_storage_account[count.index].id + scope = each.value.id role_definition_name = "Contributor" principal_id = local.kentik_nsg_flow_exporter_id } # Provide service principal Reader role to each Resource Group resource "azurerm_role_assignment" "kentic_role_reader" { - count = length(var.resource_group_names) + for_each = toset(var.resource_group_names) - scope = "/subscriptions/${var.subscription_id}/resourceGroups/${var.resource_group_names[count.index]}" + scope = "/subscriptions/${var.subscription_id}/resourceGroups/${each.value}" role_definition_name = "Reader" principal_id = local.kentik_nsg_flow_exporter_id } diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index 1b57d24..d7b7761 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -7,14 +7,24 @@ locals { generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] } +locals { + # Create a map of resource group names to storage account names + resource_group_to_storage_account = { + for rg in var.resource_group_names : rg => ( + length(var.storage_account_names) == length(var.resource_group_names) ? + var.storage_account_names[index(var.resource_group_names, rg)] : + local.generated_storage_account_names[index(var.resource_group_names, rg)] + ) + } +} + # Creates one storage account per resource group to store flow logs -# StorageAccounts are mapped 1:1 to resource_group_names and this fact is used to get storage account id for given resource group name +# StorageAccounts are mapped 1:1 to resource_group_names and this fact is used to get storage account id for given resource group name resource "azurerm_storage_account" "logs_storage_account" { - count = length(var.resource_group_names) + for_each = local.resource_group_to_storage_account - # use either custom name if one is provided, or generated one - name = length(var.storage_account_names) == length(var.resource_group_names) ? var.storage_account_names[count.index] : local.generated_storage_account_names[count.index] - resource_group_name = var.resource_group_names[count.index] + name = each.value + resource_group_name = each.key location = var.location account_tier = "Standard" account_replication_type = "GRS" @@ -22,4 +32,4 @@ resource "azurerm_storage_account" "logs_storage_account" { tags = { app = var.resource_tag } -} \ No newline at end of file +} diff --git a/cloud_IBM/README.md b/cloud_IBM/README.md deleted file mode 100644 index 55f985c..0000000 --- a/cloud_IBM/README.md +++ /dev/null @@ -1 +0,0 @@ -place holder From 27ed2026609f14ea4816190db90a9a39cfbe363b Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 15:37:52 -0600 Subject: [PATCH 02/22] filter rg's without any vnets --- cloud_Azure/terraform/module/network_watcher.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index a205490..fa927a1 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -22,7 +22,7 @@ locals { vnet = vnet.name id = vnet.id } - ] + ] if length(data.azurerm_resources.vnet[rg].resources) > 0 # filter out resource groups without VNets ]) } From 9ed130bdaa97edf71a6050ded2887cf3603b3560 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 16:04:01 -0600 Subject: [PATCH 03/22] access vnet values --- cloud_Azure/terraform/module/network_watcher.tf | 9 ++++++--- cloud_Azure/terraform/module/roles.tf | 4 ++-- cloud_Azure/terraform/module/variables.tf | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index fa927a1..3f9368a 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -18,9 +18,12 @@ locals { flat_vnets = flatten([ for rg in var.resource_group_names : [ for vnet in data.azurerm_resources.vnet[rg].resources : { - rg = rg - vnet = vnet.name - id = vnet.id + key = "${rg}-${vnet.name}" + value = { + rg = rg + vnet = vnet.name + id = vnet.id + } } ] if length(data.azurerm_resources.vnet[rg].resources) > 0 # filter out resource groups without VNets ]) diff --git a/cloud_Azure/terraform/module/roles.tf b/cloud_Azure/terraform/module/roles.tf index 83606a7..c83d57b 100644 --- a/cloud_Azure/terraform/module/roles.tf +++ b/cloud_Azure/terraform/module/roles.tf @@ -1,5 +1,5 @@ # Provide service principal Contributor role to each storage account -resource "azurerm_role_assignment" "kentic_role_contributor" { +resource "azurerm_role_assignment" "kentik_role_contributor" { for_each = azurerm_storage_account.logs_storage_account scope = each.value.id @@ -8,7 +8,7 @@ resource "azurerm_role_assignment" "kentic_role_contributor" { } # Provide service principal Reader role to each Resource Group -resource "azurerm_role_assignment" "kentic_role_reader" { +resource "azurerm_role_assignment" "kentik_role_reader" { for_each = toset(var.resource_group_names) scope = "/subscriptions/${var.subscription_id}/resourceGroups/${each.value}" diff --git a/cloud_Azure/terraform/module/variables.tf b/cloud_Azure/terraform/module/variables.tf index 8a589ef..ed4e285 100644 --- a/cloud_Azure/terraform/module/variables.tf +++ b/cloud_Azure/terraform/module/variables.tf @@ -1,4 +1,4 @@ -# provideres: azurerm & azuread +# providers: azurerm & azuread variable "subscription_id" { type = string description = "Azure subscription ID" @@ -63,4 +63,4 @@ variable "flow_exporter_application_id" { type = string default = "a20ce222-63c0-46db-86d5-58551eeee89f" description = "Kentik NSG Flow Exporter application ID" -} \ No newline at end of file +} From eb827c8d4164b491bcbe7b900c3ac58c6f0a678e Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 16:08:08 -0600 Subject: [PATCH 04/22] fix rg name, key values --- cloud_Azure/terraform/module/network_watcher.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index 3f9368a..9d107db 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -31,11 +31,11 @@ locals { # Turns on vnet flow logs for all vnets in requested resource groups resource "azurerm_network_watcher_flow_log" "kentik_network_flow_log" { - for_each = { for vnet in local.flat_vnets : vnet.name => vnet } + for_each = { for vnet in local.flat_vnets : vnet.key => vnet.value } - name = format("${var.name}-flowLogs-%s", each.key) + name = "${var.name}_flow_log_${each.value.name}" network_watcher_name = data.azurerm_network_watcher.network_watcher.name - resource_group_name = each.value.rg + resource_group_name = "NetworkWatcherRG" target_resource_id = each.value.id storage_account_id = azurerm_storage_account.logs_storage_account[each.value.rg].id From 25c5ff50e25221973c35913a3ce3a5dfe9d79d97 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 16:10:38 -0600 Subject: [PATCH 05/22] fix rg name, key values --- cloud_Azure/terraform/module/network_watcher.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index 9d107db..505c0e0 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -21,7 +21,7 @@ locals { key = "${rg}-${vnet.name}" value = { rg = rg - vnet = vnet.name + name = vnet.name id = vnet.id } } From 3a4794872a255cb05808cd1e55e933f6bea171ba Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 16:12:19 -0600 Subject: [PATCH 06/22] name --- cloud_Azure/terraform/module/network_watcher.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index 505c0e0..c75674e 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -33,7 +33,7 @@ locals { resource "azurerm_network_watcher_flow_log" "kentik_network_flow_log" { for_each = { for vnet in local.flat_vnets : vnet.key => vnet.value } - name = "${var.name}_flow_log_${each.value.name}" + name = "${var.name}-flowLog-${each.value.name}" network_watcher_name = data.azurerm_network_watcher.network_watcher.name resource_group_name = "NetworkWatcherRG" From ba6245f84a16d177f055a45df3ecf6d57c222223 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Tue, 14 Jan 2025 16:22:28 -0600 Subject: [PATCH 07/22] update provider versions in ci tests --- cloud_Azure/terraform/module/tests/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cloud_Azure/terraform/module/tests/main.tf b/cloud_Azure/terraform/module/tests/main.tf index 6737976..f8e4bd4 100644 --- a/cloud_Azure/terraform/module/tests/main.tf +++ b/cloud_Azure/terraform/module/tests/main.tf @@ -3,11 +3,11 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "~> 3.10" + version = "~> 4.15" } azuread = { source = "hashicorp/azuread" - version = "~> 2.24" + version = "~> 3.0" } kentik-cloudexport = { source = "kentik/kentik-cloudexport" From 906dcbeea7c63fddccf50065de9779746e18715c Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 15 Jan 2025 10:15:10 -0600 Subject: [PATCH 08/22] update docs, replace nsg w/ vnet --- cloud_Azure/terraform/module/README.md | 33 +++++------------------ cloud_Azure/terraform/module/variables.tf | 2 +- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index 9b12a38..30e7a84 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -3,18 +3,18 @@ Module supporting management of Azure and Kentik resources required for flow log export from Azure to Kentik. Module enables: -* Flow logs in all Network Security Groups (NSG) found in requested Resource Groups +* Flow logs in all Virtual Networks (VNets) found in requested Resource Groups Module creates: -* Service Principal for Kentik NSG Flow Exporter application +* Service Principal for Kentik VNet Flow Exporter application * Reader and Contributor Roles for above mentioned Service Principal * One Storage Account for flow logs per requested Resource Group * Registers flow in Kentik platform per requested Resource Group All resources created in Azure are tagged, see variable "resource_tag" in [variables.tf](./variables.tf) -Module assumes that NetworkWatcher resource exists in NetworkWatcherRG resource group in specified Azure location (see variable "location" in [variables.tf](./variables.tf)). -For example, in location "eastus" there should be "NetworkWatcher_eastus" in "NetworkWatcherRG" resource group. +Module assumes that NetworkWatcher resource exists in NetworkWatcherRG resource group in specified Azure location (see variable "location" in [variables.tf](./variables.tf)). +For example, in location "eastus" there should be "NetworkWatcher_eastus" in "NetworkWatcherRG" resource group. NetworkWatcher is automatically created by Azure when VirtualNetwork is created or updated, [as per documentation.](https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-create). This happens eg. when launching a new virtual machine. ## Usage examples @@ -40,27 +40,6 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created | null | >= 2.1.2 | | external | >= 2.0.0 | -## Python and dependencies - -This module uses Python script to list all Network Security Groups in specified Resource Groups and exposes the list to Terraform as external data source. -To install Python and required packages: -* [Install Python and PIP](https://docs.python.org/3/using/index.html) -* Install packages - in module directory, execute: - PowerShell: - ```powershell - pip install virtualenv - virtualenv venv - .\venv\Scripts\activate - pip install -r requirements.txt - ``` - - or Bash: - ```bash - pip install virtualenv - virtualenv venv - source venv/bin/activate - pip install -r requirements.txt - ``` ## Inputs | Name | Description | Type | Default | Required | @@ -75,7 +54,7 @@ To install Python and required packages: | enabled | Defines if cloud export to Kentik is enabled | `bool` | true | no | | description | Cloudexport entry description in Kentik | `string` | `Created using Terraform` | no | | resource_tag | Azure Tag value to apply to created resources | `string` | `flow_log_exporter` | no | -| flow_exporter_application_id | Kentik NSG Flow Exporter application ID | `string` | `a20ce222-63c0-46db-86d5-58551eeee89f` | no | +| flow_exporter_application_id | Kentik VNet Flow Exporter application ID | `string` | `a20ce222-63c0-46db-86d5-58551eeee89f` | no | | storage_account_names | Names of Storage Accounts for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. | `list of strings` | `[]` | no | @@ -87,4 +66,4 @@ To install Python and required packages: | subscription_id | Azure subscription ID | | resource_group_names | Names of Resource Groups from which to collect flow logs | | storage_accounts | Storage Account names where flow logs will be collected | -| principal_id | Service Principal ID created for Kentik NSG Flow Exporter application | +| principal_id | Service Principal ID created for Kentik VNet Flow Exporter application | diff --git a/cloud_Azure/terraform/module/variables.tf b/cloud_Azure/terraform/module/variables.tf index ed4e285..2988dcb 100644 --- a/cloud_Azure/terraform/module/variables.tf +++ b/cloud_Azure/terraform/module/variables.tf @@ -62,5 +62,5 @@ variable "enabled" { variable "flow_exporter_application_id" { type = string default = "a20ce222-63c0-46db-86d5-58551eeee89f" - description = "Kentik NSG Flow Exporter application ID" + description = "Kentik VNet Flow Exporter application ID" } From 7867dc0e6679d0ec9003fd455c84abbdf3c6f20d Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 15 Jan 2025 10:37:24 -0600 Subject: [PATCH 09/22] vnet id outputs --- cloud_Azure/terraform/module/README.md | 2 +- cloud_Azure/terraform/module/output.tf | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index 30e7a84..7c7e4cc 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -62,7 +62,7 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created | Name | Description | |------|-------------| -| network_security_groups | Id's of the Network Security Groups which flow logs will be collected | +| network_security_groups | Id's of the Virtual Networks which to collect flow logs | | subscription_id | Azure subscription ID | | resource_group_names | Names of Resource Groups from which to collect flow logs | | storage_accounts | Storage Account names where flow logs will be collected | diff --git a/cloud_Azure/terraform/module/output.tf b/cloud_Azure/terraform/module/output.tf index fee51be..6e7ee7a 100644 --- a/cloud_Azure/terraform/module/output.tf +++ b/cloud_Azure/terraform/module/output.tf @@ -1,3 +1,8 @@ +output "vnet_ids" { + value = [for vnet in local.flat_vnets : vnet.value.id] + description = "Id's of the Virtual Networks from which to collect flow logs" +} + output "subscription_id" { value = var.subscription_id description = "Azure subscription ID" From 06d082bc22b4e8f7f35b03b3c37e5585d18e88c6 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 15 Jan 2025 13:19:55 -0600 Subject: [PATCH 10/22] remove local-exec provisioner null resources --- cloud_Azure/terraform/module/providers.tf | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 cloud_Azure/terraform/module/providers.tf diff --git a/cloud_Azure/terraform/module/providers.tf b/cloud_Azure/terraform/module/providers.tf deleted file mode 100644 index 1cc54b2..0000000 --- a/cloud_Azure/terraform/module/providers.tf +++ /dev/null @@ -1,17 +0,0 @@ -# Enable network watcher feature -resource "null_resource" "feature_allow_watcher" { - provisioner "local-exec" { - command = "az feature register --namespace Microsoft.Network --name AllowNetworkWatcher" - } - - provisioner "local-exec" { - command = "az provider register -n Microsoft.Network" - } -} - -# Enable Microsoft Insights -resource "null_resource" "feature_insights_register" { - provisioner "local-exec" { - command = "az provider register -n Microsoft.Insights" - } -} From a9937eb499a3a3d82b28d3019bedb37272d1596c Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 15 Jan 2025 13:33:23 -0600 Subject: [PATCH 11/22] retire get_nsg.py and remove unused requirements --- cloud_Azure/terraform/module/README.md | 2 +- .../README.md | 4 +-- .../main.tf | 4 +-- .../output.tf | 8 ++--- cloud_Azure/terraform/module/get_nsg.py | 34 ------------------- cloud_Azure/terraform/module/requirements.txt | 3 -- 6 files changed, 8 insertions(+), 47 deletions(-) delete mode 100755 cloud_Azure/terraform/module/get_nsg.py delete mode 100644 cloud_Azure/terraform/module/requirements.txt diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index 7c7e4cc..b90146e 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -62,7 +62,7 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created | Name | Description | |------|-------------| -| network_security_groups | Id's of the Virtual Networks which to collect flow logs | +| vnet_ids | Id's of the Virtual Networks which to collect flow logs | | subscription_id | Azure subscription ID | | resource_group_names | Names of Resource Groups from which to collect flow logs | | storage_accounts | Storage Account names where flow logs will be collected | diff --git a/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/README.md b/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/README.md index d724701..9113486 100644 --- a/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/README.md +++ b/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/README.md @@ -15,7 +15,7 @@ None. location = "eastus" resource_group_names = ["resource-group-1", "resource-group-2", "resource-group-3"] # groups must exist in selected location storage_account_names = [] - + # Kentik email = "dummy@test.mail" token = "dummy_token" @@ -29,8 +29,6 @@ None. 1. Execute: ```bash - virtualenv venv && source venv/bin/activate - pip install -r ../../requirements.txt terraform init ``` diff --git a/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/main.tf b/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/main.tf index c96cc1b..725f162 100644 --- a/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/main.tf +++ b/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/main.tf @@ -3,11 +3,11 @@ terraform { required_providers { azurerm = { source = "hashicorp/azurerm" - version = "~> 3.10" + version = "~> 4.15" } azuread = { source = "hashicorp/azuread" - version = "~> 2.24" + version = "~> 3.0" } kentik-cloudexport = { source = "kentik/kentik-cloudexport" diff --git a/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/output.tf b/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/output.tf index 69348b1..665f42b 100644 --- a/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/output.tf +++ b/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups/output.tf @@ -1,7 +1,7 @@ -output "network_security_groups" { - value = module.kentik_azure_integration.network_security_groups - description = "Id's of the Network Security Groups which flow logs will be collected" +output "vnet_ids" { + value = module.kentik_azure_integration.vnet_ids + description = "Id's of the Virtual Networks from which to collect flow logs" } output "subscription_id" { @@ -22,4 +22,4 @@ output "storage_accounts" { output "principal_id" { value = module.kentik_azure_integration.principal_id description = "Service Principal ID created for Kentik NSG Flow Exporter application" -} \ No newline at end of file +} diff --git a/cloud_Azure/terraform/module/get_nsg.py b/cloud_Azure/terraform/module/get_nsg.py deleted file mode 100755 index 4b31455..0000000 --- a/cloud_Azure/terraform/module/get_nsg.py +++ /dev/null @@ -1,34 +0,0 @@ -import sys -from typing import Dict, List - -from az.cli import az -from terraform_external_data import terraform_external_data - - -@terraform_external_data -def get_nsg_from_rg(query: Dict[str, str]) -> Dict[str, str]: - """ - Gather all Network Security Groups for each requested Resource Group - """ - - if query["resource_group_names"] == "": - return {} - - resource_group_names: List[str] = query["resource_group_names"].split(",") - result: Dict[str, str] = {} - - for rg in resource_group_names: - exit_code, result_dict, logs = az(f"network nsg list --resource-group {rg} --query '[].id' -o json") - if exit_code == 0: - network_security_group_ids = str(result_dict).strip("[]").replace("'", "").replace(" ", "") - result[rg] = network_security_group_ids - else: - # Terraform-Python communication protocol: on error, print message to stderr and exit with non-zero code - print(logs, file=sys.stderr) - exit(1) - - return result # result is consumed by function decorator - - -if __name__ == "__main__": - get_nsg_from_rg() # pylint: disable=no-value-for-parameter diff --git a/cloud_Azure/terraform/module/requirements.txt b/cloud_Azure/terraform/module/requirements.txt deleted file mode 100644 index a547788..0000000 --- a/cloud_Azure/terraform/module/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -az.cli>=0.4 -virtualenv>=20.4.0 -terraform-external-data>=1.0.3 \ No newline at end of file From 181ea2179b89070476fcdcf4e0fcd9cc5c1a1822 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 15 Jan 2025 15:49:04 -0600 Subject: [PATCH 12/22] cleanup service_principal creation --- README.md | 4 ++-- cloud_Azure/terraform/module/README.md | 2 +- cloud_Azure/terraform/module/output.tf | 4 ++-- cloud_Azure/terraform/module/roles.tf | 4 ++-- .../terraform/module/service_principal.tf | 18 +++++++++--------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 663eb05..fbd185e 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ ## Terraform * [Tearraform](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_Azure/terraform) ### Examples -#### Subnet-list, Single region -* [all_nsg](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_Azure/terraform/module/examples/all_nsg) +#### All Virtual Networks from multiple Resource Groups +* [single_account_multiple_resource_groups](https://github.com/kentik/config-snippets-cloud/tree/master/cloud_Azure/terraform/module/examples/single_account_multiple_resource_groups) ## Ansible * [Ansible](cloud_Azure/ansible/roles/kentik_az) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index b90146e..fbdf7eb 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -19,7 +19,7 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created ## Usage examples -* [All Network Security Groups in requested Resource Groups in single Azure Account](examples/single_account_multiple_resource_groups) +* [All Virtual Networks in requested Resource Groups in single Azure Account](examples/single_account_multiple_resource_groups) * [All Network Security Groups in requested Resource Groups in multiple Azure Accounts](examples/multiple_accounts_multiple_resource_group) ## Requirements diff --git a/cloud_Azure/terraform/module/output.tf b/cloud_Azure/terraform/module/output.tf index 6e7ee7a..70053e9 100644 --- a/cloud_Azure/terraform/module/output.tf +++ b/cloud_Azure/terraform/module/output.tf @@ -19,6 +19,6 @@ output "storage_accounts" { } output "principal_id" { - value = local.kentik_nsg_flow_exporter_id - description = "Service Principal ID created for Kentik NSG Flow Exporter application" + value = local.kentik_vnet_flow_exporter_id + description = "Service Principal ID created for Kentik VNet Flow Exporter application" } diff --git a/cloud_Azure/terraform/module/roles.tf b/cloud_Azure/terraform/module/roles.tf index c83d57b..73b5e2b 100644 --- a/cloud_Azure/terraform/module/roles.tf +++ b/cloud_Azure/terraform/module/roles.tf @@ -4,7 +4,7 @@ resource "azurerm_role_assignment" "kentik_role_contributor" { scope = each.value.id role_definition_name = "Contributor" - principal_id = local.kentik_nsg_flow_exporter_id + principal_id = local.kentik_vnet_flow_exporter_id } # Provide service principal Reader role to each Resource Group @@ -13,5 +13,5 @@ resource "azurerm_role_assignment" "kentik_role_reader" { scope = "/subscriptions/${var.subscription_id}/resourceGroups/${each.value}" role_definition_name = "Reader" - principal_id = local.kentik_nsg_flow_exporter_id + principal_id = local.kentik_vnet_flow_exporter_id } diff --git a/cloud_Azure/terraform/module/service_principal.tf b/cloud_Azure/terraform/module/service_principal.tf index d625e84..f5e0bc7 100644 --- a/cloud_Azure/terraform/module/service_principal.tf +++ b/cloud_Azure/terraform/module/service_principal.tf @@ -1,20 +1,20 @@ data "azuread_client_config" "current" {} -data "azuread_service_principals" "existing_nsg_flow_exporter" { - client_ids = [var.flow_exporter_application_id] +data "azuread_service_principals" "existing_vnet_flow_exporter" { + client_ids = [var.flow_exporter_application_id] ignore_missing = true } locals { - nsg_flow_exporter_already_exists = length(data.azuread_service_principals.existing_nsg_flow_exporter.object_ids) == 1 ? true : false + vnet_flow_exporter_already_exists = length(data.azuread_service_principals.existing_vnet_flow_exporter.object_ids) == 1 } -# Creates Service Principal for pre-existing "Kentik NSG Flow Exporter" app, so the app can access flow logs in Azure cloud +# Creates Service Principal for pre-existing "Kentik VNet Flow Exporter" app, so the app can access flow logs in Azure cloud # This resource is shared across Azure Account, so only create it if doesn't exist yet -resource "azuread_service_principal" "new_nsg_flow_exporter" { - count = local.nsg_flow_exporter_already_exists ? 0 : 1 +resource "azuread_service_principal" "new_vnet_flow_exporter" { + count = local.vnet_flow_exporter_already_exists ? 0 : 1 - client_id = var.flow_exporter_application_id + client_id = var.flow_exporter_application_id app_role_assignment_required = false owners = [data.azuread_client_config.current.object_id] @@ -24,5 +24,5 @@ resource "azuread_service_principal" "new_nsg_flow_exporter" { } locals { - kentik_nsg_flow_exporter_id = local.nsg_flow_exporter_already_exists ? data.azuread_service_principals.existing_nsg_flow_exporter.object_ids[0] : azuread_service_principal.new_nsg_flow_exporter[0].object_id -} \ No newline at end of file + kentik_vnet_flow_exporter_id = local.vnet_flow_exporter_already_exists ? data.azuread_service_principals.existing_vnet_flow_exporter.object_ids[0] : azuread_service_principal.new_vnet_flow_exporter[0].object_id +} From cc476e9626d6fdd9105b109449b09984ce42a470 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:09:50 -0600 Subject: [PATCH 13/22] modify azure sa name generation --- cloud_Azure/terraform/module/README.md | 4 ++-- cloud_Azure/terraform/module/storage_account.tf | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index fbdf7eb..2fb0d8d 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -50,12 +50,12 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created | email | Kentik account email | `string` | none | yes | | token | Kentik account token | `string` | none | yes | | plan_id | Kentik billing plan ID | `string` | none | yes | -| name | Cloudexport entry name in Kentik | `string` | none | yes | +| name | Cloudexport entry name in Kentik will be appended with: resource_group_names and subscription_id to ensure uniqueness | `string` | none | yes | | enabled | Defines if cloud export to Kentik is enabled | `bool` | true | no | | description | Cloudexport entry description in Kentik | `string` | `Created using Terraform` | no | | resource_tag | Azure Tag value to apply to created resources | `string` | `flow_log_exporter` | no | | flow_exporter_application_id | Kentik VNet Flow Exporter application ID | `string` | `a20ce222-63c0-46db-86d5-58551eeee89f` | no | -| storage_account_names | Names of Storage Accounts for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. | `list of strings` | `[]` | no | +| storage_account_names | Names of Storage Accounts to be created for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. | `list of strings` | `[]` | no | ## Outputs diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index d7b7761..dd37ff4 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -1,14 +1,19 @@ # Prepare names that meet Azure Storage Account naming restrictions (only alphanum letters, max 24 length, Azure-wide unique) -# Each output name is concatenation of Resource Group name and Subscription ID, adjusted to naming restrictions +resource "random_id" "storage_account_id" { + byte_length = 6 # 6 bytes = 12 characters when base64 encoded +} + +# Each output name is concatenation of the exporter name and a random id, adjusted to naming restrictions locals { - _names = [for name in var.resource_group_names : "${name}${var.subscription_id}"] + truncated_name = substr(var.name, 0, 12) + _names = [for name in var.resource_group_names : "${truncated_name}${random_id.storage_account_id.hex}"] _lowercase_names = [for name in local._names : lower(name)] _alphanum_lowercase_names = [for name in local._lowercase_names : join("", regexall("[[:alnum:]]+", name))] generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] } +# Create a map of resource group names to storage account names locals { - # Create a map of resource group names to storage account names resource_group_to_storage_account = { for rg in var.resource_group_names : rg => ( length(var.storage_account_names) == length(var.resource_group_names) ? From 751c259a6a39b3943034c8892738cec8d676901e Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:12:09 -0600 Subject: [PATCH 14/22] fix sa name --- cloud_Azure/terraform/module/storage_account.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index dd37ff4..0d8ec9a 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -6,7 +6,7 @@ resource "random_id" "storage_account_id" { # Each output name is concatenation of the exporter name and a random id, adjusted to naming restrictions locals { truncated_name = substr(var.name, 0, 12) - _names = [for name in var.resource_group_names : "${truncated_name}${random_id.storage_account_id.hex}"] + _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id.hex}"] _lowercase_names = [for name in local._names : lower(name)] _alphanum_lowercase_names = [for name in local._lowercase_names : join("", regexall("[[:alnum:]]+", name))] generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] From 0426cffcacd6f6ccee7884233a55fe12dc585347 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:24:23 -0600 Subject: [PATCH 15/22] index sa's for uniqueness --- cloud_Azure/terraform/module/storage_account.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index 0d8ec9a..0331b3c 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -3,10 +3,10 @@ resource "random_id" "storage_account_id" { byte_length = 6 # 6 bytes = 12 characters when base64 encoded } -# Each output name is concatenation of the exporter name and a random id, adjusted to naming restrictions +# Each output name is concatenation of the exporter name truncated to 12 chars and a random id of 12 chars, adjusted to naming restrictions locals { truncated_name = substr(var.name, 0, 12) - _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id.hex}"] + _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id[idx].hex}"] _lowercase_names = [for name in local._names : lower(name)] _alphanum_lowercase_names = [for name in local._lowercase_names : join("", regexall("[[:alnum:]]+", name))] generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] @@ -15,10 +15,10 @@ locals { # Create a map of resource group names to storage account names locals { resource_group_to_storage_account = { - for rg in var.resource_group_names : rg => ( + for idx, rg in var.resource_group_names : rg => ( length(var.storage_account_names) == length(var.resource_group_names) ? - var.storage_account_names[index(var.resource_group_names, rg)] : - local.generated_storage_account_names[index(var.resource_group_names, rg)] + var.storage_account_names[idx] : + local.generated_storage_account_names[idx] ) } } From d39f1822b3b542a7120562f6d8d1d0005cfa24fd Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:25:45 -0600 Subject: [PATCH 16/22] fix --- cloud_Azure/terraform/module/storage_account.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index 0331b3c..b6857ca 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -6,7 +6,7 @@ resource "random_id" "storage_account_id" { # Each output name is concatenation of the exporter name truncated to 12 chars and a random id of 12 chars, adjusted to naming restrictions locals { truncated_name = substr(var.name, 0, 12) - _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id[idx].hex}"] + _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id.hex}"] _lowercase_names = [for name in local._names : lower(name)] _alphanum_lowercase_names = [for name in local._lowercase_names : join("", regexall("[[:alnum:]]+", name))] generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] From 9b1ecee2f8c069eea9df38646e32ee4923add7f5 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:32:54 -0600 Subject: [PATCH 17/22] count with random_id on rg list' --- cloud_Azure/terraform/module/storage_account.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index b6857ca..fabeedd 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -1,5 +1,6 @@ # Prepare names that meet Azure Storage Account naming restrictions (only alphanum letters, max 24 length, Azure-wide unique) resource "random_id" "storage_account_id" { + count = length(var.resource_group_names) byte_length = 6 # 6 bytes = 12 characters when base64 encoded } From e65e42c3dfb469af944945c6b2261c2b6f4ae076 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:34:41 -0600 Subject: [PATCH 18/22] add count index to local._names --- cloud_Azure/terraform/module/storage_account.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index fabeedd..e1cb2a6 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -7,7 +7,7 @@ resource "random_id" "storage_account_id" { # Each output name is concatenation of the exporter name truncated to 12 chars and a random id of 12 chars, adjusted to naming restrictions locals { truncated_name = substr(var.name, 0, 12) - _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id.hex}"] + _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id[count.index].hex}"] _lowercase_names = [for name in local._names : lower(name)] _alphanum_lowercase_names = [for name in local._lowercase_names : join("", regexall("[[:alnum:]]+", name))] generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] From fc71171d375d0945a564f9b409117b01337dcfc2 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:36:50 -0600 Subject: [PATCH 19/22] more index --- cloud_Azure/terraform/module/storage_account.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index e1cb2a6..0552652 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -7,7 +7,7 @@ resource "random_id" "storage_account_id" { # Each output name is concatenation of the exporter name truncated to 12 chars and a random id of 12 chars, adjusted to naming restrictions locals { truncated_name = substr(var.name, 0, 12) - _names = [for name in var.resource_group_names : "${local.truncated_name}${random_id.storage_account_id[count.index].hex}"] + _names = [for idx in range(length(var.resource_group_names)) : "${local.truncated_name}${random_id.storage_account_id[idx].hex}"] _lowercase_names = [for name in local._names : lower(name)] _alphanum_lowercase_names = [for name in local._lowercase_names : join("", regexall("[[:alnum:]]+", name))] generated_storage_account_names = [for name in local._alphanum_lowercase_names : substr(name, 0, 24)] From b2c25f244262d0a1331053d56ae8b03740f0b446 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Mon, 20 Jan 2025 15:54:28 -0600 Subject: [PATCH 20/22] comment --- cloud_Azure/terraform/module/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index 2fb0d8d..3b280ad 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -55,7 +55,7 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created | description | Cloudexport entry description in Kentik | `string` | `Created using Terraform` | no | | resource_tag | Azure Tag value to apply to created resources | `string` | `flow_log_exporter` | no | | flow_exporter_application_id | Kentik VNet Flow Exporter application ID | `string` | `a20ce222-63c0-46db-86d5-58551eeee89f` | no | -| storage_account_names | Names of Storage Accounts to be created for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. | `list of strings` | `[]` | no | +| storage_account_names | Names of Storage Accounts to be created for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. Auto-generated names will use the first 12 characters of the var.name for the Cloudexport appended with a random id of 12 characters for uniqueness. | `list of strings` | `[]` | no | ## Outputs From cddadd25398c645a57d4e21e98132f09a502c3b5 Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 22 Jan 2025 09:22:12 -0600 Subject: [PATCH 21/22] add bd team as codeowners --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..8d7a895 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @kentik/bd From 5c1db3b16bf64dde4998b7378f8d549e9156da7d Mon Sep 17 00:00:00 2001 From: jksprattler Date: Wed, 22 Jan 2025 09:28:03 -0600 Subject: [PATCH 22/22] comment --- cloud_Azure/terraform/module/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index 3b280ad..dc9b7de 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -55,7 +55,7 @@ NetworkWatcher is automatically created by Azure when VirtualNetwork is created | description | Cloudexport entry description in Kentik | `string` | `Created using Terraform` | no | | resource_tag | Azure Tag value to apply to created resources | `string` | `flow_log_exporter` | no | | flow_exporter_application_id | Kentik VNet Flow Exporter application ID | `string` | `a20ce222-63c0-46db-86d5-58551eeee89f` | no | -| storage_account_names | Names of Storage Accounts to be created for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. Auto-generated names will use the first 12 characters of the var.name for the Cloudexport appended with a random id of 12 characters for uniqueness. | `list of strings` | `[]` | no | +| storage_account_names | Names of Storage Accounts to be created for storing flow logs. Names must meet Azure Storage Account naming restrictions.
The list should either contain 1 Storage Account name for each Resource Group, or be empty, in which case names will be generated automatically. Auto-generated names will use the first 12 characters of the `var.name` for the Cloudexport as a prefix appended with a random id of 12 characters for global uniqueness. | `list of strings` | `[]` | no | ## Outputs