From f2929279da441ff901ff21d7d55e9c1c5a4018bf Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 11:16:20 +0200 Subject: [PATCH 01/26] add barebone terraform project and github actions --- .../workflows/infrastructure-template.yaml | 63 +++++++++++++++++++ .github/workflows/infrastructure.yaml | 58 +++++++++++++++++ infrastructure/authorization/main.tf | 14 +++++ infrastructure/authorization/provider.tf | 4 ++ infrastructure/authorization/variables.tf | 1 + infrastructure/modules/vnet/main.tf | 0 infrastructure/modules/vnet/variables.tf | 0 7 files changed, 140 insertions(+) create mode 100644 .github/workflows/infrastructure-template.yaml create mode 100644 .github/workflows/infrastructure.yaml create mode 100644 infrastructure/authorization/main.tf create mode 100644 infrastructure/authorization/provider.tf create mode 100644 infrastructure/authorization/variables.tf create mode 100644 infrastructure/modules/vnet/main.tf create mode 100644 infrastructure/modules/vnet/variables.tf diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml new file mode 100644 index 00000000..8629d6cc --- /dev/null +++ b/.github/workflows/infrastructure-template.yaml @@ -0,0 +1,63 @@ +name: Infrastructure + +on: + workflow_call: + inputs: + tf_should_apply: + default: false + type: boolean + description: Specifies if terraform should apply plan + + environment: + type: string + description: GitHub environment + required: true + +env: + TF_STATE_NAME: infrastructure.tfstate + WORKING_DIR: ./infrastructure/authorization + +permissions: + id-token: write + contents: write + pull-requests: write + +jobs: + plan: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Terraform Initialize + uses: altinn/altinn-platform/actions/terraform/plan@main + with: + working_directory: ${{ env.WORKING_DIR }} + oidc_type: environment + oidc_value: ${{ inputs.environment }} + + arm_client_id: ${{ variables.ARM_CLIENT_ID }} + arm_subscription_id: ${{ variables.ARM_SUBSCRIPTION_ID }} + + tf_state_name: ${{ env.TF_STATE_NAME }} + gh_token: ${{ secrets.GITHUB_TOKEN }} + + apply: + runs-on: ubuntu-latest + if: inputs.tf_should_apply + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Terraform Initialize + uses: altinn/altinn-platform/actions/terraform/plan@main + with: + working_directory: ${{ env.WORKING_DIR }} + oidc_type: environment + oidc_value: ${{ inputs.environment }} + + arm_client_id: ${{ variables.ARM_CLIENT_ID }} + arm_subscription_id: ${{ variables.ARM_SUBSCRIPTION_ID }} + + tf_state_name: ${{ env.TF_STATE_NAME }} + gh_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/infrastructure.yaml b/.github/workflows/infrastructure.yaml new file mode 100644 index 00000000..220df4bc --- /dev/null +++ b/.github/workflows/infrastructure.yaml @@ -0,0 +1,58 @@ +name: Infrastructure + +on: + push: + release: + types: + - released + +permissions: + id-token: write + contents: write + pull-requests: write + +jobs: + ci: + name: Continous Integration + secrets: inherit + strategy: + fail-fast: false + matrix: + environment: [AT21, AT22, AT23, AT24] + uses: ./.github/workflows/infrastructure-template.yaml + with: + environment: ${{ matrix.environment }} + + at: + name: AT + secrets: inherit + needs: ci + if: github.event_name == 'release' + strategy: + fail-fast: false + matrix: + environment: [AT21, AT22, AT23, AT24] + uses: ./.github/workflows/infrastructure-template.yaml + with: + environment: ${{ matrix.environment }} + tf_should_apply: true + + tt02: + name: TT02 + if: github.event_name == 'release' + needs: at + secrets: inherit + uses: ./.github/workflows/infrastructure-template.yaml + with: + environment: TT02 + tf_should_apply: true + + prod: + name: PROD + if: github.event_name == 'release + needs: tt02 + secrets: inherit + uses: ./.github/workflows/infrastructure-template.yaml + with: + environment: PROD + tf_should_apply: true diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf new file mode 100644 index 00000000..33d552dc --- /dev/null +++ b/infrastructure/authorization/main.tf @@ -0,0 +1,14 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "3.112.0" + } + } +} + + +resource "azurerm_resource_group" "auth" { + name = "rg-altinn-auth-001" + location = "norwayeast" +} diff --git a/infrastructure/authorization/provider.tf b/infrastructure/authorization/provider.tf new file mode 100644 index 00000000..8bef2c25 --- /dev/null +++ b/infrastructure/authorization/provider.tf @@ -0,0 +1,4 @@ +provider "azurerm" { + use_oidc = true + features {} +} diff --git a/infrastructure/authorization/variables.tf b/infrastructure/authorization/variables.tf new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/infrastructure/authorization/variables.tf @@ -0,0 +1 @@ + diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/modules/vnet/variables.tf b/infrastructure/modules/vnet/variables.tf new file mode 100644 index 00000000..e69de29b From 5942176247bf4ca1418140bf8a095c1a68ce2cdb Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 11:17:33 +0200 Subject: [PATCH 02/26] fix missing ' --- .github/workflows/infrastructure.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/infrastructure.yaml b/.github/workflows/infrastructure.yaml index 220df4bc..0a94d20d 100644 --- a/.github/workflows/infrastructure.yaml +++ b/.github/workflows/infrastructure.yaml @@ -49,7 +49,7 @@ jobs: prod: name: PROD - if: github.event_name == 'release + if: github.event_name == 'release' needs: tt02 secrets: inherit uses: ./.github/workflows/infrastructure-template.yaml From 0cd1493562ba2bbf36d5a7e7e7b2dd6fa9728392 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 11:23:36 +0200 Subject: [PATCH 03/26] rewrite tempalte subs. variables to vars. --- .github/workflows/infrastructure-template.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml index 8629d6cc..5aae8ec8 100644 --- a/.github/workflows/infrastructure-template.yaml +++ b/.github/workflows/infrastructure-template.yaml @@ -25,6 +25,7 @@ permissions: jobs: plan: runs-on: ubuntu-latest + environment: ${{ inputs.environment }} steps: - name: Checkout Repository uses: actions/checkout@v4 @@ -36,14 +37,15 @@ jobs: oidc_type: environment oidc_value: ${{ inputs.environment }} - arm_client_id: ${{ variables.ARM_CLIENT_ID }} - arm_subscription_id: ${{ variables.ARM_SUBSCRIPTION_ID }} + arm_client_id: ${{ vars.ARM_CLIENT_ID }} + arm_subscription_id: ${{ vars.ARM_SUBSCRIPTION_ID }} tf_state_name: ${{ env.TF_STATE_NAME }} gh_token: ${{ secrets.GITHUB_TOKEN }} apply: runs-on: ubuntu-latest + environment: ${{ inputs.environment }} if: inputs.tf_should_apply steps: - name: Checkout Repository @@ -56,8 +58,8 @@ jobs: oidc_type: environment oidc_value: ${{ inputs.environment }} - arm_client_id: ${{ variables.ARM_CLIENT_ID }} - arm_subscription_id: ${{ variables.ARM_SUBSCRIPTION_ID }} + arm_client_id: ${{ vars.ARM_CLIENT_ID }} + arm_subscription_id: ${{ vars.ARM_SUBSCRIPTION_ID }} tf_state_name: ${{ env.TF_STATE_NAME }} gh_token: ${{ secrets.GITHUB_TOKEN }} From 57418d494c6b7f83b76d3a193174cd16670c16f2 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 12:29:50 +0200 Subject: [PATCH 04/26] add environment as variable --- .github/workflows/infrastructure-template.yaml | 3 ++- infrastructure/authorization/main.tf | 2 +- infrastructure/authorization/variables.tf | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml index 5aae8ec8..e17462b1 100644 --- a/.github/workflows/infrastructure-template.yaml +++ b/.github/workflows/infrastructure-template.yaml @@ -41,6 +41,7 @@ jobs: arm_subscription_id: ${{ vars.ARM_SUBSCRIPTION_ID }} tf_state_name: ${{ env.TF_STATE_NAME }} + tf_args: -var environment=${{ inputs.environment }} gh_token: ${{ secrets.GITHUB_TOKEN }} apply: @@ -61,5 +62,5 @@ jobs: arm_client_id: ${{ vars.ARM_CLIENT_ID }} arm_subscription_id: ${{ vars.ARM_SUBSCRIPTION_ID }} + tf_args: -var environment=${{ inputs.environment }} tf_state_name: ${{ env.TF_STATE_NAME }} - gh_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index 33d552dc..880b559b 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -9,6 +9,6 @@ terraform { resource "azurerm_resource_group" "auth" { - name = "rg-altinn-auth-001" + name = "rg-altinn-authorization-${var.environment}-001" location = "norwayeast" } diff --git a/infrastructure/authorization/variables.tf b/infrastructure/authorization/variables.tf index 8b137891..b1374264 100644 --- a/infrastructure/authorization/variables.tf +++ b/infrastructure/authorization/variables.tf @@ -1 +1,4 @@ +variable "environment" { + type = string +} From 45d082ccb85553e4d3ed8969b49a2de77c6c681e Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 12:33:09 +0200 Subject: [PATCH 05/26] add azurem backend --- infrastructure/authorization/main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index 880b559b..26c63f98 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -5,6 +5,10 @@ terraform { version = "3.112.0" } } + + backend "azurerm" { + use_azuread_auth = true + } } From 38526b3f2a95c0a4a0caa3b46bd229424b80e4e6 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 15:33:41 +0200 Subject: [PATCH 06/26] debug pipeline --- .../workflows/infrastructure-template.yaml | 4 +- infrastructure/authorization/README.md | 0 infrastructure/authorization/at21.tfvars | 0 infrastructure/authorization/main.tf | 11 +++- infrastructure/authorization/variables.tf | 15 ++++- infrastructure/modules/vnet/main.tf | 61 +++++++++++++++++++ infrastructure/modules/vnet/outputs.tf | 19 ++++++ infrastructure/modules/vnet/variables.tf | 15 +++++ 8 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 infrastructure/authorization/README.md create mode 100644 infrastructure/authorization/at21.tfvars create mode 100644 infrastructure/modules/vnet/outputs.tf diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml index e17462b1..0dd57bb0 100644 --- a/.github/workflows/infrastructure-template.yaml +++ b/.github/workflows/infrastructure-template.yaml @@ -31,7 +31,7 @@ jobs: uses: actions/checkout@v4 - name: Terraform Initialize - uses: altinn/altinn-platform/actions/terraform/plan@main + uses: altinn/altinn-platform/actions/terraform/plan@features/828 with: working_directory: ${{ env.WORKING_DIR }} oidc_type: environment @@ -53,7 +53,7 @@ jobs: uses: actions/checkout@v4 - name: Terraform Initialize - uses: altinn/altinn-platform/actions/terraform/plan@main + uses: altinn/altinn-platform/actions/terraform/plan@features/828 with: working_directory: ${{ env.WORKING_DIR }} oidc_type: environment diff --git a/infrastructure/authorization/README.md b/infrastructure/authorization/README.md new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/authorization/at21.tfvars b/infrastructure/authorization/at21.tfvars new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index 26c63f98..31ca7c1b 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -12,7 +12,12 @@ terraform { } -resource "azurerm_resource_group" "auth" { - name = "rg-altinn-authorization-${var.environment}-001" - location = "norwayeast" +locals { + environment = lower(var.environment) + metadata = { + solution = "authorization" + environment = local.environment + instance = var.instance + } } + diff --git a/infrastructure/authorization/variables.tf b/infrastructure/authorization/variables.tf index b1374264..c47a7729 100644 --- a/infrastructure/authorization/variables.tf +++ b/infrastructure/authorization/variables.tf @@ -1,4 +1,17 @@ - variable "environment" { type = string } + +variable "location" { + type = string + default = "norwayeast" +} + +variable "instance" { + type = string + default = "001" +} + +variable "cidr" { + type = string +} diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index e69de29b..0a7fa6cd 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -0,0 +1,61 @@ +locals { + size = 20 + subnets = { + key_vault = { + ip_addresses = 1 + } + app_configuration = { + ip_addresses = 1 + } + storage_accounts = { + ip_addresses = 1 + } + redis = { + ip_addresses = 1 + } + postgres = { + ip_addresses = 2 + delegations = { + fs = { + name = "Microsoft.DBforPostgreSQL/flexibleServers" + actions = [ + "Microsoft.Network/virtualNetworks/subnets/join/action" + ] + } + } + } + } +} + +data "azurerm_resource_group" "vnet" { + name = var.resource_group_name +} + +resource "azurerm_virtual_network" "vnet" { + name = "vnet-${var.metadata.solution}-${var.metadata.enviroment}-${var.metadata.instance}" + address_space = var.cidr + location = data.azurerm_resource_group.vnet.location + resource_group_name = data.azurerm_resource_group.vnet.name +} + + +resource "azurerm_subnet" "vnet" { + resource_group_name = var.resource_group_name + virtual_network_name = azurerm_virtual_network.vnet.name + address_prefixes = "" + name = each.key + + dynamic "delegation" { + content { + name = each.key + service_delegation { + name = each.value.name + actions = each.value.actions + } + } + + for_each = try(each.value.delegations, {}) + } + + for_each = local.subnets +} diff --git a/infrastructure/modules/vnet/outputs.tf b/infrastructure/modules/vnet/outputs.tf new file mode 100644 index 00000000..e718c9ae --- /dev/null +++ b/infrastructure/modules/vnet/outputs.tf @@ -0,0 +1,19 @@ +output "vnet" { + value = { + id : azurerm_virtual_network.vnet.id + name = azurerm_virtual_network.vnet.name + } + + description = "" +} + +output "subnets" { + value = { for subnet in local.subnets : subnet => + { + id = azurerm_virtual_network.vnet[subnet].id + name = azurerm_virtual_network.vnet[subnet].name + } + } + + description = "" +} diff --git a/infrastructure/modules/vnet/variables.tf b/infrastructure/modules/vnet/variables.tf index e69de29b..5e20c5dc 100644 --- a/infrastructure/modules/vnet/variables.tf +++ b/infrastructure/modules/vnet/variables.tf @@ -0,0 +1,15 @@ +variable "metadata" { + type = object({ + solution = string + environment = string + instance = string + }) +} + +variable "resource_group_name" { + type = string +} + +variable "cidr" { + type = string +} From 8a4f5c2504f5056e5850f777cbbe037124565c0e Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 15:34:50 +0200 Subject: [PATCH 07/26] debug pipeline --- infrastructure/authorization/variables.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/infrastructure/authorization/variables.tf b/infrastructure/authorization/variables.tf index c47a7729..97ca773e 100644 --- a/infrastructure/authorization/variables.tf +++ b/infrastructure/authorization/variables.tf @@ -13,5 +13,6 @@ variable "instance" { } variable "cidr" { - type = string + type = string + default = "value" } From ff578c651ffc48da09e917ee7cfedd3e300af3d8 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 15:49:37 +0200 Subject: [PATCH 08/26] debug pipeline --- infrastructure/authorization/main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index 31ca7c1b..a7fbd08c 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -21,3 +21,7 @@ locals { } } +resource "azurerm_resource_group" "authorization" { + name = "rg-${local.metadata.environment}-${local.metadata.instance}" + location = "norwayeast" +} From 1504b9937d4b5182b71962717010cd8b028d6baf Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 16:24:53 +0200 Subject: [PATCH 09/26] tfvars files --- .github/workflows/infrastructure-template.yaml | 7 +++++-- infrastructure/authorization/README.md | 8 ++++++++ infrastructure/authorization/at21.tfvars | 1 + infrastructure/authorization/at22.tfvars | 1 + infrastructure/authorization/at23.tfvars | 1 + infrastructure/authorization/at24.tfvars | 1 + infrastructure/authorization/main.tf | 8 ++++++++ infrastructure/modules/vnet/main.tf | 12 ++++++------ 8 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 infrastructure/authorization/at22.tfvars create mode 100644 infrastructure/authorization/at23.tfvars create mode 100644 infrastructure/authorization/at24.tfvars diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml index 0dd57bb0..309a2093 100644 --- a/.github/workflows/infrastructure-template.yaml +++ b/.github/workflows/infrastructure-template.yaml @@ -30,6 +30,9 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 + - name: Terraform Set TFVARS + run: echo "TF_VARS_FILE=$(echo ${{ inputs.environment }} | tr '[:upper:]' '[:lower:]').tfvars" >> $GITHUB_ENV + - name: Terraform Initialize uses: altinn/altinn-platform/actions/terraform/plan@features/828 with: @@ -41,7 +44,7 @@ jobs: arm_subscription_id: ${{ vars.ARM_SUBSCRIPTION_ID }} tf_state_name: ${{ env.TF_STATE_NAME }} - tf_args: -var environment=${{ inputs.environment }} + tf_args: -var environment=${{ inputs.environment }} -var-file=${{ env.TF_VARS_FILE }} gh_token: ${{ secrets.GITHUB_TOKEN }} apply: @@ -62,5 +65,5 @@ jobs: arm_client_id: ${{ vars.ARM_CLIENT_ID }} arm_subscription_id: ${{ vars.ARM_SUBSCRIPTION_ID }} - tf_args: -var environment=${{ inputs.environment }} + tf_args: -var environment=${{ inputs.environment }} -var-file=${{ env.TF_VARS_FILE }} tf_state_name: ${{ env.TF_STATE_NAME }} diff --git a/infrastructure/authorization/README.md b/infrastructure/authorization/README.md index e69de29b..7d93e309 100644 --- a/infrastructure/authorization/README.md +++ b/infrastructure/authorization/README.md @@ -0,0 +1,8 @@ + + +## Network Address Ranges +* Full Address Space for Authorization 10.202.0.0/20 +* 10.202.0.0/22 +* 10.202.4.0/22 +* 10.202.8.0/22 +* 10.202.12.0/22 \ No newline at end of file diff --git a/infrastructure/authorization/at21.tfvars b/infrastructure/authorization/at21.tfvars index e69de29b..bd9513ef 100644 --- a/infrastructure/authorization/at21.tfvars +++ b/infrastructure/authorization/at21.tfvars @@ -0,0 +1 @@ +cidr = "10.202.0.0/22" diff --git a/infrastructure/authorization/at22.tfvars b/infrastructure/authorization/at22.tfvars new file mode 100644 index 00000000..bd9513ef --- /dev/null +++ b/infrastructure/authorization/at22.tfvars @@ -0,0 +1 @@ +cidr = "10.202.0.0/22" diff --git a/infrastructure/authorization/at23.tfvars b/infrastructure/authorization/at23.tfvars new file mode 100644 index 00000000..bd9513ef --- /dev/null +++ b/infrastructure/authorization/at23.tfvars @@ -0,0 +1 @@ +cidr = "10.202.0.0/22" diff --git a/infrastructure/authorization/at24.tfvars b/infrastructure/authorization/at24.tfvars new file mode 100644 index 00000000..bd9513ef --- /dev/null +++ b/infrastructure/authorization/at24.tfvars @@ -0,0 +1 @@ +cidr = "10.202.0.0/22" diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index a7fbd08c..b23ca91e 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -25,3 +25,11 @@ resource "azurerm_resource_group" "authorization" { name = "rg-${local.metadata.environment}-${local.metadata.instance}" location = "norwayeast" } + +# module "vnet" { +# source = "../modules/vnet" +# metadata = local.metadata + +# cidr = var.cidr +# resource_group_name = azurerm_resource_group.authorization.name +# } diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index 0a7fa6cd..315da3eb 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -1,20 +1,20 @@ locals { - size = 20 + size = 22 subnets = { key_vault = { - ip_addresses = 1 + address_space = 4 } app_configuration = { - ip_addresses = 1 + address_space = 2 } storage_accounts = { - ip_addresses = 1 + address_space = 3 } redis = { - ip_addresses = 1 + address_space = 4 } postgres = { - ip_addresses = 2 + address_space = 5 delegations = { fs = { name = "Microsoft.DBforPostgreSQL/flexibleServers" From 6ca8b1a3f489955adb31bc91038a489dbab3bcf2 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 16:25:24 +0200 Subject: [PATCH 10/26] update github action template --- .github/workflows/infrastructure-template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml index 309a2093..5d408f83 100644 --- a/.github/workflows/infrastructure-template.yaml +++ b/.github/workflows/infrastructure-template.yaml @@ -34,7 +34,7 @@ jobs: run: echo "TF_VARS_FILE=$(echo ${{ inputs.environment }} | tr '[:upper:]' '[:lower:]').tfvars" >> $GITHUB_ENV - name: Terraform Initialize - uses: altinn/altinn-platform/actions/terraform/plan@features/828 + uses: altinn/altinn-platform/actions/terraform/plan@main with: working_directory: ${{ env.WORKING_DIR }} oidc_type: environment @@ -56,7 +56,7 @@ jobs: uses: actions/checkout@v4 - name: Terraform Initialize - uses: altinn/altinn-platform/actions/terraform/plan@features/828 + uses: altinn/altinn-platform/actions/terraform/plan@main with: working_directory: ${{ env.WORKING_DIR }} oidc_type: environment From b9a4815b48f8793613b262c2162d5fc16efde2e8 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 17:15:51 +0200 Subject: [PATCH 11/26] add vnet --- infrastructure/modules/vnet/main.tf | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index 315da3eb..38aa8d14 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -1,20 +1,24 @@ locals { - size = 22 + cidr_prefix = tonumber(split("/", var.cidr)[1]) + small_subnet_mask = 28 - cidr_prefix # IPs 16 + medium_subnet_mask = 26 - cidr_prefix # IPs 64 + large_subnet_mask = 24 - cidr_prefix # IPs 256 + subnets = { key_vault = { - address_space = 4 + bits = local.medium_subnet_mask } app_configuration = { - address_space = 2 + bits = local.medium_subnet_mask } storage_accounts = { - address_space = 3 + bits = local.small_subnet_mask } redis = { - address_space = 4 + bits = local.small_subnet_mask } postgres = { - address_space = 5 + bits = local.small_subnet_mask delegations = { fs = { name = "Microsoft.DBforPostgreSQL/flexibleServers" @@ -31,18 +35,27 @@ data "azurerm_resource_group" "vnet" { name = var.resource_group_name } + resource "azurerm_virtual_network" "vnet" { name = "vnet-${var.metadata.solution}-${var.metadata.enviroment}-${var.metadata.instance}" - address_space = var.cidr + address_space = [var.cidr] location = data.azurerm_resource_group.vnet.location resource_group_name = data.azurerm_resource_group.vnet.name } +module "subnet" { + source = "hashicorp/subnets/cidr" + base_cidr_block = var.cidr + networks = [for key, value in local.subnets : { + name = key + new_bits = value.subnet_mask + }] +} resource "azurerm_subnet" "vnet" { resource_group_name = var.resource_group_name virtual_network_name = azurerm_virtual_network.vnet.name - address_prefixes = "" + address_prefixes = module.subnet[each.key] name = each.key dynamic "delegation" { From 5e5ec3dbedcb8ae12760e05e42f187ad474b12ea Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 17:17:32 +0200 Subject: [PATCH 12/26] add vnet --- infrastructure/authorization/main.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index b23ca91e..1ea112d8 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -26,10 +26,10 @@ resource "azurerm_resource_group" "authorization" { location = "norwayeast" } -# module "vnet" { -# source = "../modules/vnet" -# metadata = local.metadata +module "vnet" { + source = "../modules/vnet" + metadata = local.metadata -# cidr = var.cidr -# resource_group_name = azurerm_resource_group.authorization.name -# } + cidr = var.cidr + resource_group_name = azurerm_resource_group.authorization.name +} From ece3fd2a8557687f31fa802babb10f0a4af13b04 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 15 Jul 2024 17:47:06 +0200 Subject: [PATCH 13/26] add vnet module --- .gitignore | 39 +++++++++++++++++++ .../authorization/.terraform.lock.hcl | 22 +++++++++++ infrastructure/authorization/main.tf | 8 ++-- infrastructure/authorization/variables.tf | 11 +++--- infrastructure/modules/vnet/main.tf | 31 +++++++-------- infrastructure/modules/vnet/outputs.tf | 6 +-- 6 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 infrastructure/authorization/.terraform.lock.hcl diff --git a/.gitignore b/.gitignore index 2e77f69f..e4793fbf 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,45 @@ nupkg/ # Visual Studio 2015 .vs/ +### Terraform +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Ignore transient lock info files created by terraform apply +.terraform.tfstate.lock.info + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + # Rider .idea diff --git a/infrastructure/authorization/.terraform.lock.hcl b/infrastructure/authorization/.terraform.lock.hcl new file mode 100644 index 00000000..b76fcebd --- /dev/null +++ b/infrastructure/authorization/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "3.112.0" + constraints = "3.112.0" + hashes = [ + "h1:5KSVV/O2eG6ty/3/qpOLQFQqJd96KEPzsTHItslJaMw=", + "zh:341c22454d24a75792aa99fbbc0c156f368534b7bb04eef4701b85995c7526a4", + "zh:3708656d75061c92f7208cc731b946c991ad343a443f8ff0ef082f077b7580b9", + "zh:38ca06f9f45705c648f04f272bd9483397693ea8da6db788cd7955f49ab79d6b", + "zh:3f305adb5ee0032e0ea68d198a089ecfd0127092930e99fa51377a250292b592", + "zh:4ae2fc6065164a819f576f705e634ebf5059f983149a41dad909719fea96145a", + "zh:5d376ac7dd71898a94038d6b6b8036dfec4c0216d832ec1135c855bf3e58eb5f", + "zh:63d2ff296d3aee5787e12c759a6a3d5aa15a574456aebbe11b833f01adf3faef", + "zh:8ad8746741f7f0ac10da6f1d105f26ebeb6e4d944f58ba749e86d7c9a67da3db", + "zh:abec182594ee8a21d72a5f23d3aa7fa45247488539fce6ed648c9c255d8bf972", + "zh:bf704b400be4181333b38c0306949f26326a9aa5ae68b4167e2fb8ee7fb13618", + "zh:c072938f8695f725fc5fbe986a54890f00d520cce570006390dc5bbc51b2a4ea", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf index 1ea112d8..86c1bd78 100644 --- a/infrastructure/authorization/main.tf +++ b/infrastructure/authorization/main.tf @@ -6,9 +6,9 @@ terraform { } } - backend "azurerm" { - use_azuread_auth = true - } + # backend "azurerm" { + # use_azuread_auth = true + # } } @@ -32,4 +32,6 @@ module "vnet" { cidr = var.cidr resource_group_name = azurerm_resource_group.authorization.name + + depends_on = [azurerm_resource_group.authorization] } diff --git a/infrastructure/authorization/variables.tf b/infrastructure/authorization/variables.tf index 97ca773e..69d82d0b 100644 --- a/infrastructure/authorization/variables.tf +++ b/infrastructure/authorization/variables.tf @@ -1,7 +1,3 @@ -variable "environment" { - type = string -} - variable "location" { type = string default = "norwayeast" @@ -12,7 +8,10 @@ variable "instance" { default = "001" } +variable "environment" { + type = string +} + variable "cidr" { - type = string - default = "value" + type = string } diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index 38aa8d14..9bc61579 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -1,24 +1,24 @@ locals { - cidr_prefix = tonumber(split("/", var.cidr)[1]) - small_subnet_mask = 28 - cidr_prefix # IPs 16 - medium_subnet_mask = 26 - cidr_prefix # IPs 64 - large_subnet_mask = 24 - cidr_prefix # IPs 256 + cidr_prefix = tonumber(split("/", var.cidr)[1]) + small_subnet = 28 - local.cidr_prefix # Available IPs 11 + medium_subnet = 26 - local.cidr_prefix # Available IPs 59 + large_subnet = 24 - local.cidr_prefix # # Available IPs 251 subnets = { key_vault = { - bits = local.medium_subnet_mask + bits = local.medium_subnet } app_configuration = { - bits = local.medium_subnet_mask + bits = local.medium_subnet } storage_accounts = { - bits = local.small_subnet_mask + bits = local.small_subnet } redis = { - bits = local.small_subnet_mask + bits = local.small_subnet } postgres = { - bits = local.small_subnet_mask + bits = local.small_subnet delegations = { fs = { name = "Microsoft.DBforPostgreSQL/flexibleServers" @@ -35,9 +35,8 @@ data "azurerm_resource_group" "vnet" { name = var.resource_group_name } - resource "azurerm_virtual_network" "vnet" { - name = "vnet-${var.metadata.solution}-${var.metadata.enviroment}-${var.metadata.instance}" + name = "vnet-${var.metadata.solution}-${var.metadata.environment}-${var.metadata.instance}" address_space = [var.cidr] location = data.azurerm_resource_group.vnet.location resource_group_name = data.azurerm_resource_group.vnet.name @@ -48,22 +47,22 @@ module "subnet" { base_cidr_block = var.cidr networks = [for key, value in local.subnets : { name = key - new_bits = value.subnet_mask + new_bits = value.bits }] } resource "azurerm_subnet" "vnet" { resource_group_name = var.resource_group_name virtual_network_name = azurerm_virtual_network.vnet.name - address_prefixes = module.subnet[each.key] + address_prefixes = [module.subnet.networks[index(module.subnet.networks.*.name, each.key)].cidr_block] name = each.key dynamic "delegation" { content { - name = each.key + name = delegation.key service_delegation { - name = each.value.name - actions = each.value.actions + name = delegation.value.name + actions = delegation.value.actions } } diff --git a/infrastructure/modules/vnet/outputs.tf b/infrastructure/modules/vnet/outputs.tf index e718c9ae..5e39d1e0 100644 --- a/infrastructure/modules/vnet/outputs.tf +++ b/infrastructure/modules/vnet/outputs.tf @@ -8,10 +8,10 @@ output "vnet" { } output "subnets" { - value = { for subnet in local.subnets : subnet => + value = { for key, value in local.subnets : key => { - id = azurerm_virtual_network.vnet[subnet].id - name = azurerm_virtual_network.vnet[subnet].name + id = azurerm_subnet.vnet[key].id + name = azurerm_subnet.vnet[key].name } } From c7964ed85399fd0c8519e07d21e6df49ee234ebb Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Tue, 16 Jul 2024 12:39:12 +0200 Subject: [PATCH 14/26] add network and encryption --- .gitignore | 7 -- infrastructure/authorization/main.tf | 37 -------- infrastructure/modules/dns/main.tf | 34 +++++++ infrastructure/modules/dns/outputs.tf | 7 ++ infrastructure/modules/dns/variables.tf | 15 ++++ infrastructure/modules/key_vault/main.tf | 88 +++++++++++++++++++ infrastructure/modules/key_vault/outputs.tf | 1 + infrastructure/modules/key_vault/variables.tf | 24 +++++ infrastructure/modules/nat_gateway/main.tf | 35 ++++++++ infrastructure/modules/nat_gateway/outputs.tf | 0 .../modules/nat_gateway/variables.tf | 18 ++++ infrastructure/modules/vnet/main.tf | 16 ++-- infrastructure/modules/vnet/outputs.tf | 11 ++- .../.terraform.lock.hcl | 19 ++++ .../{authorization => shared}/README.md | 0 .../{authorization => shared}/at21.tfvars | 0 .../{authorization => shared}/at22.tfvars | 0 .../{authorization => shared}/at23.tfvars | 0 .../{authorization => shared}/at24.tfvars | 0 infrastructure/shared/main.tf | 79 +++++++++++++++++ .../{authorization => shared}/provider.tf | 0 .../{authorization => shared}/variables.tf | 0 22 files changed, 330 insertions(+), 61 deletions(-) delete mode 100644 infrastructure/authorization/main.tf create mode 100644 infrastructure/modules/dns/main.tf create mode 100644 infrastructure/modules/dns/outputs.tf create mode 100644 infrastructure/modules/dns/variables.tf create mode 100644 infrastructure/modules/key_vault/main.tf create mode 100644 infrastructure/modules/key_vault/outputs.tf create mode 100644 infrastructure/modules/key_vault/variables.tf create mode 100644 infrastructure/modules/nat_gateway/main.tf create mode 100644 infrastructure/modules/nat_gateway/outputs.tf create mode 100644 infrastructure/modules/nat_gateway/variables.tf rename infrastructure/{authorization => shared}/.terraform.lock.hcl (53%) rename infrastructure/{authorization => shared}/README.md (100%) rename infrastructure/{authorization => shared}/at21.tfvars (100%) rename infrastructure/{authorization => shared}/at22.tfvars (100%) rename infrastructure/{authorization => shared}/at23.tfvars (100%) rename infrastructure/{authorization => shared}/at24.tfvars (100%) create mode 100644 infrastructure/shared/main.tf rename infrastructure/{authorization => shared}/provider.tf (100%) rename infrastructure/{authorization => shared}/variables.tf (100%) diff --git a/.gitignore b/.gitignore index e4793fbf..be1c78dd 100644 --- a/.gitignore +++ b/.gitignore @@ -23,13 +23,6 @@ nupkg/ crash.log crash.*.log -# Exclude all .tfvars files, which are likely to contain sensitive data, such as -# password, private keys, and other secrets. These should not be part of version -# control as they are data points which are potentially sensitive and subject -# to change depending on the environment. -*.tfvars -*.tfvars.json - # Ignore override files as they are usually used to override resources locally and so # are not checked in override.tf diff --git a/infrastructure/authorization/main.tf b/infrastructure/authorization/main.tf deleted file mode 100644 index 86c1bd78..00000000 --- a/infrastructure/authorization/main.tf +++ /dev/null @@ -1,37 +0,0 @@ -terraform { - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "3.112.0" - } - } - - # backend "azurerm" { - # use_azuread_auth = true - # } -} - - -locals { - environment = lower(var.environment) - metadata = { - solution = "authorization" - environment = local.environment - instance = var.instance - } -} - -resource "azurerm_resource_group" "authorization" { - name = "rg-${local.metadata.environment}-${local.metadata.instance}" - location = "norwayeast" -} - -module "vnet" { - source = "../modules/vnet" - metadata = local.metadata - - cidr = var.cidr - resource_group_name = azurerm_resource_group.authorization.name - - depends_on = [azurerm_resource_group.authorization] -} diff --git a/infrastructure/modules/dns/main.tf b/infrastructure/modules/dns/main.tf new file mode 100644 index 00000000..c8391fd7 --- /dev/null +++ b/infrastructure/modules/dns/main.tf @@ -0,0 +1,34 @@ +locals { + # https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-dns#virtual-network-and-on-premises-workloads-using-a-dns-forwarder + zones = tomap({ + service_bus = "privatelink.servicebus.windows.net" + storage_account_blob = "privatelink.blob.core.windows.net" + postgres = "privatelink.postgres.database.azure.com" + key_vault = "privatelink.vaultcore.azure.net" + app_configuration = "privatelink.azconfig.io" + }) +} + +data "azurerm_resource_group" "dns" { + name = var.resource_group_name +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/dns_zone +resource "azurerm_private_dns_zone" "dns" { + name = each.value + resource_group_name = data.azurerm_resource_group.dns.name + + for_each = local.zones +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone_virtual_network_link +resource "azurerm_private_dns_zone_virtual_network_link" "network" { + name = each.key + private_dns_zone_name = azurerm_private_dns_zone.dns[each.key].name + + virtual_network_id = var.vnet_id + resource_group_name = data.azurerm_resource_group.dns.name + registration_enabled = false + + for_each = local.zones +} diff --git a/infrastructure/modules/dns/outputs.tf b/infrastructure/modules/dns/outputs.tf new file mode 100644 index 00000000..071fb141 --- /dev/null +++ b/infrastructure/modules/dns/outputs.tf @@ -0,0 +1,7 @@ +output "zones" { + value = { for key, value in local.zones : key => + { + id = azurerm_private_dns_zone.dns[key].id + name = value + } } +} diff --git a/infrastructure/modules/dns/variables.tf b/infrastructure/modules/dns/variables.tf new file mode 100644 index 00000000..ddf7bcef --- /dev/null +++ b/infrastructure/modules/dns/variables.tf @@ -0,0 +1,15 @@ +variable "metadata" { + type = object({ + solution = string + environment = string + instance = string + }) +} + +variable "resource_group_name" { + type = string +} + +variable "vnet_id" { + type = string +} diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf new file mode 100644 index 00000000..9346452f --- /dev/null +++ b/infrastructure/modules/key_vault/main.tf @@ -0,0 +1,88 @@ +locals { + +} + +data "azurerm_client_config" "current" {} + +# https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#security +data "azurerm_role_definition" "key_vault_administrator" { + role_definition_id = "00482a5a-887f-4fb3-b363-3b7fe8e74483" +} + +data "azurerm_resource_group" "key_vault" { + name = var.resource_group_name +} + +resource "random_string" "key_vault" { + length = 4 + lower = true + numeric = false + upper = false +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault +resource "azurerm_key_vault" "key_vault" { + name = "kvencryption${random_string.key_vault.result}" + resource_group_name = data.azurerm_resource_group.key_vault.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + location = data.azurerm_resource_group.key_vault.location + enable_rbac_authorization = true + purge_protection_enabled = true + soft_delete_retention_days = 30 + public_network_access_enabled = true + + network_acls { + bypass = "AzureServices" + default_action = "Allow" + } +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment +resource "azurerm_role_assignment" "key_vault_administrator" { + scope = azurerm_key_vault.key_vault.id + principal_id = data.azurerm_client_config.current.object_id + role_definition_name = data.azurerm_role_definition.key_vault_administrator.name +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint +resource "azurerm_private_endpoint" "key_vault" { + name = "pe-${azurerm_key_vault.key_vault.name}" + location = data.azurerm_resource_group.key_vault.location + resource_group_name = data.azurerm_resource_group.key_vault.name + subnet_id = var.subnet_id + custom_network_interface_name = "nic-${azurerm_key_vault.key_vault.name}" + + private_service_connection { + name = azurerm_key_vault.key_vault.name + private_connection_resource_id = azurerm_key_vault.key_vault.id + is_manual_connection = false + subresource_names = ["vault"] + } + + private_dns_zone_group { + name = azurerm_key_vault.key_vault.name + private_dns_zone_ids = var.dns_zones + } +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key +resource "azurerm_key_vault_key" "key_vault" { + name = each.value + key_vault_id = azurerm_key_vault.key_vault.id + key_type = "RSA" + key_size = 2048 + + depends_on = [azurerm_role_assignment.key_vault_administrator] + + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey" + ] + + for_each = var.encryption_keys +} diff --git a/infrastructure/modules/key_vault/outputs.tf b/infrastructure/modules/key_vault/outputs.tf new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/infrastructure/modules/key_vault/outputs.tf @@ -0,0 +1 @@ + diff --git a/infrastructure/modules/key_vault/variables.tf b/infrastructure/modules/key_vault/variables.tf new file mode 100644 index 00000000..5fd93a1c --- /dev/null +++ b/infrastructure/modules/key_vault/variables.tf @@ -0,0 +1,24 @@ +variable "encryption_keys" { + type = map(string) + default = {} +} + +variable "metadata" { + type = object({ + solution = string + environment = string + instance = string + }) +} + +variable "resource_group_name" { + type = string +} + +variable "subnet_id" { + type = string +} + +variable "dns_zones" { + type = list(string) +} diff --git a/infrastructure/modules/nat_gateway/main.tf b/infrastructure/modules/nat_gateway/main.tf new file mode 100644 index 00000000..7c4c9c6f --- /dev/null +++ b/infrastructure/modules/nat_gateway/main.tf @@ -0,0 +1,35 @@ +data "azurerm_resource_group" "nat_gateway" { + name = var.resource_group_name +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway +resource "azurerm_nat_gateway" "nat_gateway" { + name = "natgw-${var.metadata.solution}-${var.metadata.environment}-${var.metadata.instance}" + resource_group_name = data.azurerm_resource_group.nat_gateway.name + location = data.azurerm_resource_group.nat_gateway.location + sku_name = "Standard" + idle_timeout_in_minutes = 4 +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip +resource "azurerm_public_ip" "nat_gateway" { + name = "pip-egress-${var.metadata.solution}-${var.metadata.environment}-${var.metadata.instance}" + resource_group_name = data.azurerm_resource_group.nat_gateway.name + location = data.azurerm_resource_group.nat_gateway.location + sku = "Standard" + allocation_method = "Static" +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway_public_ip_association +resource "azurerm_nat_gateway_public_ip_association" "nat_gateway" { + nat_gateway_id = azurerm_nat_gateway.nat_gateway.id + public_ip_address_id = azurerm_public_ip.nat_gateway.id +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet_nat_gateway_association +resource "azurerm_subnet_nat_gateway_association" "nat_gateway" { + nat_gateway_id = azurerm_nat_gateway.nat_gateway.id + subnet_id = each.value.id + + for_each = var.subnets +} diff --git a/infrastructure/modules/nat_gateway/outputs.tf b/infrastructure/modules/nat_gateway/outputs.tf new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/modules/nat_gateway/variables.tf b/infrastructure/modules/nat_gateway/variables.tf new file mode 100644 index 00000000..3f3b47e1 --- /dev/null +++ b/infrastructure/modules/nat_gateway/variables.tf @@ -0,0 +1,18 @@ +variable "metadata" { + type = object({ + solution = string + environment = string + instance = string + }) +} + +variable "resource_group_name" { + type = string +} + +variable "subnets" { + type = map(object({ + id = string + name = string + })) +} diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index 9bc61579..0b9bac04 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -1,23 +1,17 @@ locals { cidr_prefix = tonumber(split("/", var.cidr)[1]) small_subnet = 28 - local.cidr_prefix # Available IPs 11 - medium_subnet = 26 - local.cidr_prefix # Available IPs 59 + medium_subnet = 26 - local.cidr_prefix # Available IPs IPs 59 large_subnet = 24 - local.cidr_prefix # # Available IPs 251 subnets = { - key_vault = { - bits = local.medium_subnet + application = { + bits = local.large_subnet } - app_configuration = { - bits = local.medium_subnet - } - storage_accounts = { - bits = local.small_subnet - } - redis = { + encryption = { bits = local.small_subnet } - postgres = { + databases = { bits = local.small_subnet delegations = { fs = { diff --git a/infrastructure/modules/vnet/outputs.tf b/infrastructure/modules/vnet/outputs.tf index 5e39d1e0..39473041 100644 --- a/infrastructure/modules/vnet/outputs.tf +++ b/infrastructure/modules/vnet/outputs.tf @@ -1,10 +1,9 @@ -output "vnet" { - value = { - id : azurerm_virtual_network.vnet.id - name = azurerm_virtual_network.vnet.name - } +output "id" { + value = azurerm_virtual_network.vnet.id +} - description = "" +output "name" { + value = azurerm_virtual_network.vnet.name } output "subnets" { diff --git a/infrastructure/authorization/.terraform.lock.hcl b/infrastructure/shared/.terraform.lock.hcl similarity index 53% rename from infrastructure/authorization/.terraform.lock.hcl rename to infrastructure/shared/.terraform.lock.hcl index b76fcebd..7d6804c8 100644 --- a/infrastructure/authorization/.terraform.lock.hcl +++ b/infrastructure/shared/.terraform.lock.hcl @@ -20,3 +20,22 @@ provider "registry.terraform.io/hashicorp/azurerm" { "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.2" + hashes = [ + "h1:wmG0QFjQ2OfyPy6BB7mQ57WtoZZGGV07uAPQeDmIrAE=", + "zh:0ef01a4f81147b32c1bea3429974d4d104bbc4be2ba3cfa667031a8183ef88ec", + "zh:1bcd2d8161e89e39886119965ef0f37fcce2da9c1aca34263dd3002ba05fcb53", + "zh:37c75d15e9514556a5f4ed02e1548aaa95c0ecd6ff9af1119ac905144c70c114", + "zh:4210550a767226976bc7e57d988b9ce48f4411fa8a60cd74a6b246baf7589dad", + "zh:562007382520cd4baa7320f35e1370ffe84e46ed4e2071fdc7e4b1a9b1f8ae9b", + "zh:5efb9da90f665e43f22c2e13e0ce48e86cae2d960aaf1abf721b497f32025916", + "zh:6f71257a6b1218d02a573fc9bff0657410404fb2ef23bc66ae8cd968f98d5ff6", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:9647e18f221380a85f2f0ab387c68fdafd58af6193a932417299cdcae4710150", + "zh:bb6297ce412c3c2fa9fec726114e5e0508dd2638cad6a0cb433194930c97a544", + "zh:f83e925ed73ff8a5ef6e3608ad9225baa5376446349572c2449c0c0b3cf184b7", + "zh:fbef0781cb64de76b1df1ca11078aecba7800d82fd4a956302734999cfd9a4af", + ] +} diff --git a/infrastructure/authorization/README.md b/infrastructure/shared/README.md similarity index 100% rename from infrastructure/authorization/README.md rename to infrastructure/shared/README.md diff --git a/infrastructure/authorization/at21.tfvars b/infrastructure/shared/at21.tfvars similarity index 100% rename from infrastructure/authorization/at21.tfvars rename to infrastructure/shared/at21.tfvars diff --git a/infrastructure/authorization/at22.tfvars b/infrastructure/shared/at22.tfvars similarity index 100% rename from infrastructure/authorization/at22.tfvars rename to infrastructure/shared/at22.tfvars diff --git a/infrastructure/authorization/at23.tfvars b/infrastructure/shared/at23.tfvars similarity index 100% rename from infrastructure/authorization/at23.tfvars rename to infrastructure/shared/at23.tfvars diff --git a/infrastructure/authorization/at24.tfvars b/infrastructure/shared/at24.tfvars similarity index 100% rename from infrastructure/authorization/at24.tfvars rename to infrastructure/shared/at24.tfvars diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf new file mode 100644 index 00000000..a3038b86 --- /dev/null +++ b/infrastructure/shared/main.tf @@ -0,0 +1,79 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "3.112.0" + } + } + + # backend "azurerm" { + # use_azuread_auth = true + # } +} + + +locals { + environment = lower(var.environment) + metadata = { + solution = "shared" + environment = local.environment + instance = var.instance + } +} + +resource "azurerm_resource_group" "authorization" { + name = "rg-${local.metadata.solution}-${local.metadata.environment}-${local.metadata.instance}" + location = "norwayeast" +} + +resource "azurerm_user_assigned_identity" "shared" { + name = "mi-${local.metadata.solution}-${local.metadata.environment}-${local.metadata.instance}" + resource_group_name = azurerm_resource_group.authorization.name + location = azurerm_resource_group.authorization.location +} + +module "vnet" { + source = "../modules/vnet" + resource_group_name = azurerm_resource_group.authorization.name + metadata = local.metadata + + cidr = var.cidr + + depends_on = [azurerm_resource_group.authorization] +} + +module "nat" { + source = "../modules/nat_gateway" + resource_group_name = azurerm_resource_group.authorization.name + metadata = local.metadata + + subnets = module.vnet.subnets + + depends_on = [azurerm_resource_group.authorization] +} + +module "dns" { + source = "../modules/dns" + resource_group_name = azurerm_resource_group.authorization.name + metadata = local.metadata + + vnet_id = module.vnet.id + + depends_on = [azurerm_resource_group.authorization] +} + +module "key_vault" { + source = "../modules/key_vault" + resource_group_name = azurerm_resource_group.authorization.name + metadata = local.metadata + + ###! Changing these deletes and creates new one(s) + encryption_keys = { + service_bus = "ServiceBusEncryptionKey" + } + + dns_zones = [module.dns.zones["key_vault"].id] + subnet_id = module.vnet.subnets["encryption"].id + + depends_on = [azurerm_resource_group.authorization] +} diff --git a/infrastructure/authorization/provider.tf b/infrastructure/shared/provider.tf similarity index 100% rename from infrastructure/authorization/provider.tf rename to infrastructure/shared/provider.tf diff --git a/infrastructure/authorization/variables.tf b/infrastructure/shared/variables.tf similarity index 100% rename from infrastructure/authorization/variables.tf rename to infrastructure/shared/variables.tf From 6afc3c4eb62466863657c8d150f35c104e65ff6a Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Tue, 16 Jul 2024 12:39:29 +0200 Subject: [PATCH 15/26] add network and encryption --- .github/workflows/infrastructure-template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/infrastructure-template.yaml b/.github/workflows/infrastructure-template.yaml index 5d408f83..66a75d7c 100644 --- a/.github/workflows/infrastructure-template.yaml +++ b/.github/workflows/infrastructure-template.yaml @@ -15,7 +15,7 @@ on: env: TF_STATE_NAME: infrastructure.tfstate - WORKING_DIR: ./infrastructure/authorization + WORKING_DIR: ./infrastructure/shared permissions: id-token: write From 8ce58881f20ca3c3e250317d516b92204a9327cb Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 17 Jul 2024 10:39:04 +0200 Subject: [PATCH 16/26] remove unused locals --- infrastructure/modules/dns/outputs.tf | 5 ++++- infrastructure/modules/key_vault/main.tf | 6 ------ infrastructure/shared/main.tf | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/infrastructure/modules/dns/outputs.tf b/infrastructure/modules/dns/outputs.tf index 071fb141..923b93d5 100644 --- a/infrastructure/modules/dns/outputs.tf +++ b/infrastructure/modules/dns/outputs.tf @@ -3,5 +3,8 @@ output "zones" { { id = azurerm_private_dns_zone.dns[key].id name = value - } } + } + } + + description = "Map of all private link DNS zones. The keys are the resource type name. e.g service_bus. Value contains the fields 'id' which is the ARM reference and name the domain" } diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index 9346452f..a52ac473 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -1,9 +1,3 @@ -locals { - -} - -data "azurerm_client_config" "current" {} - # https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#security data "azurerm_role_definition" "key_vault_administrator" { role_definition_id = "00482a5a-887f-4fb3-b363-3b7fe8e74483" diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf index a3038b86..a0fabde5 100644 --- a/infrastructure/shared/main.tf +++ b/infrastructure/shared/main.tf @@ -67,7 +67,7 @@ module "key_vault" { resource_group_name = azurerm_resource_group.authorization.name metadata = local.metadata - ###! Changing these deletes and creates new one(s) + ###! Changing key or value deletes and creates a new one! encryption_keys = { service_bus = "ServiceBusEncryptionKey" } From acd4b90e4f4d90d81760fc81979cfd66ab71e2bc Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 17 Jul 2024 10:51:03 +0200 Subject: [PATCH 17/26] add client config to key vault module --- infrastructure/modules/key_vault/main.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index a52ac473..4a0fadc9 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -1,3 +1,5 @@ +data "azurerm_client_config" "current" {} + # https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#security data "azurerm_role_definition" "key_vault_administrator" { role_definition_id = "00482a5a-887f-4fb3-b363-3b7fe8e74483" From bdd26f1455ee3141b479e41961853b56cceb6d0c Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 17 Jul 2024 12:06:34 +0200 Subject: [PATCH 18/26] update key vault suffix name --- infrastructure/modules/key_vault/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index 4a0fadc9..f2923da8 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -9,7 +9,7 @@ data "azurerm_resource_group" "key_vault" { name = var.resource_group_name } -resource "random_string" "key_vault" { +resource "random_string" "key_vault_name_prefix" { length = 4 lower = true numeric = false @@ -18,7 +18,7 @@ resource "random_string" "key_vault" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault resource "azurerm_key_vault" "key_vault" { - name = "kvencryption${random_string.key_vault.result}" + name = "kvencryption${random_string.key_vault_name_prefix.result}" resource_group_name = data.azurerm_resource_group.key_vault.name tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "standard" From 4a41c18bee2558f34e38ba6fed42de443a632ebf Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 17 Jul 2024 13:10:50 +0200 Subject: [PATCH 19/26] remove single managed identity from main.tf --- infrastructure/shared/main.tf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf index a0fabde5..81dea8f8 100644 --- a/infrastructure/shared/main.tf +++ b/infrastructure/shared/main.tf @@ -26,12 +26,6 @@ resource "azurerm_resource_group" "authorization" { location = "norwayeast" } -resource "azurerm_user_assigned_identity" "shared" { - name = "mi-${local.metadata.solution}-${local.metadata.environment}-${local.metadata.instance}" - resource_group_name = azurerm_resource_group.authorization.name - location = azurerm_resource_group.authorization.location -} - module "vnet" { source = "../modules/vnet" resource_group_name = azurerm_resource_group.authorization.name From 6acd66473ea9c2126149dcfa41bd86a2543a8004 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 17 Jul 2024 14:01:17 +0200 Subject: [PATCH 20/26] rewrite subnets from map to list --- infrastructure/modules/key_vault/main.tf | 1 + infrastructure/modules/vnet/main.tf | 29 ++++++++++++------------ infrastructure/modules/vnet/outputs.tf | 7 +++--- infrastructure/shared/main.tf | 6 ++++- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index f2923da8..31c48362 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -14,6 +14,7 @@ resource "random_string" "key_vault_name_prefix" { lower = true numeric = false upper = false + special = false } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index 0b9bac04..b217e68f 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -1,17 +1,18 @@ locals { - cidr_prefix = tonumber(split("/", var.cidr)[1]) + cidr_prefix = tonumber(split("/", var.cidr)[1]) + small_subnet = 28 - local.cidr_prefix # Available IPs 11 medium_subnet = 26 - local.cidr_prefix # Available IPs IPs 59 - large_subnet = 24 - local.cidr_prefix # # Available IPs 251 + large_subnet = 24 - local.cidr_prefix # Available IPs 251 - subnets = { - application = { + ###! Important to not change order or resize subnets once created and resource are allocated to the network + subnets = [ + { + name : "default" bits = local.large_subnet - } - encryption = { - bits = local.small_subnet - } - databases = { + }, + { + name : "postgres" bits = local.small_subnet delegations = { fs = { @@ -22,7 +23,7 @@ locals { } } } - } + ] } data "azurerm_resource_group" "vnet" { @@ -39,9 +40,9 @@ resource "azurerm_virtual_network" "vnet" { module "subnet" { source = "hashicorp/subnets/cidr" base_cidr_block = var.cidr - networks = [for key, value in local.subnets : { - name = key - new_bits = value.bits + networks = [for subnet in local.subnets : { + name = subnet.name + new_bits = subnet.bits }] } @@ -63,5 +64,5 @@ resource "azurerm_subnet" "vnet" { for_each = try(each.value.delegations, {}) } - for_each = local.subnets + for_each = { for subnet in local.subnets : subnet.name => subnet } } diff --git a/infrastructure/modules/vnet/outputs.tf b/infrastructure/modules/vnet/outputs.tf index 39473041..ccddb115 100644 --- a/infrastructure/modules/vnet/outputs.tf +++ b/infrastructure/modules/vnet/outputs.tf @@ -7,10 +7,11 @@ output "name" { } output "subnets" { - value = { for key, value in local.subnets : key => + value = { for subnet in local.subnets : subnet.name => { - id = azurerm_subnet.vnet[key].id - name = azurerm_subnet.vnet[key].name + id = azurerm_subnet.vnet[subnet.name].id + name = azurerm_subnet.vnet[subnet.name].name + address_space = azurerm_subnet.vnet[subnet.name].address_space } } diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf index 81dea8f8..5b77047d 100644 --- a/infrastructure/shared/main.tf +++ b/infrastructure/shared/main.tf @@ -67,7 +67,11 @@ module "key_vault" { } dns_zones = [module.dns.zones["key_vault"].id] - subnet_id = module.vnet.subnets["encryption"].id + subnet_id = module.vnet.subnets["default"].id depends_on = [azurerm_resource_group.authorization] } + +output "subnets" { + value = module.vnet.subnets +} From 818e66202ffbeab38270197e47033c9fbe26947a Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 17 Jul 2024 14:25:21 +0200 Subject: [PATCH 21/26] update output for vnet module --- infrastructure/modules/vnet/outputs.tf | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/infrastructure/modules/vnet/outputs.tf b/infrastructure/modules/vnet/outputs.tf index ccddb115..3045b14e 100644 --- a/infrastructure/modules/vnet/outputs.tf +++ b/infrastructure/modules/vnet/outputs.tf @@ -1,19 +1,32 @@ output "id" { - value = azurerm_virtual_network.vnet.id + value = azurerm_virtual_network.vnet.id + description = "Vnet ID" } output "name" { - value = azurerm_virtual_network.vnet.name + value = azurerm_virtual_network.vnet.name + description = "Vnet name" } + +# { +# postgres : { +# id = /subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/virtualNetworks/{vnet_name}/subnets/postgres +# name = postgres +# address_prefixes = [ +# "10.202.1.0/28" +# ] +# } +# ... +# } output "subnets" { value = { for subnet in local.subnets : subnet.name => { - id = azurerm_subnet.vnet[subnet.name].id - name = azurerm_subnet.vnet[subnet.name].name - address_space = azurerm_subnet.vnet[subnet.name].address_space + id = azurerm_subnet.vnet[subnet.name].id + name = azurerm_subnet.vnet[subnet.name].name + address_prefixes = [module.subnet.networks[index(module.subnet.networks.*.name, subnet.name)].cidr_block] } } - description = "" + description = "Dynamic object containing subnet name(s) as fields and objects with fields subnet id, name and address_prefixes" } From 1714b02f6aacfe3fb06b29c9395d3c421ee5e86c Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Fri, 19 Jul 2024 12:18:52 +0200 Subject: [PATCH 22/26] add initital postgres server setup and service bus --- infrastructure/modules/dns/variables.tf | 8 +- infrastructure/modules/key_vault/main.tf | 33 ++--- infrastructure/modules/key_vault/outputs.tf | 5 +- infrastructure/modules/key_vault/variables.tf | 17 +-- infrastructure/modules/nat_gateway/main.tf | 4 +- infrastructure/modules/nat_gateway/outputs.tf | 3 + .../modules/nat_gateway/variables.tf | 8 +- .../modules/postgres_database/main.tf | 22 ++++ .../modules/postgres_database/variables.tf | 13 ++ .../modules/postgres_server/main.tf | 89 ++++++++++++++ .../modules/postgres_server/variables.tf | 41 +++++++ infrastructure/modules/service_bus/main.tf | 114 ++++++++++++++++++ infrastructure/modules/service_bus/outputs.tf | 3 + .../modules/service_bus/variables.tf | 35 ++++++ infrastructure/modules/vnet/main.tf | 9 +- infrastructure/modules/vnet/variables.tf | 8 +- infrastructure/shared/at21.tfvars | 3 +- infrastructure/shared/at22.tfvars | 3 +- infrastructure/shared/at23.tfvars | 3 +- infrastructure/shared/at24.tfvars | 3 +- infrastructure/shared/main.tf | 47 ++++++-- infrastructure/shared/variables.tf | 2 +- 22 files changed, 408 insertions(+), 65 deletions(-) create mode 100644 infrastructure/modules/postgres_database/main.tf create mode 100644 infrastructure/modules/postgres_database/variables.tf create mode 100644 infrastructure/modules/postgres_server/main.tf create mode 100644 infrastructure/modules/postgres_server/variables.tf create mode 100644 infrastructure/modules/service_bus/main.tf create mode 100644 infrastructure/modules/service_bus/outputs.tf create mode 100644 infrastructure/modules/service_bus/variables.tf diff --git a/infrastructure/modules/dns/variables.tf b/infrastructure/modules/dns/variables.tf index ddf7bcef..9e23f7e2 100644 --- a/infrastructure/modules/dns/variables.tf +++ b/infrastructure/modules/dns/variables.tf @@ -1,8 +1,10 @@ variable "metadata" { type = object({ - solution = string - environment = string - instance = string + name = string + environment = string + instance = string + suffix = string + default_tags = map(string) }) } diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index 31c48362..f0df079c 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -19,7 +19,7 @@ resource "random_string" "key_vault_name_prefix" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault resource "azurerm_key_vault" "key_vault" { - name = "kvencryption${random_string.key_vault_name_prefix.result}" + name = "kv${random_string.key_vault_name_prefix.result}${var.metadata.suffix}" resource_group_name = data.azurerm_resource_group.key_vault.name tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "standard" @@ -37,18 +37,19 @@ resource "azurerm_key_vault" "key_vault" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment resource "azurerm_role_assignment" "key_vault_administrator" { - scope = azurerm_key_vault.key_vault.id - principal_id = data.azurerm_client_config.current.object_id - role_definition_name = data.azurerm_role_definition.key_vault_administrator.name + scope = azurerm_key_vault.key_vault.id + principal_id = data.azurerm_client_config.current.object_id + role_definition_name = data.azurerm_role_definition.key_vault_administrator.name + skip_service_principal_aad_check = true } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint resource "azurerm_private_endpoint" "key_vault" { - name = "pe-${azurerm_key_vault.key_vault.name}" + name = "pe${azurerm_key_vault.key_vault.name}" location = data.azurerm_resource_group.key_vault.location resource_group_name = data.azurerm_resource_group.key_vault.name subnet_id = var.subnet_id - custom_network_interface_name = "nic-${azurerm_key_vault.key_vault.name}" + custom_network_interface_name = "nic${azurerm_key_vault.key_vault.name}" private_service_connection { name = azurerm_key_vault.key_vault.name @@ -63,23 +64,3 @@ resource "azurerm_private_endpoint" "key_vault" { } } -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key -resource "azurerm_key_vault_key" "key_vault" { - name = each.value - key_vault_id = azurerm_key_vault.key_vault.id - key_type = "RSA" - key_size = 2048 - - depends_on = [azurerm_role_assignment.key_vault_administrator] - - key_opts = [ - "decrypt", - "encrypt", - "sign", - "unwrapKey", - "verify", - "wrapKey" - ] - - for_each = var.encryption_keys -} diff --git a/infrastructure/modules/key_vault/outputs.tf b/infrastructure/modules/key_vault/outputs.tf index 8b137891..67e0920f 100644 --- a/infrastructure/modules/key_vault/outputs.tf +++ b/infrastructure/modules/key_vault/outputs.tf @@ -1 +1,4 @@ - +output "id" { + value = azurerm_key_vault.key_vault.id + description = "value" +} diff --git a/infrastructure/modules/key_vault/variables.tf b/infrastructure/modules/key_vault/variables.tf index 5fd93a1c..89dc3cb3 100644 --- a/infrastructure/modules/key_vault/variables.tf +++ b/infrastructure/modules/key_vault/variables.tf @@ -1,15 +1,18 @@ +variable "metadata" { + type = object({ + name = string + environment = string + instance = string + suffix = string + default_tags = map(string) + }) +} + variable "encryption_keys" { type = map(string) default = {} } -variable "metadata" { - type = object({ - solution = string - environment = string - instance = string - }) -} variable "resource_group_name" { type = string diff --git a/infrastructure/modules/nat_gateway/main.tf b/infrastructure/modules/nat_gateway/main.tf index 7c4c9c6f..f5da9d39 100644 --- a/infrastructure/modules/nat_gateway/main.tf +++ b/infrastructure/modules/nat_gateway/main.tf @@ -4,7 +4,7 @@ data "azurerm_resource_group" "nat_gateway" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway resource "azurerm_nat_gateway" "nat_gateway" { - name = "natgw-${var.metadata.solution}-${var.metadata.environment}-${var.metadata.instance}" + name = "natgw${var.metadata.suffix}" resource_group_name = data.azurerm_resource_group.nat_gateway.name location = data.azurerm_resource_group.nat_gateway.location sku_name = "Standard" @@ -13,7 +13,7 @@ resource "azurerm_nat_gateway" "nat_gateway" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip resource "azurerm_public_ip" "nat_gateway" { - name = "pip-egress-${var.metadata.solution}-${var.metadata.environment}-${var.metadata.instance}" + name = "pipegress${var.metadata.suffix}" resource_group_name = data.azurerm_resource_group.nat_gateway.name location = data.azurerm_resource_group.nat_gateway.location sku = "Standard" diff --git a/infrastructure/modules/nat_gateway/outputs.tf b/infrastructure/modules/nat_gateway/outputs.tf index e69de29b..f4bb9a49 100644 --- a/infrastructure/modules/nat_gateway/outputs.tf +++ b/infrastructure/modules/nat_gateway/outputs.tf @@ -0,0 +1,3 @@ +output "ip" { + value = azurerm_public_ip.nat_gateway.ip_address +} diff --git a/infrastructure/modules/nat_gateway/variables.tf b/infrastructure/modules/nat_gateway/variables.tf index 3f3b47e1..6bcbdec4 100644 --- a/infrastructure/modules/nat_gateway/variables.tf +++ b/infrastructure/modules/nat_gateway/variables.tf @@ -1,8 +1,10 @@ variable "metadata" { type = object({ - solution = string - environment = string - instance = string + name = string + environment = string + instance = string + suffix = string + default_tags = map(string) }) } diff --git a/infrastructure/modules/postgres_database/main.tf b/infrastructure/modules/postgres_database/main.tf new file mode 100644 index 00000000..db3a1249 --- /dev/null +++ b/infrastructure/modules/postgres_database/main.tf @@ -0,0 +1,22 @@ + + +data "azurerm_resource_group" "postgres_database" { + name = var.resource_group_name +} + +data "azurerm_postgresql_flexible_server" "postgres_database" { + name = var.postgres_server_name + resource_group_name = data.azurerm_resource_group.postgres_database.name +} + +resource "azurerm_postgresql_flexible_server_database" "postgres_database" { + name = var.database_name + server_id = azurerm_postgresql_flexible_server.postgres_database.id + collation = "en_US.utf8" + charset = "utf8" + + # prevent the possibility of accidental data loss + lifecycle { + prevent_destroy = true + } +} diff --git a/infrastructure/modules/postgres_database/variables.tf b/infrastructure/modules/postgres_database/variables.tf new file mode 100644 index 00000000..e6e83684 --- /dev/null +++ b/infrastructure/modules/postgres_database/variables.tf @@ -0,0 +1,13 @@ + +variable "resource_group_name" { + type = string +} + +variable "postgres_server_name" { + type = string +} + +variable "database_name" { + type = string + nullable = false +} diff --git a/infrastructure/modules/postgres_server/main.tf b/infrastructure/modules/postgres_server/main.tf new file mode 100644 index 00000000..a0c93517 --- /dev/null +++ b/infrastructure/modules/postgres_server/main.tf @@ -0,0 +1,89 @@ +data "azurerm_client_config" "current" {} + +data "azurerm_resource_group" "postgres_server" { + name = var.resource_group_name +} + +# https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#security +data "azurerm_role_definition" "key_vault_crypto_officer" { + role_definition_id = "14b46e9e-c2b7-41b4-b07b-48a6ebf60603" +} + + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity +resource "azurerm_user_assigned_identity" "postgres_server" { + name = "mipsqlsrv${var.metadata.suffix}" + resource_group_name = data.azurerm_resource_group.postgres_server.name + location = data.azurerm_resource_group.postgres_server.location +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment +resource "azurerm_role_assignment" "key_vault_crypto_officer" { + scope = var.key_vault_id + principal_id = azurerm_user_assigned_identity.postgres_server.principal_id + role_definition_name = data.azurerm_role_definition.key_vault_crypto_officer.name + skip_service_principal_aad_check = true +} + +resource "azurerm_postgresql_flexible_server" "postgres_server" { + name = "psqlsrv${var.metadata.suffix}" + resource_group_name = data.azurerm_resource_group.postgres_server.name + location = data.azurerm_resource_group.postgres_server.location + version = var.postgres_version + + delegated_subnet_id = var.subnet_id + private_dns_zone_id = var.dns_zone + public_network_access_enabled = false + + administrator_login = "psqladmin" + administrator_password = random_password.administrator_password.result + zone = "1" + + storage_mb = var.storage_mb + auto_grow_enabled = true + + authentication { + active_directory_auth_enabled = true + password_auth_enabled = true + tenant_id = data.azurerm_client_config.current.tenant_id + } + + customer_managed_key { + key_vault_key_id = azurerm_key_vault_key.postgres_server.id + primary_user_assigned_identity_id = azurerm_user_assigned_identity.postgres_server.id + } + + identity { + identity_ids = [azurerm_user_assigned_identity.postgres_server.id] + type = "UserAssigned" + } + + storage_tier = "P30" + sku_name = "GP_Standard_D4s_v3" +} + +# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password +resource "random_password" "administrator_password" { + length = 30 +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret +resource "azurerm_key_vault_secret" "administrator_password" { + name = "Postgres--AdminPassword" + content_type = "text/plain" + key_vault_id = var.key_vault_id + value = random_password.administrator_password.result +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key +resource "azurerm_key_vault_key" "postgres_server" { + name = "Postgres" + key_vault_id = var.key_vault_id + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "unwrapKey", + "wrapKey" + ] +} diff --git a/infrastructure/modules/postgres_server/variables.tf b/infrastructure/modules/postgres_server/variables.tf new file mode 100644 index 00000000..1f0f3065 --- /dev/null +++ b/infrastructure/modules/postgres_server/variables.tf @@ -0,0 +1,41 @@ + +variable "metadata" { + type = object({ + name = string + environment = string + instance = string + suffix = string + default_tags = map(string) + }) +} + +variable "resource_group_name" { + type = string +} + +variable "key_vault_id" { + type = string +} + +variable "subnet_id" { + type = string +} + +variable "dns_zone" { + type = string +} + +variable "postgres_version" { + default = "12" + type = string +} + +variable "storage_mb" { + default = 32768 + type = number + validation { + condition = contains([32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4193280, 4194304, 8388608, 16777216, 33553408], var.storage_mb) + error_message = "possible values for 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4193280, 4194304, 8388608, 16777216, 33553408" + } +} + diff --git a/infrastructure/modules/service_bus/main.tf b/infrastructure/modules/service_bus/main.tf new file mode 100644 index 00000000..d52e4173 --- /dev/null +++ b/infrastructure/modules/service_bus/main.tf @@ -0,0 +1,114 @@ +# NOTES +# * You only see the Networking tab for premium namespaces. To set IP firewall rules for the other tiers, use Azure Resource Manager templates, Azure CLI, PowerShell or REST API. +# * Private endpoint and CMK encryption are only available in Premium SKU +# * Capacity and Partitions are only allowed to set if SKU is premium +# * Using User Assigned Identity due to problematic execution order for System assigned identity and enabling CMK encryption + +locals { + service_bus_enable_public_endpoint = !var.is_prod_like + service_bus_sku = var.is_prod_like ? "Premium" : "Standard" + service_bus_enable_local_auth = !var.is_prod_like + service_bus_enable_private_endpoint = var.is_prod_like # Only avaiable for Premium tier + service_bus_enable_encryption_at_rest = var.is_prod_like # Only avaiable for Premium tier + service_bus_capacity = var.is_prod_like ? 1 : 0 # Only avaiable for Premium tier + service_bus_premium_messaging_partitions = var.is_prod_like ? 1 : 0 # Only avaiable for Premium tier +} + +data "azurerm_resource_group" "service_bus" { + name = var.resource_group_name +} + +# https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#security +data "azurerm_role_definition" "key_vault_crypto_officer" { + role_definition_id = "14b46e9e-c2b7-41b4-b07b-48a6ebf60603" +} + + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity +resource "azurerm_user_assigned_identity" "service_bus" { + name = "misb${var.metadata.suffix}" + resource_group_name = data.azurerm_resource_group.service_bus.name + location = data.azurerm_resource_group.service_bus.location +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment +resource "azurerm_role_assignment" "key_vault_crypto_officer" { + scope = var.key_vault_id + principal_id = azurerm_user_assigned_identity.service_bus.principal_id + role_definition_name = data.azurerm_role_definition.key_vault_crypto_officer.name + skip_service_principal_aad_check = true +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key +resource "azurerm_key_vault_key" "service_bus" { + name = "ServiceBus" + key_vault_id = var.key_vault_id + key_type = "RSA" + key_size = 2048 + + count = local.service_bus_enable_private_endpoint ? 1 : 0 + + key_opts = [ + "unwrapKey", + "wrapKey" + ] +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/servicebus_namespace +resource "azurerm_servicebus_namespace" "service_bus" { + name = "sb${var.metadata.suffix}" + resource_group_name = data.azurerm_resource_group.service_bus.name + location = data.azurerm_resource_group.service_bus.location + sku = local.service_bus_sku + local_auth_enabled = local.service_bus_enable_local_auth + capacity = local.service_bus_capacity + premium_messaging_partitions = local.service_bus_premium_messaging_partitions + + dynamic "customer_managed_key" { + content { + infrastructure_encryption_enabled = true + identity_id = azurerm_user_assigned_identity.service_bus.id + key_vault_key_id = azurerm_key_vault_key.service_bus[0].id + } + + for_each = local.service_bus_enable_encryption_at_rest ? [1] : [] + } + + network_rule_set { + default_action = "Deny" + public_network_access_enabled = local.service_bus_enable_public_endpoint + ip_rules = var.permitted_ip_addresses + trusted_services_allowed = true + } + + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.service_bus.id] + } + + depends_on = [azurerm_role_assignment.key_vault_crypto_officer] +} + +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint +resource "azurerm_private_endpoint" "service_bus_private_endpoint" { + name = "pe${azurerm_servicebus_namespace.service_bus.name}" + location = data.azurerm_resource_group.service_bus.location + resource_group_name = data.azurerm_resource_group.service_bus.name + subnet_id = var.subnet_id + custom_network_interface_name = "nic${azurerm_servicebus_namespace.service_bus.name}" + + count = local.service_bus_enable_private_endpoint ? 1 : 0 + + private_service_connection { + name = azurerm_servicebus_namespace.service_bus.name + private_connection_resource_id = azurerm_servicebus_namespace.service_bus.id + is_manual_connection = false + subresource_names = ["namespace"] + } + + private_dns_zone_group { + name = azurerm_servicebus_namespace.service_bus.name + private_dns_zone_ids = var.dns_zones + } +} + diff --git a/infrastructure/modules/service_bus/outputs.tf b/infrastructure/modules/service_bus/outputs.tf new file mode 100644 index 00000000..5c504601 --- /dev/null +++ b/infrastructure/modules/service_bus/outputs.tf @@ -0,0 +1,3 @@ +output "id" { + value = azurerm_servicebus_namespace.service_bus.id +} diff --git a/infrastructure/modules/service_bus/variables.tf b/infrastructure/modules/service_bus/variables.tf new file mode 100644 index 00000000..0a91de8d --- /dev/null +++ b/infrastructure/modules/service_bus/variables.tf @@ -0,0 +1,35 @@ +variable "metadata" { + type = object({ + name = string + environment = string + instance = string + suffix = string + default_tags = map(string) + }) +} + +variable "subnet_id" { + type = string +} + +variable "dns_zones" { + type = list(string) +} + +variable "key_vault_id" { + type = string +} + +variable "resource_group_name" { + type = string +} + +variable "is_prod_like" { + default = true +} + +variable "permitted_ip_addresses" { + default = [] + type = set(string) + sensitive = true +} diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index b217e68f..b55fa76e 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -2,10 +2,11 @@ locals { cidr_prefix = tonumber(split("/", var.cidr)[1]) small_subnet = 28 - local.cidr_prefix # Available IPs 11 - medium_subnet = 26 - local.cidr_prefix # Available IPs IPs 59 - large_subnet = 24 - local.cidr_prefix # Available IPs 251 + medium_subnet = 25 - local.cidr_prefix # Available IPs IPs 123 + large_subnet = 23 - local.cidr_prefix # Available IPs 507 - ###! Important to not change order or resize subnets once created and resource are allocated to the network + ###! Important to not change order or resize subnets once created and resource are allocated to the network. + ###! For adding new subnets, append object only to the end of list. subnets = [ { name : "default" @@ -31,7 +32,7 @@ data "azurerm_resource_group" "vnet" { } resource "azurerm_virtual_network" "vnet" { - name = "vnet-${var.metadata.solution}-${var.metadata.environment}-${var.metadata.instance}" + name = "vnet${var.metadata.suffix}" address_space = [var.cidr] location = data.azurerm_resource_group.vnet.location resource_group_name = data.azurerm_resource_group.vnet.name diff --git a/infrastructure/modules/vnet/variables.tf b/infrastructure/modules/vnet/variables.tf index 5e20c5dc..027f8069 100644 --- a/infrastructure/modules/vnet/variables.tf +++ b/infrastructure/modules/vnet/variables.tf @@ -1,8 +1,10 @@ variable "metadata" { type = object({ - solution = string - environment = string - instance = string + name = string + environment = string + instance = string + suffix = string + default_tags = map(string) }) } diff --git a/infrastructure/shared/at21.tfvars b/infrastructure/shared/at21.tfvars index bd9513ef..3dcb2077 100644 --- a/infrastructure/shared/at21.tfvars +++ b/infrastructure/shared/at21.tfvars @@ -1 +1,2 @@ -cidr = "10.202.0.0/22" +environment = "at21" +cidr = "10.202.0.0/22" diff --git a/infrastructure/shared/at22.tfvars b/infrastructure/shared/at22.tfvars index bd9513ef..6a4cac14 100644 --- a/infrastructure/shared/at22.tfvars +++ b/infrastructure/shared/at22.tfvars @@ -1 +1,2 @@ -cidr = "10.202.0.0/22" +cidr = "10.202.0.0/22" +environment = "at22" diff --git a/infrastructure/shared/at23.tfvars b/infrastructure/shared/at23.tfvars index bd9513ef..bf6ea1d1 100644 --- a/infrastructure/shared/at23.tfvars +++ b/infrastructure/shared/at23.tfvars @@ -1 +1,2 @@ -cidr = "10.202.0.0/22" +cidr = "10.202.0.0/22" +environment = "at23" diff --git a/infrastructure/shared/at24.tfvars b/infrastructure/shared/at24.tfvars index bd9513ef..ad4b2d06 100644 --- a/infrastructure/shared/at24.tfvars +++ b/infrastructure/shared/at24.tfvars @@ -1 +1,2 @@ -cidr = "10.202.0.0/22" +cidr = "10.202.0.0/22" +environment = "at24" diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf index 5b77047d..7d282649 100644 --- a/infrastructure/shared/main.tf +++ b/infrastructure/shared/main.tf @@ -4,6 +4,10 @@ terraform { source = "hashicorp/azurerm" version = "3.112.0" } + random = { + source = "hashicorp/random" + version = ">= 3.4.0" + } } # backend "azurerm" { @@ -11,19 +15,25 @@ terraform { # } } - locals { + repository = "github.com/altinn/altinn-authorization" environment = lower(var.environment) + name = "shared" + metadata = { - solution = "shared" + name = local.name environment = local.environment instance = var.instance + suffix = "${local.name}${var.instance}${var.environment}" + default_tags = { + repository = local.repository + } } } resource "azurerm_resource_group" "authorization" { - name = "rg-${local.metadata.solution}-${local.metadata.environment}-${local.metadata.instance}" - location = "norwayeast" + name = "rg${local.metadata.suffix}" + location = var.location } module "vnet" { @@ -61,17 +71,32 @@ module "key_vault" { resource_group_name = azurerm_resource_group.authorization.name metadata = local.metadata - ###! Changing key or value deletes and creates a new one! - encryption_keys = { - service_bus = "ServiceBusEncryptionKey" - } - dns_zones = [module.dns.zones["key_vault"].id] subnet_id = module.vnet.subnets["default"].id depends_on = [azurerm_resource_group.authorization] } -output "subnets" { - value = module.vnet.subnets +module "service_bus" { + source = "../modules/service_bus" + resource_group_name = azurerm_resource_group.authorization.name + metadata = local.metadata + + is_prod_like = true + key_vault_id = module.key_vault.id + dns_zones = [module.dns.zones["service_bus"].id] + subnet_id = module.vnet.subnets["default"].id + permitted_ip_addresses = [module.nat.ip] + + depends_on = [azurerm_resource_group.authorization] +} + +module "postgres_server" { + source = "../modules/postgres_server" + resource_group_name = azurerm_resource_group.authorization.name + metadata = local.metadata + + dns_zone = module.dns.zones["postgres"].id + key_vault_id = module.key_vault.id + subnet_id = module.vnet.subnets["postgres"].id } diff --git a/infrastructure/shared/variables.tf b/infrastructure/shared/variables.tf index 69d82d0b..2886339a 100644 --- a/infrastructure/shared/variables.tf +++ b/infrastructure/shared/variables.tf @@ -5,7 +5,7 @@ variable "location" { variable "instance" { type = string - default = "001" + default = "002" } variable "environment" { From 2bcd85405cf63074427a5e30d8807c0a8d9d0c26 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Fri, 19 Jul 2024 12:44:24 +0200 Subject: [PATCH 23/26] remove unused variable --- infrastructure/modules/key_vault/variables.tf | 6 ------ 1 file changed, 6 deletions(-) diff --git a/infrastructure/modules/key_vault/variables.tf b/infrastructure/modules/key_vault/variables.tf index 89dc3cb3..f91b8296 100644 --- a/infrastructure/modules/key_vault/variables.tf +++ b/infrastructure/modules/key_vault/variables.tf @@ -8,12 +8,6 @@ variable "metadata" { }) } -variable "encryption_keys" { - type = map(string) - default = {} -} - - variable "resource_group_name" { type = string } From 73dee311b0d43905284ccadf1140589887664a07 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Mon, 22 Jul 2024 12:06:25 +0200 Subject: [PATCH 24/26] add state and remove unused params --- infrastructure/modules/key_vault/main.tf | 7 +++--- .../modules/postgres_server/main.tf | 22 +++---------------- infrastructure/shared/main.tf | 10 +++++---- infrastructure/shared/variables.tf | 2 +- 4 files changed, 13 insertions(+), 28 deletions(-) diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index f0df079c..c2b2d32a 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -37,10 +37,9 @@ resource "azurerm_key_vault" "key_vault" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment resource "azurerm_role_assignment" "key_vault_administrator" { - scope = azurerm_key_vault.key_vault.id - principal_id = data.azurerm_client_config.current.object_id - role_definition_name = data.azurerm_role_definition.key_vault_administrator.name - skip_service_principal_aad_check = true + scope = azurerm_key_vault.key_vault.id + principal_id = data.azurerm_client_config.current.object_id + role_definition_name = data.azurerm_role_definition.key_vault_administrator.name } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint diff --git a/infrastructure/modules/postgres_server/main.tf b/infrastructure/modules/postgres_server/main.tf index a0c93517..d4460346 100644 --- a/infrastructure/modules/postgres_server/main.tf +++ b/infrastructure/modules/postgres_server/main.tf @@ -9,7 +9,6 @@ data "azurerm_role_definition" "key_vault_crypto_officer" { role_definition_id = "14b46e9e-c2b7-41b4-b07b-48a6ebf60603" } - # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity resource "azurerm_user_assigned_identity" "postgres_server" { name = "mipsqlsrv${var.metadata.suffix}" @@ -25,6 +24,7 @@ resource "azurerm_role_assignment" "key_vault_crypto_officer" { skip_service_principal_aad_check = true } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server resource "azurerm_postgresql_flexible_server" "postgres_server" { name = "psqlsrv${var.metadata.suffix}" resource_group_name = data.azurerm_resource_group.postgres_server.name @@ -35,16 +35,13 @@ resource "azurerm_postgresql_flexible_server" "postgres_server" { private_dns_zone_id = var.dns_zone public_network_access_enabled = false - administrator_login = "psqladmin" - administrator_password = random_password.administrator_password.result - zone = "1" - + zone = "1" storage_mb = var.storage_mb auto_grow_enabled = true authentication { active_directory_auth_enabled = true - password_auth_enabled = true + password_auth_enabled = false tenant_id = data.azurerm_client_config.current.tenant_id } @@ -62,19 +59,6 @@ resource "azurerm_postgresql_flexible_server" "postgres_server" { sku_name = "GP_Standard_D4s_v3" } -# https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password -resource "random_password" "administrator_password" { - length = 30 -} - -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_secret -resource "azurerm_key_vault_secret" "administrator_password" { - name = "Postgres--AdminPassword" - content_type = "text/plain" - key_vault_id = var.key_vault_id - value = random_password.administrator_password.result -} - # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key resource "azurerm_key_vault_key" "postgres_server" { name = "Postgres" diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf index 7d282649..d9641533 100644 --- a/infrastructure/shared/main.tf +++ b/infrastructure/shared/main.tf @@ -10,9 +10,9 @@ terraform { } } - # backend "azurerm" { - # use_azuread_auth = true - # } + backend "azurerm" { + use_azuread_auth = true + } } locals { @@ -88,7 +88,7 @@ module "service_bus" { subnet_id = module.vnet.subnets["default"].id permitted_ip_addresses = [module.nat.ip] - depends_on = [azurerm_resource_group.authorization] + depends_on = [azurerm_resource_group.authorization, module.key_vault] } module "postgres_server" { @@ -99,4 +99,6 @@ module "postgres_server" { dns_zone = module.dns.zones["postgres"].id key_vault_id = module.key_vault.id subnet_id = module.vnet.subnets["postgres"].id + + depends_on = [azurerm_resource_group.authorization, module.key_vault] } diff --git a/infrastructure/shared/variables.tf b/infrastructure/shared/variables.tf index 2886339a..69d82d0b 100644 --- a/infrastructure/shared/variables.tf +++ b/infrastructure/shared/variables.tf @@ -5,7 +5,7 @@ variable "location" { variable "instance" { type = string - default = "002" + default = "001" } variable "environment" { From 723789f07d3c9c6244adf56a5bb13b6659fc1b15 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 24 Jul 2024 10:17:43 +0200 Subject: [PATCH 25/26] add masstransit role --- infrastructure/shared/at22.tfvars | 2 +- infrastructure/shared/at23.tfvars | 2 +- infrastructure/shared/at24.tfvars | 2 +- infrastructure/shared/main.tf | 32 +++++++++++++++---------------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/infrastructure/shared/at22.tfvars b/infrastructure/shared/at22.tfvars index 6a4cac14..32e19a54 100644 --- a/infrastructure/shared/at22.tfvars +++ b/infrastructure/shared/at22.tfvars @@ -1,2 +1,2 @@ -cidr = "10.202.0.0/22" environment = "at22" +cidr = "10.202.0.0/22" diff --git a/infrastructure/shared/at23.tfvars b/infrastructure/shared/at23.tfvars index bf6ea1d1..215a9582 100644 --- a/infrastructure/shared/at23.tfvars +++ b/infrastructure/shared/at23.tfvars @@ -1,2 +1,2 @@ -cidr = "10.202.0.0/22" environment = "at23" +cidr = "10.202.0.0/22" diff --git a/infrastructure/shared/at24.tfvars b/infrastructure/shared/at24.tfvars index ad4b2d06..af95c64e 100644 --- a/infrastructure/shared/at24.tfvars +++ b/infrastructure/shared/at24.tfvars @@ -1,2 +1,2 @@ -cidr = "10.202.0.0/22" environment = "at24" +cidr = "10.202.0.0/22" diff --git a/infrastructure/shared/main.tf b/infrastructure/shared/main.tf index d9641533..d72c7959 100644 --- a/infrastructure/shared/main.tf +++ b/infrastructure/shared/main.tf @@ -10,9 +10,9 @@ terraform { } } - backend "azurerm" { - use_azuread_auth = true - } + # backend "azurerm" { + # use_azuread_auth = true + # } } locals { @@ -31,55 +31,55 @@ locals { } } -resource "azurerm_resource_group" "authorization" { +resource "azurerm_resource_group" "shared" { name = "rg${local.metadata.suffix}" location = var.location } module "vnet" { source = "../modules/vnet" - resource_group_name = azurerm_resource_group.authorization.name + resource_group_name = azurerm_resource_group.shared.name metadata = local.metadata cidr = var.cidr - depends_on = [azurerm_resource_group.authorization] + depends_on = [azurerm_resource_group.shared] } module "nat" { source = "../modules/nat_gateway" - resource_group_name = azurerm_resource_group.authorization.name + resource_group_name = azurerm_resource_group.shared.name metadata = local.metadata subnets = module.vnet.subnets - depends_on = [azurerm_resource_group.authorization] + depends_on = [azurerm_resource_group.shared] } module "dns" { source = "../modules/dns" - resource_group_name = azurerm_resource_group.authorization.name + resource_group_name = azurerm_resource_group.shared.name metadata = local.metadata vnet_id = module.vnet.id - depends_on = [azurerm_resource_group.authorization] + depends_on = [azurerm_resource_group.shared] } module "key_vault" { source = "../modules/key_vault" - resource_group_name = azurerm_resource_group.authorization.name + resource_group_name = azurerm_resource_group.shared.name metadata = local.metadata dns_zones = [module.dns.zones["key_vault"].id] subnet_id = module.vnet.subnets["default"].id - depends_on = [azurerm_resource_group.authorization] + depends_on = [azurerm_resource_group.shared] } module "service_bus" { source = "../modules/service_bus" - resource_group_name = azurerm_resource_group.authorization.name + resource_group_name = azurerm_resource_group.shared.name metadata = local.metadata is_prod_like = true @@ -88,17 +88,17 @@ module "service_bus" { subnet_id = module.vnet.subnets["default"].id permitted_ip_addresses = [module.nat.ip] - depends_on = [azurerm_resource_group.authorization, module.key_vault] + depends_on = [azurerm_resource_group.shared, module.key_vault] } module "postgres_server" { source = "../modules/postgres_server" - resource_group_name = azurerm_resource_group.authorization.name + resource_group_name = azurerm_resource_group.shared.name metadata = local.metadata dns_zone = module.dns.zones["postgres"].id key_vault_id = module.key_vault.id subnet_id = module.vnet.subnets["postgres"].id - depends_on = [azurerm_resource_group.authorization, module.key_vault] + depends_on = [azurerm_resource_group.shared, module.key_vault] } From 225e0d10dd236c2d5f75a79b29621096df255b24 Mon Sep 17 00:00:00 2001 From: Andreas Isnes Date: Wed, 24 Jul 2024 10:17:55 +0200 Subject: [PATCH 26/26] add masstransit role --- infrastructure/modules/dns/main.tf | 8 ++-- infrastructure/modules/key_vault/main.tf | 21 +++++---- infrastructure/modules/nat_gateway/main.tf | 10 ++-- .../modules/postgres_database/main.tf | 4 +- .../modules/postgres_server/main.tf | 47 +++++++++++++------ .../modules/postgres_server/outputs.tf | 9 ++++ infrastructure/modules/service_bus/main.tf | 33 +++++++++---- infrastructure/modules/vnet/main.tf | 8 ++-- 8 files changed, 92 insertions(+), 48 deletions(-) create mode 100644 infrastructure/modules/postgres_server/outputs.tf diff --git a/infrastructure/modules/dns/main.tf b/infrastructure/modules/dns/main.tf index c8391fd7..75e55300 100644 --- a/infrastructure/modules/dns/main.tf +++ b/infrastructure/modules/dns/main.tf @@ -9,25 +9,25 @@ locals { }) } -data "azurerm_resource_group" "dns" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/dns_zone resource "azurerm_private_dns_zone" "dns" { name = each.value - resource_group_name = data.azurerm_resource_group.dns.name + resource_group_name = data.azurerm_resource_group.rg.name for_each = local.zones } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone_virtual_network_link -resource "azurerm_private_dns_zone_virtual_network_link" "network" { +resource "azurerm_private_dns_zone_virtual_network_link" "dns" { name = each.key private_dns_zone_name = azurerm_private_dns_zone.dns[each.key].name virtual_network_id = var.vnet_id - resource_group_name = data.azurerm_resource_group.dns.name + resource_group_name = data.azurerm_resource_group.rg.name registration_enabled = false for_each = local.zones diff --git a/infrastructure/modules/key_vault/main.tf b/infrastructure/modules/key_vault/main.tf index c2b2d32a..e0ffea60 100644 --- a/infrastructure/modules/key_vault/main.tf +++ b/infrastructure/modules/key_vault/main.tf @@ -5,7 +5,7 @@ data "azurerm_role_definition" "key_vault_administrator" { role_definition_id = "00482a5a-887f-4fb3-b363-3b7fe8e74483" } -data "azurerm_resource_group" "key_vault" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } @@ -19,13 +19,14 @@ resource "random_string" "key_vault_name_prefix" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault resource "azurerm_key_vault" "key_vault" { - name = "kv${random_string.key_vault_name_prefix.result}${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.key_vault.name - tenant_id = data.azurerm_client_config.current.tenant_id - sku_name = "standard" - location = data.azurerm_resource_group.key_vault.location - enable_rbac_authorization = true - purge_protection_enabled = true + name = "kv${random_string.key_vault_name_prefix.result}${var.metadata.suffix}" + resource_group_name = data.azurerm_resource_group.rg.name + tenant_id = data.azurerm_client_config.current.tenant_id + sku_name = "standard" + location = data.azurerm_resource_group.rg.location + enable_rbac_authorization = true + purge_protection_enabled = true + soft_delete_retention_days = 30 public_network_access_enabled = true @@ -45,8 +46,8 @@ resource "azurerm_role_assignment" "key_vault_administrator" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint resource "azurerm_private_endpoint" "key_vault" { name = "pe${azurerm_key_vault.key_vault.name}" - location = data.azurerm_resource_group.key_vault.location - resource_group_name = data.azurerm_resource_group.key_vault.name + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name subnet_id = var.subnet_id custom_network_interface_name = "nic${azurerm_key_vault.key_vault.name}" diff --git a/infrastructure/modules/nat_gateway/main.tf b/infrastructure/modules/nat_gateway/main.tf index f5da9d39..e5a484a3 100644 --- a/infrastructure/modules/nat_gateway/main.tf +++ b/infrastructure/modules/nat_gateway/main.tf @@ -1,12 +1,12 @@ -data "azurerm_resource_group" "nat_gateway" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nat_gateway resource "azurerm_nat_gateway" "nat_gateway" { name = "natgw${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.nat_gateway.name - location = data.azurerm_resource_group.nat_gateway.location + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location sku_name = "Standard" idle_timeout_in_minutes = 4 } @@ -14,8 +14,8 @@ resource "azurerm_nat_gateway" "nat_gateway" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip resource "azurerm_public_ip" "nat_gateway" { name = "pipegress${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.nat_gateway.name - location = data.azurerm_resource_group.nat_gateway.location + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location sku = "Standard" allocation_method = "Static" } diff --git a/infrastructure/modules/postgres_database/main.tf b/infrastructure/modules/postgres_database/main.tf index db3a1249..74e44f2f 100644 --- a/infrastructure/modules/postgres_database/main.tf +++ b/infrastructure/modules/postgres_database/main.tf @@ -1,12 +1,12 @@ -data "azurerm_resource_group" "postgres_database" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } data "azurerm_postgresql_flexible_server" "postgres_database" { name = var.postgres_server_name - resource_group_name = data.azurerm_resource_group.postgres_database.name + resource_group_name = data.azurerm_resource_group.rg.name } resource "azurerm_postgresql_flexible_server_database" "postgres_database" { diff --git a/infrastructure/modules/postgres_server/main.tf b/infrastructure/modules/postgres_server/main.tf index d4460346..4b7e4221 100644 --- a/infrastructure/modules/postgres_server/main.tf +++ b/infrastructure/modules/postgres_server/main.tf @@ -1,6 +1,6 @@ data "azurerm_client_config" "current" {} -data "azurerm_resource_group" "postgres_server" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } @@ -12,8 +12,8 @@ data "azurerm_role_definition" "key_vault_crypto_officer" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity resource "azurerm_user_assigned_identity" "postgres_server" { name = "mipsqlsrv${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.postgres_server.name - location = data.azurerm_resource_group.postgres_server.location + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment @@ -24,11 +24,24 @@ resource "azurerm_role_assignment" "key_vault_crypto_officer" { skip_service_principal_aad_check = true } +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key +resource "azurerm_key_vault_key" "postgres_server" { + name = "psqlsrv${var.metadata.suffix}" + key_vault_id = var.key_vault_id + key_type = "RSA" + key_size = 2048 + + key_opts = [ + "unwrapKey", + "wrapKey" + ] +} + # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server resource "azurerm_postgresql_flexible_server" "postgres_server" { name = "psqlsrv${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.postgres_server.name - location = data.azurerm_resource_group.postgres_server.location + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location version = var.postgres_version delegated_subnet_id = var.subnet_id @@ -59,15 +72,19 @@ resource "azurerm_postgresql_flexible_server" "postgres_server" { sku_name = "GP_Standard_D4s_v3" } -# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key -resource "azurerm_key_vault_key" "postgres_server" { - name = "Postgres" - key_vault_id = var.key_vault_id - key_type = "RSA" - key_size = 2048 +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity +resource "azurerm_user_assigned_identity" "postgres_server_admin" { + name = "mipsqlsrvadmin${var.metadata.suffix}" + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location +} - key_opts = [ - "unwrapKey", - "wrapKey" - ] +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server_active_directory_administrator +resource "azurerm_postgresql_flexible_server_active_directory_administrator" "admin" { + server_name = azurerm_postgresql_flexible_server.postgres_server.name + resource_group_name = data.azurerm_resource_group.rg.name + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = azurerm_user_assigned_identity.postgres_server_admin.principal_id + principal_name = azurerm_user_assigned_identity.postgres_server_admin.name + principal_type = "ServicePrincipal" } diff --git a/infrastructure/modules/postgres_server/outputs.tf b/infrastructure/modules/postgres_server/outputs.tf new file mode 100644 index 00000000..d0b4489a --- /dev/null +++ b/infrastructure/modules/postgres_server/outputs.tf @@ -0,0 +1,9 @@ +output "id" { + value = azurerm_key_vault_key.postgres_server.id + description = "Postgres Flexible server AzureRM ID" +} + +output "admin" { + value = azurerm_user_assigned_identity.postgres_server_admin.id + description = "Managed Identity AzureRM ID" +} diff --git a/infrastructure/modules/service_bus/main.tf b/infrastructure/modules/service_bus/main.tf index d52e4173..7d805612 100644 --- a/infrastructure/modules/service_bus/main.tf +++ b/infrastructure/modules/service_bus/main.tf @@ -14,7 +14,7 @@ locals { service_bus_premium_messaging_partitions = var.is_prod_like ? 1 : 0 # Only avaiable for Premium tier } -data "azurerm_resource_group" "service_bus" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } @@ -27,8 +27,8 @@ data "azurerm_role_definition" "key_vault_crypto_officer" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/user_assigned_identity resource "azurerm_user_assigned_identity" "service_bus" { name = "misb${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.service_bus.name - location = data.azurerm_resource_group.service_bus.location + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location } # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment @@ -41,7 +41,7 @@ resource "azurerm_role_assignment" "key_vault_crypto_officer" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_key resource "azurerm_key_vault_key" "service_bus" { - name = "ServiceBus" + name = "sb${var.metadata.suffix}" key_vault_id = var.key_vault_id key_type = "RSA" key_size = 2048 @@ -57,8 +57,8 @@ resource "azurerm_key_vault_key" "service_bus" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/servicebus_namespace resource "azurerm_servicebus_namespace" "service_bus" { name = "sb${var.metadata.suffix}" - resource_group_name = data.azurerm_resource_group.service_bus.name - location = data.azurerm_resource_group.service_bus.location + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location sku = local.service_bus_sku local_auth_enabled = local.service_bus_enable_local_auth capacity = local.service_bus_capacity @@ -92,8 +92,8 @@ resource "azurerm_servicebus_namespace" "service_bus" { # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint resource "azurerm_private_endpoint" "service_bus_private_endpoint" { name = "pe${azurerm_servicebus_namespace.service_bus.name}" - location = data.azurerm_resource_group.service_bus.location - resource_group_name = data.azurerm_resource_group.service_bus.name + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name subnet_id = var.subnet_id custom_network_interface_name = "nic${azurerm_servicebus_namespace.service_bus.name}" @@ -112,3 +112,20 @@ resource "azurerm_private_endpoint" "service_bus_private_endpoint" { } } +# Service bus Actions List: https://learn.microsoft.com/en-us/azure/role-based-access-control/permissions/integration#microsoftservicebus +# https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition +resource "azurerm_role_definition" "service_bus_masstransit" { + name = "Azure Service Bus Mass Transit" + scope = azurerm_servicebus_namespace.service_bus.id + description = "Allow C# Applications use MassTransit with Azure Service Bus" + + permissions { + actions = [ + "Microsoft.ServiceBus/namespaces/read", + "Microsoft.ServiceBus/namespaces/queues/*", + "Microsoft.ServiceBus/namespaces/topics/*" + ] + } + + assignable_scopes = [azurerm_servicebus_namespace.service_bus.id] +} diff --git a/infrastructure/modules/vnet/main.tf b/infrastructure/modules/vnet/main.tf index b55fa76e..6bec449e 100644 --- a/infrastructure/modules/vnet/main.tf +++ b/infrastructure/modules/vnet/main.tf @@ -5,7 +5,7 @@ locals { medium_subnet = 25 - local.cidr_prefix # Available IPs IPs 123 large_subnet = 23 - local.cidr_prefix # Available IPs 507 - ###! Important to not change order or resize subnets once created and resource are allocated to the network. + ###! Important to not change order, resize or rename subnets once created and resource are allocated to the network. ###! For adding new subnets, append object only to the end of list. subnets = [ { @@ -27,15 +27,15 @@ locals { ] } -data "azurerm_resource_group" "vnet" { +data "azurerm_resource_group" "rg" { name = var.resource_group_name } resource "azurerm_virtual_network" "vnet" { name = "vnet${var.metadata.suffix}" address_space = [var.cidr] - location = data.azurerm_resource_group.vnet.location - resource_group_name = data.azurerm_resource_group.vnet.name + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name } module "subnet" {