From 74a4e2095a6fa4cf6db0349495d4d42b697fc027 Mon Sep 17 00:00:00 2001 From: Mateusz Midor <3demaniac@gmail.com> Date: Tue, 25 Jan 2022 07:55:55 +0100 Subject: [PATCH] Cloudexport azure automation across resourcegroups (#45) * Add kentik-side cloudexport configuration for azure * Add service principal creation to further automate onboarding * Azure cloudexport across resource groups --- .github/workflows/azure-terraform.yml | 8 +-- cloud_AWS/terraform/module/tests/main.tf | 2 +- cloud_Azure/README.md | 8 +-- cloud_Azure/terraform/module/README.md | 56 +++++++++-------- cloud_Azure/terraform/module/cloudexport.tf | 27 ++++++++ .../module/examples/all_nsg/README.md | 40 ++++++++---- .../terraform/module/examples/all_nsg/main.tf | 24 +++++-- .../module/examples/all_nsg/output.tf | 12 ++-- .../module/examples/all_nsg/variables.tf | 19 ++++-- cloud_Azure/terraform/module/get_nsg.py | 32 ++++++---- .../terraform/module/network_watcher.tf | 62 ++++++++++++++----- cloud_Azure/terraform/module/output.tf | 23 ++++--- cloud_Azure/terraform/module/requirements.txt | 2 +- cloud_Azure/terraform/module/roles.tf | 16 +++-- .../terraform/module/service_principal.tf | 12 ++++ .../terraform/module/storage_account.tf | 13 ++-- cloud_Azure/terraform/module/tests/main.tf | 30 +++++++-- cloud_Azure/terraform/module/variables.tf | 44 ++++++++++--- synthetics_POC/terraform/README.md | 15 +++-- 19 files changed, 317 insertions(+), 128 deletions(-) create mode 100644 cloud_Azure/terraform/module/cloudexport.tf create mode 100644 cloud_Azure/terraform/module/service_principal.tf diff --git a/.github/workflows/azure-terraform.yml b/.github/workflows/azure-terraform.yml index 2e1aa72..ad749a5 100644 --- a/.github/workflows/azure-terraform.yml +++ b/.github/workflows/azure-terraform.yml @@ -21,10 +21,10 @@ jobs: # Initialize the Terraform code - name: (HELPER) Init Code - uses: docker://hashicorp/terraform:0.12.29 + uses: docker://hashicorp/terraform:1.0.0 with: entrypoint: terraform - args: init cloud_Azure/terraform/module/tests/ + args: -chdir=cloud_Azure/terraform/module/tests/ init # Lint the Terraform code # Using: https://github.com/terraform-linters/tflint @@ -36,7 +36,7 @@ jobs: # Validate the Terraform code using inbuilt # validate command - name: Validate Module - uses: docker://hashicorp/terraform:0.12.29 + uses: docker://hashicorp/terraform:1.0.0 with: entrypoint: terraform - args: validate cloud_Azure/terraform/module/tests/ -no-color + args: -chdir=cloud_Azure/terraform/module/tests/ validate -no-color diff --git a/cloud_AWS/terraform/module/tests/main.tf b/cloud_AWS/terraform/module/tests/main.tf index ef91cb0..1cbbeca 100644 --- a/cloud_AWS/terraform/module/tests/main.tf +++ b/cloud_AWS/terraform/module/tests/main.tf @@ -32,7 +32,7 @@ provider "aws" { } provider "kentik-cloudexport" { - email = "dummy@tesl.mail" + email = "dummy@test.mail" token = "dummy_token" } diff --git a/cloud_Azure/README.md b/cloud_Azure/README.md index a22a499..6951f95 100644 --- a/cloud_Azure/README.md +++ b/cloud_Azure/README.md @@ -1,5 +1,5 @@ -Code for preparing Azure cloud to work with portal.kentik.com [portal.kentik.com](https://portal.kentik.com) +# Automation support for configuring flow log export from Azure to [Kentik](https://portal.kentik.com) -Currently supported: -* [terraform](terraform/module) -* [ansible](ansible/roles/kentik_az) +Currently supported frameworks: +* [Terraform] (terrafrom/module) +* [Ansible] (ansible/roles/kentik_az) diff --git a/cloud_Azure/terraform/module/README.md b/cloud_Azure/terraform/module/README.md index f9b3232..64a7c4b 100644 --- a/cloud_Azure/terraform/module/README.md +++ b/cloud_Azure/terraform/module/README.md @@ -1,12 +1,21 @@ # Azure Kentik integration Terraform module -Terraform module which creates Azure resources required for Kentik to enable integration +Module supporting management of Azure and Kentik resources required for flow log export from Azure to Kentik. Module enables: -* Flow logs in existing Network Security Groups +* Flow logs in all Network Security Groups (NSG) found in requested Resource Groups Module creates: +* Service Principal for Kentik NSG Flow Exporter application +* Reader and Contributor Roles for above mentioned Service Principal +* One Storage Account for flow logs per requested Resource Group +* One Flow log per NSG across all requested Resource Groups +* Registers flow in Kentik platform per requested Resource Group +All created resources are tagged with: +`app = "kentik_flow_log_exporter"` + +Module assumes that NetworkWatcher resource exists in NetworkWatcherRG resource group in specified Azure location (see variable "location"). It 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) ## Usage @@ -16,28 +25,29 @@ Module creates: module kentik_azure_integration { source = "../../" location = var.location - resource_group_name = var.resource_group_name - principal_id = var.principal_id subscription_id = var.subscription_id + resource_group_names = var.resource_group_names + prefix = var.prefix + plan_id = var.plan_id + name = var.name } ``` ## Examples -* [All Network Security Groups in Resource Group](examples/all_nsg) +* [All Network Security Groups in requested Resource Groups](examples/all_nsg) ## Demo * [Demo showing how to add list of subnets to Kentik portal using this module](demo) (TBD) -## Note -* this module creates Azure resources only. This won't register resources in Kentik platform automatically. - ## Requirements | Name | Version | |------|---------| -| terraform | >=0.12.0 | -| azurem provider | >= =2.20.0 | +| terraform | >= 1.0.0 | +| azurerm provider | >= 2.85.0 | +| azuread provider | >= 2.14.0 | +| kentik-cloudexport provider | >= 0.4.1 | | null provider | >= 2.1.2 | | external provider | >= 2.0.0 | | python | >= 3.7.5 | @@ -47,30 +57,25 @@ module kentik_azure_integration { ### Python and dependencies -This module uses python to gather all NSG from Resource Group and expose it to terraform as external data source. +This module uses python to gather all NSG from Resource Groups and expose it to terraform as external data source. To install python and its requirements: * [Install Python 3](https://docs.python.org/3/using/index.html) * [Install pip3](https://pip.pypa.io/en/stable/installing/) * Install packages: run `pip3 install -r ../../requirements.txt` in example directory -## Providers - -| Name | Version | -|------|---------| -| azurem | >= =2.20.0 | -| null | >= 2.1.2 | -| external | >= 2.0.0 | - ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | location | Azure location of the resources to gather logs | `string` | `` | yes | | subscription_id | Id of the subscription in which resource are located | `string` | `` | yes | -| resource_group_name | Name of the resource group to gather logs from | `string` | `` | yes | -| principal_id | Id of the Service Principal Id for kentik app connection | `string` | `` | yes | -| prefix| Prefix for the naming resources created by this module | `string` | `kentik` | no | - +| resource_group_names | List of Resource Group names to gather logs from | `list of strings` | `` | yes | +| prefix| Prefix for the naming resources created by this module | `string` | `` | yes | +| plan_id | Billing plan ID | `string` | `` | yes | +| name | Cloudexport entry name in Kentik | `string` | `` | yes | +| flow_exporter_application_id | Kentik NSG Flow Exporter application ID | `string` | `a20ce222-63c0-46db-86d5-58551eeee89f` | no | +| enabled | Defines if cloud export to Kentik is enabled | `bool` | true | no | +| description | Cloudexport entry description in Kentik | `string` | `` | no | ## Outputs @@ -79,5 +84,6 @@ To install python and its requirements: |------|-------------| | network_security_groups | Id's of the Network Security groups that logs will be gathered from | | subscription_id | Subscription Id | -| resource_group | Resource group name | -| storage_account | Storage account name where logs will be gathered | +| resource_group_names | Resource group names | +| storage_accounts | Storage account names where logs will be gathered | +| principal_id | Principal ID created for Kentik NSG Flow Exporter application | \ No newline at end of file diff --git a/cloud_Azure/terraform/module/cloudexport.tf b/cloud_Azure/terraform/module/cloudexport.tf new file mode 100644 index 0000000..dea4dce --- /dev/null +++ b/cloud_Azure/terraform/module/cloudexport.tf @@ -0,0 +1,27 @@ +terraform { + required_providers { + kentik-cloudexport = { + source = "kentik/kentik-cloudexport" + version = ">= 0.4.1" + } + } +} + +# Creates one Kentik CloudExport for each requested Resource Group +resource "kentik-cloudexport_item" "azure_export" { + count = length(var.resource_group_names) + + name = "${var.name}_${var.resource_group_names[count.index]}" # name must be unique + type = "CLOUD_EXPORT_TYPE_KENTIK_MANAGED" + enabled = var.enabled + description = var.description + plan_id = var.plan_id + cloud_provider = "azure" + azure { + 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 + subscription_id = var.subscription_id + security_principal_enabled = true + } +} \ No newline at end of file diff --git a/cloud_Azure/terraform/module/examples/all_nsg/README.md b/cloud_Azure/terraform/module/examples/all_nsg/README.md index e0566c5..bac00d3 100644 --- a/cloud_Azure/terraform/module/examples/all_nsg/README.md +++ b/cloud_Azure/terraform/module/examples/all_nsg/README.md @@ -1,20 +1,33 @@ -# All Network Security Groups in Resource Group +# All Network Security Groups in requested Resource Groups -Configuration in this directory creates configuration for all Network Security Group in Resource Group. +This example creates cloud export configuration for all Network Security Groups in requested Resource Groups. + +## Requirements + +* Information about Azure deployment: location, resource group names, subscription ID +* Information about Kentik subscription: plan ID +* Azure CLI - [Installation](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) +* Authenticating Azure CLI to your account - [Logging-in](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli) +* Kentik API credentials present in execution environment: + ```bash + export KTAPI_AUTH_EMAIL="joe.doe@email.com" + export KTAPI_AUTH_TOKEN="token123" + ``` ## Usage To run this example you need to execute: ``` $ terraform init -$ terraform plan -$ terraform apply +$ terraform apply \ + --var subscription_id= \ + --var location= \ + --var resource_group_names= \ + --var prefix= \ + --var plan_id= \ + --var name= ``` -## Requirements - -* Example requires location, resource group name, principal id, subscription -* Installed and logged az-cli [Installation](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) [Logging](https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli) ## Inputs @@ -22,8 +35,10 @@ $ terraform apply |------|-------------|------|---------|:--------:| | location | Azure location of the resources to gather logs | `string` | `` | yes | | subscription_id | Id of the subscription in which resource are located | `string` | `` | yes | -| resource_group_name | Name of the resource group to gather logs from | `string` | `` | yes | -| principal_id | Id of the Service Principal Id for kentik app connection | `string` | `` | yes | +| resource_group_names | List of Resource Group names to gather logs from | `list of strings` | `` | yes | +| prefix| Prefix for the naming resources | `string` | `` | yes | +| plan_id | Billing plan ID | `string` | `` | yes | +| name | Cloudexport entry name in Kentik | `string` | `` | yes | ## Outputs @@ -31,5 +46,6 @@ $ terraform apply |------|-------------| | network_security_groups | Id's of the Network Security groups that logs will be gathered from | | subscription_id | Subscription Id | -| resource_group | Resource group name | -| storage_account | Storage account name where logs will be gathered | +| resource_group_names | Resource group names | +| storage_accounts | Storage account names where logs will be gathered | +| principal_id | Principal ID created for Kentik NSG Flow Exporter application | diff --git a/cloud_Azure/terraform/module/examples/all_nsg/main.tf b/cloud_Azure/terraform/module/examples/all_nsg/main.tf index cd5c1cc..e3907ef 100644 --- a/cloud_Azure/terraform/module/examples/all_nsg/main.tf +++ b/cloud_Azure/terraform/module/examples/all_nsg/main.tf @@ -1,16 +1,32 @@ terraform { - required_version = ">= 0.12.0" + required_version = ">= 1.0.0" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 2.85.0" + } + azuread = { + source = "hashicorp/azuread" + version = ">= 2.14.0" + } + kentik-cloudexport = { + source = "kentik/kentik-cloudexport" + version = ">= 0.4.1" + } + } } provider "azurerm" { - version = "=2.20.0" features {} } + module kentik_azure_integration { source = "../../" location = var.location - resource_group_name = var.resource_group_name - principal_id = var.principal_id subscription_id = var.subscription_id + resource_group_names = var.resource_group_names + prefix = var.prefix + plan_id = var.plan_id + name = var.name } diff --git a/cloud_Azure/terraform/module/examples/all_nsg/output.tf b/cloud_Azure/terraform/module/examples/all_nsg/output.tf index b29718f..97e0ddf 100644 --- a/cloud_Azure/terraform/module/examples/all_nsg/output.tf +++ b/cloud_Azure/terraform/module/examples/all_nsg/output.tf @@ -7,10 +7,14 @@ output "subscription_id" { value = module.kentik_azure_integration.subscription_id } -output "resource_group" { - value = module.kentik_azure_integration.resource_group +output "resource_group_names" { + value = module.kentik_azure_integration.resource_group_names } -output "storage_account" { - value = module.kentik_azure_integration.storage_account +output "storage_accounts" { + value = module.kentik_azure_integration.storage_accounts } + +output "principal_id" { + value = module.kentik_azure_integration.principal_id +} \ No newline at end of file diff --git a/cloud_Azure/terraform/module/examples/all_nsg/variables.tf b/cloud_Azure/terraform/module/examples/all_nsg/variables.tf index 6630d74..9d2efa7 100644 --- a/cloud_Azure/terraform/module/examples/all_nsg/variables.tf +++ b/cloud_Azure/terraform/module/examples/all_nsg/variables.tf @@ -8,12 +8,21 @@ variable "subscription_id" { description = "Subscription Id" } -variable "resource_group_name" { - type = string - description = "Resource group name" +variable "resource_group_names" { + type = list + description = "List of resource group names" } -variable "principal_id" { +variable "prefix" { type = string - description = "Service Principal Id" + description = "Unique prefix to be used for resource creation; can only consist of lowercase letters and numbers, max length is 17" +} +variable "plan_id" { + description = "Billing plan ID" + type = string } + +variable "name" { + description = "Cloudexport entry name in Kentik" + type = string +} \ No newline at end of file diff --git a/cloud_Azure/terraform/module/get_nsg.py b/cloud_Azure/terraform/module/get_nsg.py index cbbc912..8ea029f 100755 --- a/cloud_Azure/terraform/module/get_nsg.py +++ b/cloud_Azure/terraform/module/get_nsg.py @@ -1,22 +1,32 @@ +import sys +from typing import Dict, List + from az.cli import az from terraform_external_data import terraform_external_data -import sys - @terraform_external_data -def get_nsg_from_rg(query): +def get_nsg_from_rg(query: Dict[str, str]) -> Dict[str, str]: """ - Functions that gest all Network Security Groups from Resource Group + Gather all Network Security Groups for each requested Resource Group """ - exit_code, result_dict, logs = az( - "network nsg list --resource-group " + str(sys.argv[1]) + " --query '[].id' -o json") - if exit_code == 0: - return {query['network_security_groups']: str(result_dict).strip("[]").replace("'", "").replace(" ", "")} - else: - print(logs) + 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_groups = str(result_dict).strip("[]").replace("'", "").replace(" ", "") + result[rg] = network_security_groups + else: + print(logs, file=sys.stderr) + exit(1) + return result # result is consumed by function decorator -if __name__ == '__main__': +if __name__ == "__main__": get_nsg_from_rg() diff --git a/cloud_Azure/terraform/module/network_watcher.tf b/cloud_Azure/terraform/module/network_watcher.tf index 4de8e9e..ccf40e1 100644 --- a/cloud_Azure/terraform/module/network_watcher.tf +++ b/cloud_Azure/terraform/module/network_watcher.tf @@ -1,32 +1,62 @@ -# Creates network watcher -resource "azurerm_network_watcher" "kentik_network_watcher" { - name = "${var.prefix}_network_watcher" - location = var.location - resource_group_name = var.resource_group_name +# Network Watcher is created automatically by Azure when VirtualNetwork is created or updated in the subscription, see: +# https://docs.microsoft.com/en-us/azure/network-watcher/network-watcher-create +data "azurerm_network_watcher" "network_watcher" { + name = "NetworkWatcher_${var.location}" + resource_group_name = "NetworkWatcherRG" } -# Runs python script to gather network security groups and expose it as a data source +# Runs python script to gather network security groups from each requested resource group +# 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", "${var.resource_group_name}"] - + program = ["python3", "${path.module}/get_nsg.py"] query = { - network_security_groups = "nsg" + resource_group_names = join(",", var.resource_group_names) } } -# Turns on flow logs for all network securiti groups in resource group +# 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"} +# ] +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 + nsg = nsg # Network Security Group + } + ] + ]) +} + +# Turns on flow logs for all network security groups in requested resource groups resource "azurerm_network_watcher_flow_log" "kentik_network_flow_log" { - for_each = toset(split(",", data.external.nsg_data_source.result.nsg)) - network_watcher_name = azurerm_network_watcher.kentik_network_watcher.name - resource_group_name = var.resource_group_name + count = length(local.flat_nsgs) - network_security_group_id = each.key - storage_account_id = azurerm_storage_account.kentik_storage_account.id + network_watcher_name = data.azurerm_network_watcher.network_watcher.name + resource_group_name = data.azurerm_network_watcher.network_watcher.resource_group_name + + 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 - retention_policy { enabled = true days = 7 } + tags = { + app = "kentik_flow_log_exporter" + } } diff --git a/cloud_Azure/terraform/module/output.tf b/cloud_Azure/terraform/module/output.tf index 5e954ee..0a24762 100644 --- a/cloud_Azure/terraform/module/output.tf +++ b/cloud_Azure/terraform/module/output.tf @@ -1,19 +1,24 @@ output network_security_groups { - value = split(",", data.external.nsg_data_source.result.nsg) - description = "List of network security groups" + value = [for v in local.flat_nsgs: v.nsg] + description = "List of network security group IDs" } output subscription_id { value = var.subscription_id - description = "Subscription Id" + description = "Azure subscription ID" } -output resource_group { - value = var.resource_group_name - description = "Resource group name" +output resource_group_names { + value = var.resource_group_names + description = "Resource group names for which flow logs are being collected" } -output storage_account { - value = azurerm_storage_account.kentik_storage_account.name - description = "Storage account name" +output storage_accounts { + value = azurerm_storage_account.logs_storage_account[*].name + description = "Flow log storage account names" } + +output principal_id { + value = azuread_service_principal.kentik_nsg_flow_exporter.object_id + description = "Principal ID for Kentik NSG Flow Exporter" +} \ No newline at end of file diff --git a/cloud_Azure/terraform/module/requirements.txt b/cloud_Azure/terraform/module/requirements.txt index 808fb94..24e47d5 100644 --- a/cloud_Azure/terraform/module/requirements.txt +++ b/cloud_Azure/terraform/module/requirements.txt @@ -1,2 +1,2 @@ az.cli==0.4 -terraform-external-data==1.1.0 +terraform-external-data==1.0.3 diff --git a/cloud_Azure/terraform/module/roles.tf b/cloud_Azure/terraform/module/roles.tf index c0f4483..62c70cb 100644 --- a/cloud_Azure/terraform/module/roles.tf +++ b/cloud_Azure/terraform/module/roles.tf @@ -1,13 +1,17 @@ -# Provide service principal Contributor role to storage account +# Provide service principal Contributor role to each storage account resource "azurerm_role_assignment" "kentic_role_contributor" { - scope = azurerm_storage_account.kentik_storage_account.id + count = length(azurerm_storage_account.logs_storage_account) + + scope = azurerm_storage_account.logs_storage_account[count.index].id role_definition_name = "Contributor" - principal_id = var.principal_id + principal_id = azuread_service_principal.kentik_nsg_flow_exporter.object_id } -# Provide service principal Reader role to Resource Group +# Provide service principal Reader role to each Resource Group resource "azurerm_role_assignment" "kentic_role_reader" { - scope = "/subscriptions/${var.subscription_id}/resourceGroups/${var.resource_group_name}" + count = length(var.resource_group_names) + + scope = "/subscriptions/${var.subscription_id}/resourceGroups/${var.resource_group_names[count.index]}" role_definition_name = "Reader" - principal_id = var.principal_id + principal_id = azuread_service_principal.kentik_nsg_flow_exporter.object_id } diff --git a/cloud_Azure/terraform/module/service_principal.tf b/cloud_Azure/terraform/module/service_principal.tf new file mode 100644 index 0000000..7076892 --- /dev/null +++ b/cloud_Azure/terraform/module/service_principal.tf @@ -0,0 +1,12 @@ +data "azuread_client_config" "current" {} + +# Creates Service Principal for pre-existing "Kentik NSG Flow Exporter" app, so the app can access flow logs in Azure cloud +resource "azuread_service_principal" "kentik_nsg_flow_exporter" { + application_id = var.flow_exporter_application_id + app_role_assignment_required = false + owners = [data.azuread_client_config.current.object_id] + + feature_tags { + enterprise = true # show the app in AzurePortal under Enterprise Applications + } +} \ No newline at end of file diff --git a/cloud_Azure/terraform/module/storage_account.tf b/cloud_Azure/terraform/module/storage_account.tf index bef62ed..63dd130 100644 --- a/cloud_Azure/terraform/module/storage_account.tf +++ b/cloud_Azure/terraform/module/storage_account.tf @@ -1,12 +1,15 @@ -# Creates storage account to store flow logs -resource "azurerm_storage_account" "kentik_storage_account" { - name = "${var.prefix}storage" - resource_group_name = var.resource_group_name +# 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 +resource "azurerm_storage_account" "logs_storage_account" { + count = length(var.resource_group_names) + + name = "${var.prefix}flowlogstorage${tostring(count.index)}" # eg. acmeflowlogstorage0, max 27 letters + resource_group_name = var.resource_group_names[count.index] location = var.location account_tier = "Standard" account_replication_type = "GRS" tags = { - environment = "staging" + app = "kentik_flow_log_exporter" } } diff --git a/cloud_Azure/terraform/module/tests/main.tf b/cloud_Azure/terraform/module/tests/main.tf index 1419191..27bc96b 100644 --- a/cloud_Azure/terraform/module/tests/main.tf +++ b/cloud_Azure/terraform/module/tests/main.tf @@ -1,17 +1,37 @@ terraform { - required_version = ">= 0.12.0" + required_version = ">= 1.0.0" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 2.85.0" + } + azuread = { + source = "hashicorp/azuread" + version = ">= 2.14.0" + } + kentik-cloudexport = { + source = "kentik/kentik-cloudexport" + version = ">= 0.4.1" + } + } } provider "azurerm" { - # whilst the `version` attribute is optional, we recommend pinning to a given version of the Provider - version = "=2.20.0" features {} } + +provider "kentik-cloudexport" { + email = "dummy@test.mail" + token = "dummy_token" +} + module kentik_azure_integration { source = "../" location = "westeurope" - resource_group_name = "test" - principal_id = "test_prin_id" + resource_group_names = ["testrg1", "testrg2"] subscription_id = "test_sub_id" + prefix = "test" + plan_id = "12345" + name = "azure_europe_west" } diff --git a/cloud_Azure/terraform/module/variables.tf b/cloud_Azure/terraform/module/variables.tf index 6d68ea0..67a011c 100644 --- a/cloud_Azure/terraform/module/variables.tf +++ b/cloud_Azure/terraform/module/variables.tf @@ -1,3 +1,4 @@ +# provideres: azurerm & azuread variable "location" { type = string description = "Azure location" @@ -5,21 +6,44 @@ variable "location" { variable "subscription_id" { type = string - description = "Subscription Id" + description = "Azure ubscription ID" } -variable "resource_group_name" { - type = string - description = "Resource group name" +variable "resource_group_names" { + type = list + description = "List of resource group names to collect flow logs from" } -variable "principal_id" { +variable "prefix" { type = string - description = "Service Principal Id" + description = "Unique prefix to be used for resource creation; can only consist of lowercase letters and numbers" } -variable "prefix" { - type = string - default = "kentik" - description = "Prefix to be used for resource creation - default \"kentik\"" +# provider: kentik-cloudexport +variable "plan_id" { + description = "Kentik billing plan ID" + type = string +} + +variable "name" { + description = "Exported cloud name in Kentik Portal" + type = string } + +variable "flow_exporter_application_id" { + type = string + default = "a20ce222-63c0-46db-86d5-58551eeee89f" + description = "Kentik NSG Flow Exporter application ID" +} + +variable "enabled" { + description = "Defines if cloud exported to Kentik is enabled" + type = bool + default = true +} + +variable "description" { + description = "Description of exported cloud in Kentik Portal" + type = string + default = "" +} \ No newline at end of file diff --git a/synthetics_POC/terraform/README.md b/synthetics_POC/terraform/README.md index c9ea179..d78857d 100644 --- a/synthetics_POC/terraform/README.md +++ b/synthetics_POC/terraform/README.md @@ -1,11 +1,14 @@ -## Create secret from existing ksynth installation +## Preserving ksynth instance identity across VM rebuild -To create a secret that can be used in terraform automation script for new instances you have to follow this steps: -- ssh in to VM which has ksynth agent installed -- [install aws-cli](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) -- run `aws configure` to log in to AWS account that you will use to store secrets. It must be the same that VM's run on. -- run `aws secretsmanager create-secret --name --secret-binary fileb:///var/lib/ksynth/ksynth.id` +The `ksynth.id` file contains unique identity for a `ksynth` instance. It needs to be preserved across VM upgrade in order to keep the instance associated with the tracking data in Kentik. + +In case of `ksynth` hosted in AWS VM, this can be achieved by storing the `ksynth.id` in AWS Secrets Manager, using following steps: +- install AWS CLI on your workstation [install aws-cli](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) and configure it for the target account (`aws configure`) +- copy `ksynth.id` from the running VM to your local workstation: `scp :/var/lib/ksynth/ksynth.id .id` +- create entry in AWS Secrets Manager: `aws secretsmanager create-secret --name --secret-binary fileb:.id` + +Note that you have to use unique `ksynth_instance_name` for each unique `ksynth` instance (i.e. for each instance represented as a separate agent in Kentik. The `ksynth.id` identity cannot be shared among instances. ## Run terraform - create tfvars file