From d7262adf05daeee14dee586d08ddc73641d2dc02 Mon Sep 17 00:00:00 2001 From: Jason Masten Date: Wed, 28 Aug 2024 17:32:57 -0400 Subject: [PATCH] Removed terraform (#1081) * Removed files * Removed terraform references --- .../mlz-tf-azurecloud-pipelines.yml | 37 -- .../mlz-tf-azuregov-pipelines.yml | 35 - .../templates/terraform-apply.yml | 105 --- .../mlz-pr-tf-azurecloud-pipelines.yml | 31 - .../prbuild/mlz-pr-tf-azuregov-pipelines.yml | 31 - .../prbuild/templates/terraform-plan.yml | 51 -- .devcontainer/devcontainer.json | 1 - .github/ISSUE_TEMPLATE/bug_report.md | 1 - .github/workflows/README.md | 71 -- .github/workflows/validate-terraform.sh | 64 -- .github/workflows/validate-terraform.yml | 26 - .gitignore | 28 - .vscode/settings.json | 3 - README.md | 5 +- docs/deployment-guide-terraform.md | 447 ------------- docs/policies.md | 42 -- src/bicep/add-ons/README.md | 1 - src/bicep/add-ons/sentinel/README.md | 99 --- src/bicep/add-ons/sentinel/sentinel.tf | 65 -- .../add-ons/zero-trust-workbook/README.md | 2 +- src/terraform/README.md | 6 - src/terraform/mlz/main.tf | 627 ------------------ src/terraform/mlz/outputs.tf | 37 -- src/terraform/mlz/variables.tf | 603 ----------------- src/terraform/modules/bastion/main.tf | 41 -- src/terraform/modules/bastion/outputs.tf | 0 src/terraform/modules/bastion/variables.tf | 42 -- src/terraform/modules/firewall/main.tf | 176 ----- src/terraform/modules/firewall/outputs.tf | 17 - src/terraform/modules/firewall/variables.tf | 103 --- src/terraform/modules/hub/main.tf | 60 -- src/terraform/modules/hub/outputs.tf | 51 -- src/terraform/modules/hub/variables.tf | 44 -- src/terraform/modules/jumpbox/main.tf | 121 ---- src/terraform/modules/jumpbox/outputs.tf | 0 src/terraform/modules/jumpbox/variables.tf | 109 --- .../modules/linux-virtual-machine/main.tf | 54 -- .../modules/linux-virtual-machine/outputs.tf | 0 .../linux-virtual-machine/variables.tf | 69 -- .../modules/policy-assignments/main.tf | 20 - .../nist-parameter-values/public.json.tmpl | 34 - .../usgovernment.json.tmpl | 34 - .../modules/policy-assignments/outputs.tf | 0 .../modules/policy-assignments/variables.tf | 30 - src/terraform/modules/spoke/main.tf | 42 -- src/terraform/modules/spoke/outputs.tf | 7 - src/terraform/modules/spoke/variables.tf | 77 --- src/terraform/modules/subnet/main.tf | 116 ---- src/terraform/modules/subnet/outputs.tf | 0 src/terraform/modules/subnet/variables.tf | 103 --- src/terraform/modules/virtual-network/main.tf | 29 - .../modules/virtual-network/outputs.tf | 37 -- .../modules/virtual-network/variables.tf | 33 - .../modules/windows-virtual-machine/main.tf | 53 -- .../windows-virtual-machine/outputs.tf | 0 .../windows-virtual-machine/variables.tf | 69 -- src/terraform/tier3/main.tf | 188 ------ src/terraform/tier3/outputs.tf | 0 src/terraform/tier3/variables.tf | 165 ----- 59 files changed, 3 insertions(+), 4339 deletions(-) delete mode 100644 .azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml delete mode 100644 .azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml delete mode 100644 .azure-devops/nightlybuild/templates/terraform-apply.yml delete mode 100644 .azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml delete mode 100644 .azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml delete mode 100644 .azure-devops/prbuild/templates/terraform-plan.yml delete mode 100644 .github/workflows/README.md delete mode 100755 .github/workflows/validate-terraform.sh delete mode 100644 .github/workflows/validate-terraform.yml delete mode 100644 docs/deployment-guide-terraform.md delete mode 100644 src/bicep/add-ons/sentinel/README.md delete mode 100644 src/bicep/add-ons/sentinel/sentinel.tf delete mode 100644 src/terraform/README.md delete mode 100644 src/terraform/mlz/main.tf delete mode 100644 src/terraform/mlz/outputs.tf delete mode 100644 src/terraform/mlz/variables.tf delete mode 100644 src/terraform/modules/bastion/main.tf delete mode 100644 src/terraform/modules/bastion/outputs.tf delete mode 100644 src/terraform/modules/bastion/variables.tf delete mode 100644 src/terraform/modules/firewall/main.tf delete mode 100644 src/terraform/modules/firewall/outputs.tf delete mode 100644 src/terraform/modules/firewall/variables.tf delete mode 100644 src/terraform/modules/hub/main.tf delete mode 100644 src/terraform/modules/hub/outputs.tf delete mode 100644 src/terraform/modules/hub/variables.tf delete mode 100644 src/terraform/modules/jumpbox/main.tf delete mode 100644 src/terraform/modules/jumpbox/outputs.tf delete mode 100644 src/terraform/modules/jumpbox/variables.tf delete mode 100644 src/terraform/modules/linux-virtual-machine/main.tf delete mode 100644 src/terraform/modules/linux-virtual-machine/outputs.tf delete mode 100644 src/terraform/modules/linux-virtual-machine/variables.tf delete mode 100644 src/terraform/modules/policy-assignments/main.tf delete mode 100644 src/terraform/modules/policy-assignments/nist-parameter-values/public.json.tmpl delete mode 100644 src/terraform/modules/policy-assignments/nist-parameter-values/usgovernment.json.tmpl delete mode 100644 src/terraform/modules/policy-assignments/outputs.tf delete mode 100644 src/terraform/modules/policy-assignments/variables.tf delete mode 100644 src/terraform/modules/spoke/main.tf delete mode 100644 src/terraform/modules/spoke/outputs.tf delete mode 100644 src/terraform/modules/spoke/variables.tf delete mode 100644 src/terraform/modules/subnet/main.tf delete mode 100644 src/terraform/modules/subnet/outputs.tf delete mode 100644 src/terraform/modules/subnet/variables.tf delete mode 100644 src/terraform/modules/virtual-network/main.tf delete mode 100644 src/terraform/modules/virtual-network/outputs.tf delete mode 100644 src/terraform/modules/virtual-network/variables.tf delete mode 100644 src/terraform/modules/windows-virtual-machine/main.tf delete mode 100644 src/terraform/modules/windows-virtual-machine/outputs.tf delete mode 100644 src/terraform/modules/windows-virtual-machine/variables.tf delete mode 100644 src/terraform/tier3/main.tf delete mode 100644 src/terraform/tier3/outputs.tf delete mode 100644 src/terraform/tier3/variables.tf diff --git a/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml b/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml deleted file mode 100644 index d87891a1c..000000000 --- a/.azure-devops/nightlybuild/mlz-tf-azurecloud-pipelines.yml +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -schedules: - - - cron: "0 2 * * *" - displayName: "Nightly - mlz Terraform azure cloud" - branches: - include: - - main - always: true - -pool: - - vmImage: ubuntu-latest - -jobs: - -- job: CommercialCloud_TF - displayName: "Nightly deployment of Mission LZ Terraform on AzureCloud" - - steps: - - - template: templates/terraform-apply.yml - parameters: - ServiceConnectionName: $(CAzureConnection) - ClientId: $(ClientId) - ClientSecret: $(ClientSecret) - SubscriptionId: $(CSubId) - TenantId: $(CTenantId) - Environment: $(CCloudEnv) - MetadataHost: $(CMetadataHost) - Location: $(CLocation) - - - template: templates/clean-az-subscription.yml - parameters: - serviceConnectionName: $(CAzureConnection) diff --git a/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml b/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml deleted file mode 100644 index 1c64ef14f..000000000 --- a/.azure-devops/nightlybuild/mlz-tf-azuregov-pipelines.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -schedules: - - cron: "0 2 * * *" - displayName: "Nightly - mlz Terraform azure US Gov cloud" - branches: - include: - - main - always: true - -pool: - vmImage: ubuntu-latest - -jobs: - -- job: GovCloud_TF - displayName: "Nightly deployment of Mission LZ Terraform on AzureUsGovernment" - - steps: - - - template: templates/terraform-apply.yml - parameters: - ServiceConnectionName: $(GAzureConnection) - ClientId: $(GClientId) - ClientSecret: $(GClientSecret) - SubscriptionId: $(GSubId) - TenantId: $(GTenantId) - Environment: $(GCloudEnv) - MetadataHost: $(GMetadataHost) - Location: $(GLocation) - - - template: templates/clean-az-subscription.yml - parameters: - serviceConnectionName: $(GAzureConnection) diff --git a/.azure-devops/nightlybuild/templates/terraform-apply.yml b/.azure-devops/nightlybuild/templates/terraform-apply.yml deleted file mode 100644 index 7aa4dffbd..000000000 --- a/.azure-devops/nightlybuild/templates/terraform-apply.yml +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -parameters: - -- name: ServiceConnectionName - type: string -- name: ClientId - type: string -- name: ClientSecret - type: string -- name: SubscriptionId - type: string -- name: TenantId - type: string -- name: Environment - type: string -- name: MetadataHost - type: string -- name: Location - type: string - -steps: - - - task: TerraformInstaller@0 - inputs: - terraformVersion: 'latest' - - - task: AzureCLI@2 - displayName: "Apply MLZ Terraform" - inputs: - azureSubscription: ${{ parameters.ServiceConnectionName }} - scriptType: 'bash' - addSpnToEnvironment: true - scriptLocation: 'inlineScript' - inlineScript: | - export ARM_CLIENT_ID=${{ parameters.ClientId }} - export ARM_CLIENT_SECRET=${{ parameters.ClientSecret }} - export ARM_SUBSCRIPTION_ID=${{ parameters.SubscriptionId }} - export ARM_TENANT_ID=${{ parameters.TenantId }} - export ARM_ENVIRONMENT=${{ parameters.Environment }} - terraform init - terraform plan \ - -var "hub_subid=${{ parameters.SubscriptionId }}" \ - -var metadata_host=${{ parameters.MetadataHost}} \ - -var environment=${{ parameters.Environment }} \ - -var location=${{ parameters.Location }} \ - -input=false - terraform apply -var "hub_subid=${{ parameters.SubscriptionId }}" \ - -var metadata_host=${{ parameters.MetadataHost}} \ - -var environment=${{ parameters.Environment }} \ - -var location=${{ parameters.Location }} \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - - - task: AzureCLI@2 - displayName: "Extract Values and Hydrate Variables for T3 Deployment" - inputs: - azureSubscription: ${{ parameters.ServiceConnectionName }} - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - echo "##vso[task.setvariable variable=hubSubscriptionId;]$(terraform output -raw hub_subid)" - echo "##vso[task.setvariable variable=hubVirtualNetworkName;]$(terraform output -raw hub_vnetname)" - echo "##vso[task.setvariable variable=hubResourceGroupName;]$(terraform output -raw hub_rgname)" - echo "##vso[task.setvariable variable=firewallPrivateIPAddress;]$(terraform output -raw firewall_private_ip)" - echo "##vso[task.setvariable variable=lawsName;]$(terraform output -raw laws_name)" - echo "##vso[task.setvariable variable=lawsRgName;]$(terraform output -raw laws_rgname)" - echo "##vso[task.setvariable variable=tier1SubId;]$(terraform output -raw tier1_subid)" - echo "##vso[task.setvariable variable=tier3SubId;]$(terraform output -raw tier1_subid)" - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true - - - task: AzureCLI@2 - displayName: "Apply T3 Workload Terraform" - inputs: - azureSubscription: ${{ parameters.ServiceConnectionName }} - scriptType: 'bash' - scriptLocation: 'inlineScript' - addSpnToEnvironment: true - inlineScript: | - export ARM_CLIENT_ID=${{ parameters.ClientId }} - export ARM_CLIENT_SECRET=${{ parameters.ClientSecret }} - export ARM_SUBSCRIPTION_ID=${{ parameters.SubscriptionId }} - export ARM_TENANT_ID=${{ parameters.TenantId }} - export ARM_ENVIRONMENT=${{ parameters.Environment }} - terraform init - terraform apply -var "hub_subid=$(hubSubscriptionId)" \ - -var metadata_host=${{ parameters.MetadataHost}} \ - -var environment=${{ parameters.Environment }} \ - -var location=${{ parameters.Location }} \ - -var "hub_rgname=$(hubResourceGroupName)" \ - -var "firewall_private_ip=$(firewallPrivateIPAddress)" \ - -var "hub_vnetname=$(hubVirtualNetworkName)" \ - -var "laws_name=$(lawsName)" \ - -var "laws_rgname=$(lawsRgName)" \ - -var "tier1_subid=$(tier1SubId)" \ - -var "tier3_subid=$(tier3SubId)" \ - -auto-approve \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/tier3' - useGlobalConfig: true diff --git a/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml b/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml deleted file mode 100644 index 6b9c3bb5f..000000000 --- a/.azure-devops/prbuild/mlz-pr-tf-azurecloud-pipelines.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# disable CI per: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#disabling-the-ci-trigger -trigger: none - -pr: - branches: - include: - - main - -pool: - vmImage: ubuntu-latest - -jobs: - -- job: CommercialCloud_TF - displayName: "PR Checks for Mission LZ Terraform on AzureCloud" - - steps: - - template: templates/terraform-plan.yml - parameters: - ServiceConnectionName: $(CAzureConnection) - ClientId: $(ClientId) - ClientSecret: $(ClientSecret) - SubscriptionId: $(CSubId) - TenantId: $(CTenantId) - Environment: $(CCloudEnv) - MetadataHost: $(CMetadataHost) - Location: $(CLocation) diff --git a/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml b/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml deleted file mode 100644 index 7a793e8d4..000000000 --- a/.azure-devops/prbuild/mlz-pr-tf-azuregov-pipelines.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -# disable CI per: -# https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#disabling-the-ci-trigger -trigger: none - -pr: - branches: - include: - - main - -pool: - vmImage: ubuntu-latest - -jobs: - -- job: GovCloud_TF - displayName: "PR Checks for Mission LZ Terraform on AzureUsGovernment" - - steps: - - template: templates/terraform-plan.yml - parameters: - ServiceConnectionName: $(GAzureConnection) - ClientId: $(GClientId) - ClientSecret: $(GClientSecret) - SubscriptionId: $(GSubId) - TenantId: $(GTenantId) - Environment: $(GCloudEnv) - MetadataHost: $(GMetadataHost) - Location: $(GLocation) diff --git a/.azure-devops/prbuild/templates/terraform-plan.yml b/.azure-devops/prbuild/templates/terraform-plan.yml deleted file mode 100644 index db5afa388..000000000 --- a/.azure-devops/prbuild/templates/terraform-plan.yml +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -parameters: - -- name: ServiceConnectionName - type: string -- name: ClientId - type: string -- name: ClientSecret - type: string -- name: SubscriptionId - type: string -- name: TenantId - type: string -- name: Environment - type: string -- name: MetadataHost - type: string -- name: Location - type: string - -steps: - - - task: TerraformInstaller@0 - displayName: "Install Terraform" - inputs: - terraformVersion: 'latest' - - - task: AzureCLI@2 - displayName: "Terraform Plan" - inputs: - azureSubscription: ${{ parameters.ServiceConnectionName }} - scriptType: 'bash' - addSpnToEnvironment: true - scriptLocation: 'inlineScript' - inlineScript: | - export ARM_CLIENT_ID=${{ parameters.ClientId }} - export ARM_CLIENT_SECRET=${{ parameters.ClientSecret }} - export ARM_SUBSCRIPTION_ID=${{ parameters.SubscriptionId }} - export ARM_TENANT_ID=${{ parameters.TenantId }} - export ARM_ENVIRONMENT=${{ parameters.Environment }} - terraform init - terraform plan \ - -var 'hub_subid=${{ parameters.SubscriptionId }}' \ - -var 'metadata_host=${{ parameters.MetadataHost }}' \ - -var 'environment=${{ parameters.Environment }}' \ - -var 'location=${{ parameters.Location }}' \ - -input=false - workingDirectory: '$(System.DefaultWorkingDirectory)/src/terraform/mlz' - useGlobalConfig: true diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6f5313771..7abdc40b1 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -18,7 +18,6 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "hashicorp.terraform", "ms-vscode-remote.vscode-remote-extensionpack", "davidanson.vscode-markdownlint", "github.vscode-pull-request-github", diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index be0b688f5..9207af817 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,5 +24,4 @@ Steps to reproduce the behavior: ## Additional context Operating System: -Terraform Version: Cloud (public, Azure Government, etc.): diff --git a/.github/workflows/README.md b/.github/workflows/README.md deleted file mode 100644 index d80813321..000000000 --- a/.github/workflows/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# workflows - -These are the automated workflows we use for ensuring a quality working product. - -For more on GitHub Actions: - -For more on workflows: - -## Contents - -- apply-and-destroy-terraform.yml - - This workflow assumes some pre-requisites have been set-up. See: [Configuration Prerequisites](#configuration-prerequisites) - - 1. Checks out the .devcontainer from a private container registry for common tools - - 1. Authenticates against a pre-configured KeyVault that contains - - values for authenticating against a storage account - - values for deploying terraform - - 1. Pulls known good MLZ and Terraform configuration variables from that storage account - - 1. Applies terraform anew from that configuration (see [build/README.md](../../build/README.md) for how this works) - - 1. Destroys terraform from that configuration (see [build/README.md](../../build/README.md) for how this works) - -- validate-terraform.yml - - 1. Checks out the .devcontainer from a private container registry for common tools - - 1. Recursively validates and lints all the terraform referenced at src/terraform - -## Configuration Prerequisites - -1. Configuration store - - When applying terraform locally or from this automation, an MLZ Configuration file (commonly mlz.config) and Terraform-specific variables files (commonly *.tfvars) are required. - - You should end up with a container with these files: - - File Name | Value - ------------ | ------------- - mlz.config | An MLZ Configuration file that comes from create_required_resources.sh - mlz.tfvars | MLZ terraform values - - Running this from your local machine, you can provide these files yourself, but, today, for automation these files are stored in an Azure Storage Account and retrieved at workflow execution time. See [build/get_vars.sh](../../build/get_vars.sh) to see how we retrieve - - ```plaintext - ./build/get_vars.sh - - # pulls down these files: - vars/mlz.config - vars/mlz.tfvars - ``` - -1. Secret store and minimally scoped Service Principal - - See [glennmusa/keyvault-for-actions](https://github.com/glennmusa/keyvault-for-actions) to create a minimally scoped Service Principal to pull sensitive values from an Azure Key Vault. - - Supply that Key Vault the values for: - - Secret Name | Value - ------------ | ------------- - MLZTENANTID | The Tenant to deploy MLZ into - MLZCLIENTID | The Service Principal Authorized to deploy resources into MLZ Terraform Subscriptions - MLZCLIENTSECRET | The credential for the Service Principal above - STORAGEACCOUNT | The Azure Storage Account for the files in the previous step - STORAGECONTAINER | The container contianing the files in the previous step - STORAGETOKEN | A token to access the storage account (we used a Container SAS) - - For more on creating a minimally scoped token to access storage see: diff --git a/.github/workflows/validate-terraform.sh b/.github/workflows/validate-terraform.sh deleted file mode 100755 index b3f273f33..000000000 --- a/.github/workflows/validate-terraform.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# -# Validates and lints Terraform for 1:M directories, exiting if any errors are produced - -program_log () { - echo "${0}: ${1}" -} - -error_log () { - echo "Error: ${1}" -} - -# check for Terraform -if ! command -v terraform &> /dev/null; then - error_log "Terraform could not be found. This script requires the Terraform CLI." - echo "See https://learn.hashicorp.com/tutorials/terraform/install-cli for installation instructions." - exit 1 -fi - -# validate Terraform with `terraform validate` -validate() { - local tf_dir=$1 - cd "${tf_dir}" || exit 1 - program_log "validating at ${tf_dir}..." - terraform init -backend=false >> /dev/null || exit 1 - terraform validate >> /dev/null || exit 1 - program_log "successful validation with \"terraform validate ${tf_dir}\"!" -} - -# check Terraform formatting with `terraform fmt` -check_formatting() { - local tf_dir=$1 - cd "${tf_dir}" || exit 1 - program_log "checking formatting at ${tf_dir}..." - if terraform fmt -check -recursive >> /dev/null; - then - program_log "successful check with \"terraform fmt -check -recursive ${tf_dir}\"" - else - linting_results=$(terraform fmt -check -recursive) - for j in $linting_results - do - error_log "\"${j}\" is not formatted correctly. Format with the command \"terraform fmt ${j}\"" - done - program_log "run \"terraform fmt -recursive\" to format all Terraform components in a directory" - exit 1 - fi -} - -# get the starting directory -working_dir=$(pwd) - -# for every argument, try to validate and check formatting -for arg in "$@" -do - real_path=$(realpath "${arg}") - validate "${real_path}" - check_formatting "${real_path}" - cd "${working_dir}" || exit 1 -done - -program_log "done!" diff --git a/.github/workflows/validate-terraform.yml b/.github/workflows/validate-terraform.yml deleted file mode 100644 index 3e45e8e92..000000000 --- a/.github/workflows/validate-terraform.yml +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. ---- - -name: validate-terraform -on: - pull_request: - branches: [main] - paths: - - 'src/terraform/**' - - '!src/terraform/**.md' - workflow_dispatch: -jobs: - validate-terraform: - runs-on: ubuntu-latest - steps: - - uses: hashicorp/setup-terraform@v3.1.2 - - shell: bash - name: check tooling versions - run: | - terraform -version - - uses: actions/checkout@v4 - - shell: bash - name: validate and lint terraform - run: | - .github/workflows/validate-terraform.sh src/terraform/mlz src/terraform/tier3 diff --git a/.gitignore b/.gitignore index 2cd8dcb92..eaa7a2af4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,33 +1,5 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. -# Terraform artifacts -*.tfvars -*.terraform -*.tfstate -*.tfstate.* -terraform-provider-azurerm_v* -terraform-provider-random_v* -*.terraform.lock.hcl - -# Terraform logs -crash.log - -# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan -# example: *tfplan* -*plan* -!terraform-plan.yml -!src/bicep/** -*.plan* - # Mac files .DS_Store - -# Ignore deploymentVariables.json as it is specific to a single instantiation of MLZ -deploymentVariables.json - -# Ignore compiled bicep files from the examples that use the shared deployment variables file pattern. -src/bicep/examples/appServicePlan/appService.json -src/bicep/examples/containerRegistry/contRegistry.json -src/bicep/examples/keyVault/azureKeyVault.json -src/bicep/examples/tier3/tier3.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f1beeb98..395c23f3a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,6 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. { - "[terraform]": { - "editor.formatOnSave": true - }, "[json]": { "editor.tabSize": 2, "editor.insertSpaces": true, diff --git a/README.md b/README.md index 656f8df36..f3e2a4450 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Mission Landing Zone addresses a narrowly scoped, specific need for a [Secure Cl - Implements SCCA controls following Microsoft's [SACA](https://aka.ms/saca) implementation guidance - Deployable in Azure commercial, Azure Government, Azure Government Secret, and Azure Government Top Secret clouds - A simple solution with low configuration and narrow scope -- Written as [Bicep](./src/bicep/) and [Terraform](./src/terraform/) templates +- Written as [Bicep](./src/bicep/) templates Mission Landing Zone is the right solution when: @@ -88,7 +88,6 @@ Click [here](./docs/deployment-guide-walkthrough.md) to learn about each tab and > Don't have Azure CLI? Here's how to get started with Azure Cloud Shell in your browser: - ## Getting Started -For more detailed deployment instructions, see the [Deployment Guide for Bicep](docs/deployment-guide-bicep.md) and the [Deployment Guide for Terraform](docs/deployment-guide-terraform.md) in the [`docs`](docs) folder. +For more detailed deployment instructions, see the [Deployment Guide for Bicep](docs/deployment-guide-bicep.md) in the [`docs`](docs) folder. diff --git a/docs/deployment-guide-terraform.md b/docs/deployment-guide-terraform.md deleted file mode 100644 index 4c250eb2d..000000000 --- a/docs/deployment-guide-terraform.md +++ /dev/null @@ -1,447 +0,0 @@ -# Mission LZ Deployment Guide for Terraform - -> [!WARNING] -> The terraform code will be deprecated on June 30, 2024 and will no longer receive any updates. - -## Table of Contents - -- [Prerequisites](#prerequisites) -- [Planning](#planning) -- [Deployment](#deployment) -- [Cleanup](#cleanup) -- [Development Setup](#development-setup) -- [See Also](#see-also) - -This guide describes how to deploy Mission Landing Zone using the [Terraform](https://www.terraform.io/) template at [src/terraform/mlz](../src/terraform/mlz). - -To get started with Terraform on Azure check out their [tutorial](https://learn.hashicorp.com/collections/terraform/azure-get-started/). - -Below is an example of a Terraform deployment that uses all the defaults. - -```bash -cd src/terraform/mlz -terraform init -terraform apply # supply some parameters, approve, copy the output values -cd src/terraform/tier3 -terraform init -terraform apply # supply some parameters, approve -``` - -## Prerequisites - -- Current version of the [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) -- The version of the [Terraform CLI](https://www.terraform.io/downloads.html) described in the [.devcontainer Dockerfile](../.devcontainer/Dockerfile) -- An Azure Subscription(s) where you or an identity you manage has `Owner` [RBAC permissions](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#owner) - - -> NOTE: Azure Cloud Shell is often our preferred place to deploy from because the AZ CLI and Terraform are already installed. However, sometimes Cloud Shell has different versions of the dependencies from what we have tested and verified, and sometimes there have been bugs in the Terraform Azure RM provider or the AZ CLI that only appear in Cloud Shell. If you are deploying from Azure Cloud Shell and see something unexpected, try the [development container](../.devcontainer) or deploy from your machine using locally installed AZ CLI and Terraform. We welcome all feedback and [contributions](../CONTRIBUTING.md), so if you see something that doesn't make sense, please [create an issue](https://github.com/Azure/missionlz/issues/new/choose) or open a [discussion thread](https://github.com/Azure/missionlz/discussions). - - -## Planning - -### Decide on a Resource Prefix - -Resource Groups and resource names are derived from the `resourcePrefix` parameter, which defaults to 'mlz'. Pick a unqiue resource prefix that is 3-10 alphanumeric characters in length without whitespaces. - -### One Subscription or Multiple - -MLZ can deploy to a single subscription or multiple subscriptions. A test and evaluation deployment may deploy everything to a single subscription, and a production deployment may place each tier into its own subscription. - -The optional parameters related to subscriptions are below. At least one subscription is required. - -Parameter name | Default Value | Description --------------- | ------------- | ----------- -`hub_subid` | '' | Subscription ID for the Hub deployment -`tier0_subid` | value of hub_subid | Subscription ID for tier 0 -`tier1_subid` | value of hub_subid | Subscription ID for tier 1 -`tier2_subid` | value of hub_subid | Subscription ID for tier 2 - -### Networking - -The following parameters affect networking addresses. To override the defaults edit the variables file at [`src/terraform/mlz/variables.tf`](../src/terraform/mlz/variables.tf). - -Parameter name | Default Value | Description --------------- | ------------- | ----------- -`hub_vnet_address_space` | `["10.0.100.0/24"]` | The address space to be used for the virtual network -`hub_client_address_space` | `"10.0.100.0/26"` | The address space to be used for the Firewall virtual network -`hub_management_address_space` | `"10.0.100.64/26"` | The address space to be used for the Firewall virtual network subnet used for management traffic -`tier0_vnet_address_space` | `["10.0.110.0/26"]` | VNet prefix for tier 0 -`tier0_subnets.address_prefixes` | `["10.0.110.0/27"]` | Subnet prefix for tier 0 -`tier1_vnet_address_space` | `["10.0.115.0/26"]` | VNet prefix for tier 1 -`tier1_subnets.address_prefixes` | `["10.0.115.0/27"]` | Subnet prefix for tier 1 -`tier2_vnet_address_space` | `["10.0.120.0/26"]` | VNet prefix for tier 2 -`tier2_subnets.address_prefixes` | `["10.0.120.0/27"]` | Subnet prefix for tier 2 - -### Optional Features - -### Assigning Azure Policy - -This template supports assigning NIST 800-53 policies. See the [policies documentation](./policies.md) for more information. - -You can enable this by providing a `true` value to the `create_policy_assignment` variable. - -At `apply` time: - -```plaintext -terraform apply -var="create_policy_assignment=true" -``` - -Or, by updating `src/terraform/mlz/variables.tf`: - -```terraform -variable "create_policy_assignment" { - description = "Assign Policy to deployed resources?" - type = bool - default = true -} -``` - -### Planning for Workloads - -MLZ allows for deploying one or many workloads that are peered to the hub network. Each workload can be in its own subscription or multiple workloads may be combined into a single subscription. - -A separate Terraform template is provided for deploying an empty workload `src/terraform/tier3`. You can use this template as a starting point to create and customize specific workload deployments. - -The following parameters affect tier3 networking. To override the defaults edit the variables file at [`src/terraform/tier3/variables.tf`](../src/terraform/tier3/variables.tf). - -Parameter name | Default Value | Description --------------- | ------------- | ----------- -`tier3_vnet_address_space` | `["10.0.125.0/26"]` | Address space prefix for tier 3 -`tier3_subnets.address_prefixes` | `["10.0.125.0/27"]` | Subnet prefix for tier 3 - -## Deployment - -### Login to Azure CLI - -Log in using the Azure CLI. - -```BASH -az login -``` - -If you are deploying to another cloud, such as Azure Government, set the cloud name before logging in. - - ```BASH - az cloud set -n AzureUSGovernment - az login - ``` - -### Terraform init - -Before provisioning any Azure resources with Terraform you must [initialize a working directory](https://www.terraform.io/docs/cli/commands/init.html/). - -1. Navigate to the directory in the repository that contains the MissionLZ Terraform module: - - ```bash - cd src/terraform/mlz - ``` - -1. Execute `terraform init` - - ```bash - terraform init - ``` - -### Terraform apply - -After intializing the directory, use [`terraform apply`](https://www.terraform.io/docs/cli/commands/apply.html) to provision the resources described in `mlz/main.tf` and its referenced modules at `mlz/modules/*`. - -When you run `terraform apply`, by default, Terraform will inspect the state of your environment to determine what resource creation, modification, or deletion needs to occur as if you invoked a [`terraform plan`](https://www.terraform.io/docs/cli/commands/plan.html) and then prompt you for your approval before taking action. - -1. From the directory in which you executed `terraform init` execute `terraform apply`: - - ```bash - terraform apply - ``` - -1. You'll be prompted for a subscription ID. Supply the subscription ID you want to use for the Hub network: - - ```plaintext - > terraform apply - var.hub_subid - Subscription ID for the deployment - - Enter a value: - ``` - -1. Terraform will then inspect the state of your Azure environment and compare it with what is described in the Mission LZ Terraform module. Eventually, you'll be prompted for your approval to create, modify, or destroy resources. Supply `yes`: - - ```plaintext - Do you want to perform these actions? - Terraform will perform the actions described above. - Only 'yes' will be accepted to approve. - - Enter a value: yes - ``` - -1. The deployment will begin. These commands will deploy all of the resources that make up Mission LZ. Deployment could take up to 45 minutes. - -### Apply Complete - -When it's complete, you'll see some output values that will be necessary if you want to stand up new spoke, or Tier 3, networks: - -```plaintext -Apply complete! Resources: 99 added, 0 changed, 0 destroyed. - -Outputs: - -firewall_private_ip = "10.0.100.4" -hub_rgname = "hub-rg" -hub_subid = "{the Hub subscription ID}" -hub_vnetname = "hub-vnet" -laws_name = "{the name of the Log Analytics Workspace}" -laws_rgname = "operations-rg" -tier1_subid = "{the Tier 1 subscription ID}" -``` - -### Deploy New Workloads - -Once you've deployed Mission LZ, you can use the Tier 3 module to deploy and peer new Spoke Networks and workloads to the Hub and Firewall. - -1. Navigate to the directory in the repository that contains the MissionLZ Tier 3 Terraform module: - - ```bash - cd src/terraform/tier3 - ``` - -1. Execute `terraform init` - - ```bash - terraform init - ``` - -1. Execute `terraform apply` - - ```bash - terraform apply - ``` - -1. You'll be prompted for environment values for resources deployed by the core Mission LZ deployment for: 1) the Hub Firewall, 2) the Log Analytics Workspace resources and 3) the desired subscription ID for the new spoke network/Tier 3: - - ```plaintext - > terraform apply - var.firewall_private_ip - Firewall IP to bind network to - - Enter a value: 10.0.100.4 - - var.hub_rgname - Resource Group for the Hub deployment - - Enter a value: hub-rg - - var.hub_subid - Subscription ID for the Hub deployment - - Enter a value: {the Hub subscription ID} - - var.hub_vnetname - Virtual Network Name for the Hub deployment - - Enter a value: hub-vnet - - var.laws_name - Log Analytics Workspace Name for the deployment - - Enter a value: {the name of the Log Analytics Workspace} - - var.laws_rgname - The resource group that Log Analytics Workspace was deployed to - - Enter a value: operations-rg - - var.tier1_subid - Subscription ID for the Tier 1 deployment - - Enter a value: {the Tier 1 subscription ID} - - var.tier3_subid - Subscription ID for this Tier 3 deployment - - Enter a value: {the Tier 3 subscription ID} - ``` - - You get these values when `terraform apply` is complete for the core Mission LZ deployment. See the [Apply Complete](#apply-complete) section for what these values look like. You can also source the values after a successful core Mission LZ deployment by inspecting the `outputs` object in the Terraform state file. By default that state file is at `src/terraform/mlz/terraform.tfstate`. - -1. Terraform will then inspect the state of your Azure environment and compare it with what is described in the Tier 3 Terraform module. Eventually, you'll be prompted for your approval to create, modify, or destroy resources. Supply `yes`: - - ```plaintext - Do you want to perform these actions? - Terraform will perform the actions described above. - Only 'yes' will be accepted to approve. - - Enter a value: yes - ``` - -### Deploy with a Service Principal - -If you are using a Service Principal to deploy Azure resources with Terraform, [some additional configuration is required](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret/). - -Using a Service Principal will require [updating the resource providers](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret#configuring-the-service-principal-in-terraform/) for `mlz/main.tf`. - -```terraform -variable "client_secret" { -} - -terraform { - required_providers { - azurerm = { - ... - } - } -} - -provider "azurerm" { - features {} - - subscription_id = "00000000-0000-0000-0000-000000000000" - client_id = "00000000-0000-0000-0000-000000000000" - client_secret = var.client_secret - tenant_id = "00000000-0000-0000-0000-000000000000" -} -``` - -### Deploy to Other Clouds - -The `azurerm` Terraform provider provides a mechanism for changing the Azure cloud in which to deploy Terraform modules. - -If you want to deploy to another cloud, pass in the correct value for `environment`, `metadata_host`, and `location` for the cloud you're targeting to the relevant module's variables file [mlz/variables.tf](../src/terraform/mlz/variables.tf) or [tier3/variables.tf](../src/terraform/tier3/variables.tf): - -```terraform -variable "environment" { - description = "The Terraform backend environment e.g. public or usgovernment" - type = string - default = "usgovernment" -} - -variable "metadata_host" { - description = "The metadata host for the Azure Cloud e.g. management.azure.com" - type = string - default = "management.usgovcloudapi.net" -} - -variable "location" { - description = "The Azure region for most Mission LZ resources" - type = string - default = "usgovvirginia" -} -``` - -```terraform -provider "azurerm" { - features {} - - environment = var.environment # e.g. 'public' or 'usgovernment' - metadata_host = var.metadata_host # e.g. 'management.azure.com' or 'management.usgovcloudapi.net' -} -``` - -For the supported `environment` values, see this doc: - -For the supported `metadata_host` values, see this doc: - -For more endpoint mappings between AzureCloud and AzureUsGovernment: - -### Terraform Providers - -The [development container definition](../.devcontainer/Dockerfile) downloads the required Terraform plugin providers during the container build so that the container can be transported to an air-gapped network. - -The container sets the `TF_PLUGIN_CACHE_DIR` environment variable, which Terraform uses as the search location for locally installed providers. - -If you are not using the [development container](../.devcontainer) to deploy or if the `TF_PLUGIN_CACHE_DIR` environment variable is not set, Terraform will automatically attempt to download the provider from the internet when you execute the `terraform init` command. - -See the development container [README](/.devcontainer/README.md) for more details on building and running the container. - -### Terraform Backends - -The default templates write a state file directly to disk locally to where you are executing terraform from. If you wish to change the output directory you can set the path directly in the terraform backend block located in the main.tf file via the path variable in the backend configuration block. - -```terraform -terraform { - backend "local" { - path = "relative/path/to/terraform.tfstate" - } - - required_version = ">= 1.0.3" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "= 2.71.0" - } - random = { - source = "hashicorp/random" - version = "= 3.1.0" - } - time = { - source = "hashicorp/time" - version = "0.7.2" - } - } -} -``` - -To find more information about setting the backend see [Local Backend](https://www.terraform.io/docs/language/settings/backends/local.html), if you wish to AzureRM backend please see [AzureRM Backend](https://www.terraform.io/docs/language/settings/backends/azurerm.html) - -## Cleanup - -If you want to delete an MLZ deployment you can use [`terraform destroy`](https://www.terraform.io/docs/cli/commands/destroy.html). If you have deployed more than one Terraform template, e.g., if you have deployed `mlz/main.tf` and then `tier3/main.tf`, run the `terraform destroy` commands in the reverse order that you applied them. For example: - -```bash -# Deploy core MLZ resources -cd src/terraform/mlz -terraform apply - -# Deploy a tier 3 spoke network -cd ../tier3 -terraform apply - -# Reverse order to destroy: -# Destroy the tier 3 spoke network (still in the src/terraform/tier3 folder) -terraform destroy - -# Destroy core MLZ resources -cd ../mlz -terraform destroy -``` - -Running `terraform destroy` for `mlz/main.tf` looks like this: - -1. From the directory in which you executed `terraform init` and `terraform apply` execute `terraform destroy`: - - ```bash - terraform destroy - ``` - -1. You'll be prompted for a subscription ID. Supply the subscription ID you want to used previously: - - ```plaintext - > terraform destroy - var.hub_subid - Subscription ID for the deployment - - Enter a value: - ``` - -1. Terraform will then inspect the state of your Azure environment and compare it with what is described in Terraform state. Eventually, you'll be prompted for your approval to destroy resources. Supply `yes`: - - ```plaintext - Do you want to perform these actions? - Terraform will perform the actions described above. - Only 'yes' will be accepted to approve. - - Enter a value: yes - ``` - -This command will attempt to remove all the resources that were created by `terraform apply` and could take up to 45 minutes. - -## Development Setup - -For development of the Mission Landing Zone Terraform templates we recommend using the development container because it has the necessary dependencies already installed. To get started follow the [guidance for using the development container](../.devcontainer/README.md). - -## See Also - -[Terraform](https://www.terraform.io/) - -[Terraform Tutorial](https://learn.hashicorp.com/collections/terraform/azure-get-started/) - -[Developing in a container](https://code.visualstudio.com/docs/remote/containers) using Visual Studio Code diff --git a/docs/policies.md b/docs/policies.md index 00aabb533..63c671012 100644 --- a/docs/policies.md +++ b/docs/policies.md @@ -26,8 +26,6 @@ In particular, the current built-in NIST initiative has a couple policies attach These types of policies require a managed identity be created that the Policy engine can use to take these actions. This managed identity must have Contributor access to the resources but deploying as a Contributor and not owner limits the ability. -The Terraform MLZ deployment cannot make this role assignment but the managed identity is created. This is by design for security purposes. - 3. The final note is that these are audits based on NIST controls and recommendations that will require out of band work. For example, storage account redundancy and encryption will require a decision process on what MLZ is using as temporary storage for logs versus requirements for the workloads. @@ -62,52 +60,12 @@ az deployment group create \ --parameters logAnalyticsWorkspaceResourceGroupName= ``` -### Deploying with Terraform - -The Terraform implementaiton at `src/terraform/mlz/main.tf` supports assigning NIST 800-53 policies. You can enable this by providing a `true` value to the `create_policy_assignment` variable: - -```plaintext -cd src/terraform/mlz -terraform init -terraform apply -var="create_policy_assignment=true" -``` - -After the resources are deployed, you will need to go into go into each assignment and retrieve the managed identity and modify its role access to contributor scoped to the associated resource group. This is due to the initiative including modify and deploy policies that act on resources, like deploying the require policy guest configuration extensions to VMs. - ## Modifying ### Modifying with Bicep The project stores well-known policies at [src/bicep/modules/policies](../src/bicep/modules/policies) where JSON files named for the initiatives with default parameters (except for a Log Analytics workspace ID value `` that we substitute at deployment time -- any other parameter can be modified as needed). -### Modifying with Terraform - -This project uses a custom terraform module called 'policy-assignments'. This can be modified for adding additional initiatives if desired. The module deployments retrieve their parameter values from a local json file stored in the module directory named 'nist-parameter-values' and named after the cloud environment they are deploying to, public or usgovernment. - -Example parameters file snippet: - -```arm -{ - "listOfMembersToExcludeFromWindowsVMAdministratorsGroup": - { - "value": "admin" - }, - "listOfMembersToIncludeInWindowsVMAdministratorsGroup": - { - "value": "azureuser" - }, - "logAnalyticsWorkspaceIdforVMReporting": - { - "value": ${jsonencode(laws_instance_id)} - }, - "IncludeArcMachines": - { - "value": "true" - } -``` - -In the above example the 'logAnalyticsWorkspaceIdforVMReporting' is retrieved from the running terraform deployment variables. This could be modified to use a central logging workspace if desired. - ## What's Next While this is only a start, the NIST controls included in the built-in initiatives are a good start to understanding requirements on top of MLZ for compliance. diff --git a/src/bicep/add-ons/README.md b/src/bicep/add-ons/README.md index edbb9333d..1484c8aca 100644 --- a/src/bicep/add-ons/README.md +++ b/src/bicep/add-ons/README.md @@ -14,7 +14,6 @@ Example | Description [Container Registry](./container-registry/) | Deploys an Azure Container Registry for holding and deploying docker containers. [Inherit Tags](./inherit-tags) | Adds or replaces a specified tag and value from the parent resource group when any resource is created or updated. [KeyVault](./key-vault/) | Deploys a premium Azure Key Vault with RBAC enabled to support secret, key, and certificate management. -[Azure Sentinel](./sentinel) | A Terraform module that adds an Azure Sentinel solution to a Log Analytics Workspace. Sentinel can also be deployed via bicep and the base deployment of mlz.bicep by using the boolean param '-deploySentinel'. [Zero Trust (TIC3.0) Workbook](./zero-trust-workbook) | Deploys an Azure Sentinel Zero Trust (TIC3.0) Workbook [IaaS DNS Forwarders](./iaas-dns-forwarders) | Deploys DNS Forwarder Virtual Machines in the HUB, for proper resolution of Private Endpoint and internal domains accross all Virtual Networks diff --git a/src/bicep/add-ons/sentinel/README.md b/src/bicep/add-ons/sentinel/README.md deleted file mode 100644 index 1be0fc47b..000000000 --- a/src/bicep/add-ons/sentinel/README.md +++ /dev/null @@ -1,99 +0,0 @@ -# Sentinel Example - -This example adds an Azure Sentinel solution to a Log Analytics Workspace using Terraform. It shows how to use Terraform to deploy new resources to an existing Mission Landing Zone that was deployed using Bicep. Data from the original Bicep deployment can be retrieved using the Azure CLI and used as parameter inputs for a Terraform template. - -## What this example does - -### Deploys Sentinel - -The docs on Azure Sentinel: - -## Pre-requisites - -1. Terraform ([link to download](https://www.terraform.io/downloads.html)) -1. A Mission LZ deployment (a deployment of mlz.bicep) -1. The output from that deployment described below - -Required Parameters | Description -------------------- | ----------- -location | The region to deploy Azure Sentinel into - -Deployment Output Name | Description ------------------------| ----------- -operationsSubscriptionId | The subscription that contains the Log Analytics Workspace and to deploy the Sentinel solution into -operationsResourceGroupName | The resource group that contains the Log Analytics Workspace to link Azure Sentinel to -logAnalyticsWorkspaceName | The name of the Log Analytics Workspace to link Azure Sentinel to -logAnalyticsWorkspaceResourceId | The resource ID of the Log Analytics Workspace to link Azure Sentinel to - -One way to retreive these values is with the Azure CLI: - -```bash -# after a Mission LZ deployment -# -# az deployment sub create \ -# --subscription $deploymentSubscription \ -# --name "myMlzDeployment" \ -# --template-file ./mlz.bicep \ - -az deployment sub show \ - --subscription $deploymentSubscription \ - --name "myMlzDeployment" \ - --query properties.outputs -``` - -...which should return an object containing the values you need: - -```plaintext -{ - "operationsSubscriptionId": { - "type": "String", - "value": "0987654-3210..." - }, - ... - "operationsResourceGroupName": { - "type": "String", - "value": "mlz-dev-operations" - }, - ... - "logAnalyticsWorkspaceName": { - "type": "String", - "value": "mlz-dev-laws" - }, - ... - "logAnalyticsWorkspaceResourceId": { - "type": "String", - "value": "/subscriptions/.../providers/Microsoft.OperationalInsights/workspaces/mlz-dev-laws" - }, -} -``` - -...and if you're on a BASH terminal, this command (take note to replace "myMlzDeployment" with your deployment name) will export the values as environment variables: - - -```bash -export $(az deployment sub show --name "myMlzDeployment" --query "properties.outputs.{ args: [ join('', ['operationsSubscriptionId=', operationsSubscriptionId.value]), join('', ['operationsResourceGroupName=', operationsResourceGroupName.value]), join('', ['logAnalyticsWorkspaceName=', logAnalyticsWorkspaceName.value]), join('', ['logAnalyticsWorkspaceResourceId=', logAnalyticsWorkspaceResourceId.value]) ] }.args" --output tsv | xargs) -``` - - -## Deploying Sentinel - -You'll need to initialize Terraform in this directory: - -```bash -cd examples/sentinel - -terraform init -``` - -Then, using our MLZ deployment output [as input variables](https://www.terraform.io/docs/language/values/variables.html), and specifying a `location` variable, you can call Terraform apply: - -```bash -location="eastus" - -terraform apply \ - -var subscription_id="$operationsSubscriptionId" \ - -var location="$location" \ - -var resource_group_name="$operationsResourceGroupName" \ - -var workspace_resource_id="$logAnalyticsWorkspaceResourceId" \ - -var workspace_name="$logAnalyticsWorkspaceName" -``` diff --git a/src/bicep/add-ons/sentinel/sentinel.tf b/src/bicep/add-ons/sentinel/sentinel.tf deleted file mode 100644 index 7a179ea43..000000000 --- a/src/bicep/add-ons/sentinel/sentinel.tf +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -terraform { - backend "local" {} - - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "= 2.69.0" - } - random = { - source = "hashicorp/random" - version = "= 3.1.0" - } - time = { - source = "hashicorp/time" - version = "0.7.2" - } - } -} - -provider "azurerm" { - subscription_id = var.subscription_id - features {} -} - -variable "subscription_id" { - type = string - description = "The subscription that contains the Log Analytics Workspace and to deploy the Sentinel solution into" -} - -variable location { - type = string - description = "The Azure region to deploy the Sentinel solution" -} - -variable "resource_group_name" { - type = string - description = "The name of the resource group that will contain the Sentinel solution" -} - -variable "workspace_name" { - type = string - description = "The name of the Log Analytics Workspace that will link to the Sentinel solution" -} - -variable "workspace_resource_id" { - type = string - description = "The resource id of the Log Analytics Workspace that will link to the Sentinel solution" -} - - -resource "azurerm_log_analytics_solution" "laws_sentinel" { - solution_name = "SecurityInsights" - location = var.location - resource_group_name = var.resource_group_name - workspace_name = var.workspace_name - workspace_resource_id = var.workspace_resource_id - - plan { - publisher = "Microsoft" - product = "OMSGallery/SecurityInsights" - } -} \ No newline at end of file diff --git a/src/bicep/add-ons/zero-trust-workbook/README.md b/src/bicep/add-ons/zero-trust-workbook/README.md index fd4560ba7..220928534 100644 --- a/src/bicep/add-ons/zero-trust-workbook/README.md +++ b/src/bicep/add-ons/zero-trust-workbook/README.md @@ -1,6 +1,6 @@ # Zero Trust (TIC3.0) Workbook Example -This example adds an Azure Sentinel: Zero Trust (TIC3.0) Workbook solution to MLZ, provided Sentinel has already been deployed; either through the bicep or [terraform implementation instructions](../sentinel/README.md) in the Operations (T1) resource group. +This example adds an Azure Sentinel: Zero Trust (TIC3.0) Workbook solution to MLZ, provided Sentinel has already been deployed in the Operations (T1) resource group. ## What this example does diff --git a/src/terraform/README.md b/src/terraform/README.md deleted file mode 100644 index 0a68d314a..000000000 --- a/src/terraform/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Mission Landing Zone Terraform Template - -> [!WARNING] -> The terraform code will be deprecated on June 30, 2024 and will no longer receive any updates. - -This folder contains the Terraform templates for deploying Mission Landing Zone. See the [Deployment Guide for Terraform](../../docs/deployment-guide-terraform.md) for detailed instructions on how to use the templates. diff --git a/src/terraform/mlz/main.tf b/src/terraform/mlz/main.tf deleted file mode 100644 index 4b7473d76..000000000 --- a/src/terraform/mlz/main.tf +++ /dev/null @@ -1,627 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -terraform { - # It is recommended to use remote state instead of local - # If you are using Terraform Cloud, You can update these values in order to configure your remote state. - /* backend "remote" { - organization = "{{ORGANIZATION_NAME}}" - workspaces { - name = "{{WORKSPACE_NAME}}" - } - } - */ - backend "local" {} - - required_version = ">= 1.2.9" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "= 3.23.0" - } - random = { - source = "hashicorp/random" - version = "= 3.4.3" - } - time = { - source = "hashicorp/time" - version = "0.8.0" - } - } -} - -provider "azurerm" { - environment = var.environment - metadata_host = var.metadata_host - subscription_id = var.hub_subid - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "hub" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = var.hub_subid - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "tier0" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = coalesce(var.tier0_subid, var.hub_subid) - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "tier1" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = coalesce(var.tier1_subid, var.hub_subid) - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "tier2" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = coalesce(var.tier2_subid, var.hub_subid) - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "random" { -} - -provider "time" { -} - -data "azurerm_client_config" "current_client" { -} - -################################ -### GLOBAL VARIABLES ### -################################ - -locals { - firewall_premium_environments = ["public", "usgovernment"] # terraform azurerm environments where Azure Firewall Premium is supported -} - -################################ -### STAGE 0: Scaffolding ### -################################ -resource "random_id" "random" { - keepers = { - # Generate a new id each time we change resourePrefix variable - resourcePrefix = var.resourcePrefix - } - byte_length = 8 -} - -resource "azurerm_resource_group" "hub" { - provider = azurerm.hub - depends_on = [random_id.random] - - location = var.location - name = "${var.resourcePrefix}-${random_id.random.hex}-${var.hub_rgname}" - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_resource_group" "tier0" { - provider = azurerm.tier0 - depends_on = [random_id.random] - - location = var.location - name = "${var.resourcePrefix}-${random_id.random.hex}-${var.tier0_rgname}" - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_resource_group" "tier1" { - provider = azurerm.tier1 - depends_on = [random_id.random] - - location = var.location - name = "${var.resourcePrefix}-${random_id.random.hex}-${var.tier1_rgname}" - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_resource_group" "tier2" { - provider = azurerm.tier2 - depends_on = [random_id.random] - - location = var.location - name = "${var.resourcePrefix}-${random_id.random.hex}-${var.tier2_rgname}" - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -################################ -### STAGE 1: Logging ### -################################ - -resource "random_id" "laws" { - keepers = { - resource_group = azurerm_resource_group.tier1.name - } - - byte_length = 8 -} - -resource "azurerm_log_analytics_workspace" "laws" { - provider = azurerm.tier1 - depends_on = [random_id.laws] - - name = coalesce(var.log_analytics_workspace_name, format("%.24s", lower(replace("logAnalyticsWorkspace${random_id.laws.hex}", "/[[:^alnum:]]/", "")))) - resource_group_name = azurerm_resource_group.tier1.name - location = var.location - sku = "PerGB2018" - retention_in_days = "30" - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_log_analytics_solution" "laws_sentinel" { - provider = azurerm.tier1 - count = var.create_sentinel ? 1 : 0 - - solution_name = "SecurityInsights" - location = azurerm_resource_group.tier1.location - resource_group_name = azurerm_resource_group.tier1.name - workspace_resource_id = azurerm_log_analytics_workspace.laws.id - workspace_name = azurerm_log_analytics_workspace.laws.name - - plan { - publisher = "Microsoft" - product = "OMSGallery/SecurityInsights" - } - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -// Central Logging -locals { - log_categories = ["Administrative", "Security", "ServiceHealth", "Alert", "Recommendation", "Policy", "Autoscale", "ResourceHealth"] -} - -resource "azurerm_monitor_diagnostic_setting" "hub-central" { - provider = azurerm.hub - name = "hub-central-diagnostics" - target_resource_id = "/subscriptions/${var.hub_subid}" - - log_analytics_workspace_id = azurerm_log_analytics_workspace.laws.id - - dynamic "log" { - for_each = local.log_categories - content { - category = log.value - enabled = true - - retention_policy { - days = 0 - enabled = false - } - } - } -} - -resource "azurerm_monitor_diagnostic_setting" "tier0-central" { - count = (var.tier0_subid != "") ? (var.tier0_subid != var.hub_subid ? 1 : 0) : 0 - provider = azurerm.tier0 - name = "tier0-central-diagnostics" - target_resource_id = "/subscriptions/${var.tier0_subid}" - - log_analytics_workspace_id = azurerm_log_analytics_workspace.laws.id - - dynamic "log" { - for_each = local.log_categories - content { - category = log.value - enabled = true - - retention_policy { - days = 0 - enabled = false - } - } - } -} - -resource "azurerm_monitor_diagnostic_setting" "tier1-central" { - count = (var.tier1_subid != "") ? (var.tier1_subid != var.hub_subid ? 1 : 0) : 0 - provider = azurerm.tier1 - name = "tier1-central-diagnostics" - target_resource_id = "/subscriptions/${var.tier1_subid}" - - log_analytics_workspace_id = azurerm_log_analytics_workspace.laws.id - - dynamic "log" { - for_each = local.log_categories - content { - category = log.value - enabled = true - - retention_policy { - days = 0 - enabled = false - } - } - } -} - -resource "azurerm_monitor_diagnostic_setting" "tier2-central" { - count = (var.tier2_subid != "") ? (var.tier2_subid != var.hub_subid ? 1 : 0) : 0 - provider = azurerm.tier2 - name = "tier2-central-diagnostics" - target_resource_id = "/subscriptions/${var.tier2_subid}" - - log_analytics_workspace_id = azurerm_log_analytics_workspace.laws.id - - dynamic "log" { - for_each = local.log_categories - content { - category = log.value - enabled = true - - retention_policy { - days = 0 - enabled = false - } - } - } -} - -############################### -## STAGE 2: Networking ### -############################### - -module "hub-network" { - providers = { azurerm = azurerm.hub } - depends_on = [azurerm_resource_group.hub] - source = "../modules/hub" - - location = var.location - resource_group_name = azurerm_resource_group.hub.name - vnet_name = var.hub_vnetname - vnet_address_space = var.hub_vnet_address_space - client_address_space = var.hub_client_address_space - management_address_space = var.hub_management_address_space - - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -module "firewall" { - providers = { azurerm = azurerm.hub } - depends_on = [azurerm_resource_group.hub, module.hub-network] - source = "../modules/firewall" - - sub_id = var.hub_subid - resource_group_name = module.hub-network.resource_group_name - location = var.location - vnet_name = module.hub-network.virtual_network_name - vnet_address_space = module.hub-network.virtual_network_address_space - client_address_space = var.hub_client_address_space - - firewall_name = var.firewall_name - firewall_sku_name = var.firewall_sku_name - firewall_sku = contains(local.firewall_premium_environments, lower(var.environment)) ? "Premium" : "Standard" - firewall_client_subnet_name = module.hub-network.firewall_client_subnet_name - firewall_management_subnet_name = module.hub-network.firewall_management_subnet_name - firewall_policy_name = var.firewall_policy_name - - client_ipconfig_name = var.client_ipconfig_name - client_publicip_name = var.client_publicip_name - - management_ipconfig_name = var.management_ipconfig_name - management_publicip_name = var.management_publicip_name - - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -module "spoke-network-t0" { - providers = { azurerm = azurerm.tier0 } - depends_on = [azurerm_resource_group.tier0, module.hub-network, module.firewall] - source = "../modules/spoke" - - location = azurerm_resource_group.tier0.location - - firewall_private_ip = module.firewall.firewall_private_ip - - laws_location = var.location - laws_workspace_id = azurerm_log_analytics_workspace.laws.workspace_id - laws_resource_id = azurerm_log_analytics_workspace.laws.id - - spoke_rgname = azurerm_resource_group.tier0.name - spoke_vnetname = var.tier0_vnetname - spoke_vnet_address_space = var.tier0_vnet_address_space - subnets = var.tier0_subnets - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_virtual_network_peering" "t0-to-hub" { - provider = azurerm.tier0 - depends_on = [azurerm_resource_group.tier0, module.spoke-network-t0, module.hub-network, module.firewall] - - name = "${var.tier0_vnetname}-to-${var.hub_vnetname}" - resource_group_name = azurerm_resource_group.tier0.name - virtual_network_name = var.tier0_vnetname - remote_virtual_network_id = module.hub-network.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -resource "azurerm_virtual_network_peering" "hub-to-t0" { - provider = azurerm.hub - depends_on = [azurerm_resource_group.hub, module.spoke-network-t0, module.hub-network, module.firewall] - - name = "${var.hub_vnetname}-to-${var.tier0_vnetname}" - resource_group_name = azurerm_resource_group.hub.name - virtual_network_name = var.hub_vnetname - remote_virtual_network_id = module.spoke-network-t0.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -module "spoke-network-t1" { - providers = { azurerm = azurerm.tier1 } - depends_on = [azurerm_resource_group.tier1, module.hub-network, module.firewall] - source = "../modules/spoke" - - location = azurerm_resource_group.tier1.location - - firewall_private_ip = module.firewall.firewall_private_ip - - laws_location = var.location - laws_workspace_id = azurerm_log_analytics_workspace.laws.workspace_id - laws_resource_id = azurerm_log_analytics_workspace.laws.id - - spoke_rgname = azurerm_resource_group.tier1.name - spoke_vnetname = var.tier1_vnetname - spoke_vnet_address_space = var.tier1_vnet_address_space - subnets = var.tier1_subnets - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_virtual_network_peering" "t1-to-hub" { - provider = azurerm.tier1 - depends_on = [azurerm_resource_group.tier1, module.spoke-network-t1, module.hub-network, module.firewall] - - name = "${var.tier1_vnetname}-to-${var.hub_vnetname}" - resource_group_name = azurerm_resource_group.tier1.name - virtual_network_name = var.tier1_vnetname - remote_virtual_network_id = module.hub-network.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -resource "azurerm_virtual_network_peering" "hub-to-t1" { - provider = azurerm.hub - depends_on = [azurerm_resource_group.hub, module.spoke-network-t1, module.hub-network, module.firewall] - - name = "${var.hub_vnetname}-to-${var.tier1_vnetname}" - resource_group_name = azurerm_resource_group.hub.name - virtual_network_name = var.hub_vnetname - remote_virtual_network_id = module.spoke-network-t1.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -module "spoke-network-t2" { - providers = { azurerm = azurerm.tier2 } - depends_on = [azurerm_resource_group.tier2, module.hub-network, module.firewall] - source = "../modules/spoke" - - location = azurerm_resource_group.tier2.location - - firewall_private_ip = module.firewall.firewall_private_ip - - laws_location = var.location - laws_workspace_id = azurerm_log_analytics_workspace.laws.workspace_id - laws_resource_id = azurerm_log_analytics_workspace.laws.id - - spoke_rgname = azurerm_resource_group.tier2.name - spoke_vnetname = var.tier2_vnetname - spoke_vnet_address_space = var.tier2_vnet_address_space - subnets = var.tier2_subnets - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -resource "azurerm_virtual_network_peering" "t2-to-hub" { - provider = azurerm.tier2 - depends_on = [azurerm_resource_group.tier2, module.spoke-network-t2, module.hub-network, module.firewall] - - name = "${var.tier2_vnetname}-to-${var.hub_vnetname}" - resource_group_name = azurerm_resource_group.tier2.name - virtual_network_name = var.tier2_vnetname - remote_virtual_network_id = module.hub-network.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -resource "azurerm_virtual_network_peering" "hub-to-t2" { - provider = azurerm.hub - depends_on = [azurerm_resource_group.hub, module.spoke-network-t2, module.hub-network, module.firewall] - - name = "${var.hub_vnetname}-to-${var.tier2_vnetname}" - resource_group_name = azurerm_resource_group.hub.name - virtual_network_name = var.hub_vnetname - remote_virtual_network_id = module.spoke-network-t2.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -################################ -### STAGE 3: Remote Access ### -################################ - -######################################################################### -### This stage is optional based on the value of `create_bastion_jumpbox` -######################################################################### - -module "jumpbox-subnet" { - count = var.create_bastion_jumpbox ? 1 : 0 - - providers = { azurerm = azurerm.hub } - depends_on = [azurerm_resource_group.hub, module.hub-network, module.firewall, azurerm_log_analytics_workspace.laws] - source = "../modules/subnet" - - name = var.jumpbox_subnet.name - location = var.location - resource_group_name = azurerm_resource_group.hub.name - virtual_network_name = var.hub_vnetname - address_prefixes = var.jumpbox_subnet.address_prefixes - service_endpoints = lookup(var.jumpbox_subnet, "service_endpoints", []) - - private_endpoint_network_policies_enabled = lookup(var.jumpbox_subnet, "private_endpoint_network_policies_enabled", null) - private_link_service_network_policies_enabled = lookup(var.jumpbox_subnet, "private_link_service_network_policies_enabled", null) - - nsg_name = var.jumpbox_subnet.nsg_name - nsg_rules = var.jumpbox_subnet.nsg_rules - - routetable_name = var.jumpbox_subnet.routetable_name - firewall_ip_address = module.firewall.firewall_private_ip - - log_analytics_storage_id = module.hub-network.log_analytics_storage_id - log_analytics_workspace_id = azurerm_log_analytics_workspace.laws.workspace_id - log_analytics_workspace_location = var.location - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -module "bastion-host" { - count = var.create_bastion_jumpbox ? 1 : 0 - - providers = { azurerm = azurerm.hub } - depends_on = [azurerm_resource_group.hub, module.hub-network, module.firewall, module.jumpbox-subnet] - source = "../modules/bastion" - - resource_group_name = azurerm_resource_group.hub.name - location = azurerm_resource_group.hub.location - virtual_network_name = var.hub_vnetname - bastion_host_name = var.bastion_host_name - subnet_address_prefix = var.bastion_address_space - public_ip_name = var.bastion_public_ip_name - ipconfig_name = var.bastion_ipconfig_name - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -module "jumpbox" { - count = var.create_bastion_jumpbox ? 1 : 0 - - providers = { azurerm = azurerm.hub } - depends_on = [azurerm_resource_group.hub, module.hub-network, module.firewall, module.jumpbox-subnet] - source = "../modules/jumpbox" - - resource_group_name = azurerm_resource_group.hub.name - virtual_network_name = var.hub_vnetname - subnet_name = var.jumpbox_subnet.name - location = var.location - - keyvault_name = var.jumpbox_keyvault_name - - tenant_id = data.azurerm_client_config.current_client.tenant_id - object_id = data.azurerm_client_config.current_client.object_id - - windows_name = var.jumpbox_windows_vm_name - windows_size = var.jumpbox_windows_vm_size - windows_publisher = var.jumpbox_windows_vm_publisher - windows_offer = var.jumpbox_windows_vm_offer - windows_sku = var.jumpbox_windows_vm_sku - windows_image_version = var.jumpbox_windows_vm_version - - linux_name = var.jumpbox_linux_vm_name - linux_size = var.jumpbox_linux_vm_size - linux_publisher = var.jumpbox_linux_vm_publisher - linux_offer = var.jumpbox_linux_vm_offer - linux_sku = var.jumpbox_linux_vm_sku - linux_image_version = var.jumpbox_linux_vm_version - tags = merge(var.tags, { "resourcePrefix" = "${var.resourcePrefix}-${random_id.random.hex}" }) -} - -##################################### -### STAGE 4: Compliance example ### -##################################### - -module "hub-policy-assignment" { - count = var.create_policy_assignment ? 1 : 0 - - providers = { azurerm = azurerm.hub } - source = "../modules/policy-assignments" - depends_on = [azurerm_resource_group.hub, azurerm_log_analytics_workspace.laws] - resource_group_name = azurerm_resource_group.hub.name - laws_instance_id = azurerm_log_analytics_workspace.laws.workspace_id - environment = var.environment # Example "usgovernment" - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id -} - -module "tier0-policy-assignment" { - count = var.create_policy_assignment ? 1 : 0 - - providers = { azurerm = azurerm.tier0 } - source = "../modules/policy-assignments" - depends_on = [azurerm_resource_group.tier0, azurerm_log_analytics_workspace.laws] - resource_group_name = azurerm_resource_group.tier0.name - laws_instance_id = azurerm_log_analytics_workspace.laws.workspace_id - environment = var.environment # Example "usgovernment" - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id -} - -module "tier1-policy-assignment" { - count = var.create_policy_assignment ? 1 : 0 - - providers = { azurerm = azurerm.tier1 } - source = "../modules/policy-assignments" - depends_on = [azurerm_resource_group.tier1, azurerm_log_analytics_workspace.laws] - resource_group_name = azurerm_resource_group.tier1.name - laws_instance_id = azurerm_log_analytics_workspace.laws.workspace_id - environment = var.environment # Example "usgovernment" - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id -} - -module "tier2-policy-assignment" { - count = var.create_policy_assignment ? 1 : 0 - - providers = { azurerm = azurerm.tier2 } - source = "../modules/policy-assignments" - depends_on = [azurerm_resource_group.tier2, azurerm_log_analytics_workspace.laws] - resource_group_name = azurerm_resource_group.tier2.name - laws_instance_id = azurerm_log_analytics_workspace.laws.workspace_id - environment = var.environment # Example "usgovernment" - log_analytics_workspace_resource_id = azurerm_log_analytics_workspace.laws.id -} diff --git a/src/terraform/mlz/outputs.tf b/src/terraform/mlz/outputs.tf deleted file mode 100644 index c1e1282da..000000000 --- a/src/terraform/mlz/outputs.tf +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -output "hub_subid" { - description = "Subscription ID where the Hub Resource Group is provisioned" - value = var.hub_subid -} - -output "hub_rgname" { - description = "The Hub Resource Group name" - value = azurerm_resource_group.hub.name -} - -output "hub_vnetname" { - description = "The Hub Virtual Network name" - value = module.hub-network.virtual_network_name -} - -output "firewall_private_ip" { - description = "Firewall private IP" - value = module.firewall.firewall_private_ip -} - -output "tier1_subid" { - description = "Subscription ID where the Tier 1 Resource Group is provisioned" - value = coalesce(var.tier1_subid, var.hub_subid) -} - -output "laws_name" { - description = "LAWS Name" - value = azurerm_log_analytics_workspace.laws.name -} - -output "laws_rgname" { - description = "Resource Group for Laws" - value = azurerm_log_analytics_workspace.laws.resource_group_name -} diff --git a/src/terraform/mlz/variables.tf b/src/terraform/mlz/variables.tf deleted file mode 100644 index a724d40e2..000000000 --- a/src/terraform/mlz/variables.tf +++ /dev/null @@ -1,603 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -################################# -# Global Configuration -################################# - -variable "environment" { - description = "The Terraform backend environment e.g. public or usgovernment" - type = string - default = "public" -} - -variable "metadata_host" { - description = "The metadata host for the Azure Cloud e.g. management.azure.com or management.usgovcloudapi.net." - type = string - default = "management.azure.com" -} - -variable "location" { - description = "The Azure region for most Mission LZ resources. e.g. for government usgovvirginia" - type = string - default = "East US" -} - -variable "resourcePrefix" { - description = "A name for the deployment. It defaults to mlz." - type = string - default = "mlz" -} - -variable "tags" { - description = "A map of key value pairs to apply as tags to resources provisioned in this deployment" - type = map(string) - default = { - "DeploymentType" : "MissionLandingZoneTF" - } -} - -################################# -# Hub Configuration -################################# - -variable "hub_subid" { - description = "Subscription ID for the Hub deployment" - type = string -} - -variable "hub_rgname" { - description = "Resource Group for the deployment" - type = string - default = "hub" -} - -variable "hub_vnetname" { - description = "Virtual Network Name for the deployment" - type = string - default = "hub-vnet" -} - -variable "hub_vnet_address_space" { - description = "The address space to be used for the virtual network." - type = list(string) - default = ["10.0.100.0/24"] -} - -################################# -# Firewall configuration section -################################# - -variable "hub_client_address_space" { - description = "The address space to be used for the Firewall virtual network." - type = string - default = "10.0.100.0/26" -} - -variable "hub_management_address_space" { - description = "The address space to be used for the Firewall virtual network subnet used for management traffic." - type = string - default = "10.0.100.64/26" -} - -variable "firewall_name" { - description = "Name of the Hub Firewall" - type = string - default = "firewall" -} - -variable "firewall_sku_name" { - description = "SKU name of the Firewall. Possible values are AZFW_Hub and AZFW_VNet." - type = string - default = "AZFW_VNet" -} - -variable "firewall_policy_name" { - description = "Name of the firewall policy to apply to the hub firewall" - type = string - default = "firewall-policy" -} - -variable "client_ipconfig_name" { - description = "The name of the Firewall Client IP Configuration" - type = string - default = "firewall-client-ip-config" -} - -variable "client_publicip_name" { - description = "The name of the Firewall Client Public IP" - type = string - default = "firewall-client-public-ip" -} - -variable "management_ipconfig_name" { - description = "The name of the Firewall Management IP Configuration" - type = string - default = "firewall-management-ip-config" -} - -variable "management_publicip_name" { - description = "The name of the Firewall Management Public IP" - type = string - default = "firewall-management-public-ip" -} - -################################# -# Bastion Host Configuration -################################# - -variable "create_bastion_jumpbox" { - description = "Create a bastion host and jumpbox VM?" - type = bool - default = true -} - -variable "bastion_host_name" { - description = "The name of the Bastion Host" - type = string - default = "bastionHost" -} - -variable "bastion_address_space" { - description = "The address space to be used for the Bastion Host subnet (must be /27 or larger)." - type = string - default = "10.0.100.128/27" -} - -variable "bastion_public_ip_name" { - description = "The name of the Bastion Host Public IP" - type = string - default = "bastionHostPublicIPAddress" -} - -variable "bastion_ipconfig_name" { - description = "The name of the Bastion Host IP Configuration" - type = string - default = "bastionHostIPConfiguration" -} - -################################# -# Jumpbox VM Configuration -################################# - -variable "jumpbox_subnet" { - description = "The subnet for jumpboxes" - type = object({ - name = string - address_prefixes = list(string) - service_endpoints = list(string) - - private_endpoint_network_policies_enabled = bool - private_link_service_network_policies_enabled = bool - - nsg_name = string - nsg_rules = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) - - routetable_name = string - }) - default = { - name = "jumpbox-subnet" - address_prefixes = ["10.0.100.160/27"] - service_endpoints = ["Microsoft.Storage"] - - private_endpoint_network_policies_enabled = false - private_link_service_network_policies_enabled = false - - nsg_name = "jumpbox-subnet-nsg" - nsg_rules = { - "allow_ssh" = { - name = "allow_ssh" - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "22" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - }, - "allow_rdp" = { - name = "allow_rdp" - priority = "200" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "3389" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - } - } - - routetable_name = "jumpbox-routetable" - } -} - -variable "jumpbox_keyvault_name" { - description = "The name of the jumpbox virtual machine keyvault" - type = string - default = "jumpboxKeyvault" -} - -variable "jumpbox_windows_vm_name" { - description = "The name of the Windows jumpbox virtual machine" - type = string - default = "jumpboxWindowsVm" -} - -variable "jumpbox_windows_vm_size" { - description = "The size of the Windows jumpbox virtual machine" - type = string - default = "Standard_DS1_v2" -} - -variable "jumpbox_windows_vm_publisher" { - description = "The publisher of the Windows jumpbox virtual machine source image" - type = string - default = "MicrosoftWindowsServer" -} - -variable "jumpbox_windows_vm_offer" { - description = "The offer of the Windows jumpbox virtual machine source image" - type = string - default = "WindowsServer" -} - -variable "jumpbox_windows_vm_sku" { - description = "The SKU of the Windows jumpbox virtual machine source image" - type = string - default = "2019-datacenter-gensecond" -} - -variable "jumpbox_windows_vm_version" { - description = "The version of the Windows jumpbox virtual machine source image" - type = string - default = "latest" -} - -variable "jumpbox_linux_vm_name" { - description = "The name of the Linux jumpbox virtual machine" - type = string - default = "jumpboxLinuxVm" -} - -variable "jumpbox_linux_vm_size" { - description = "The size of the Linux jumpbox virtual machine" - type = string - default = "Standard_DS1_v2" -} - -variable "jumpbox_linux_vm_publisher" { - description = "The publisher of the Linux jumpbox virtual machine source image" - type = string - default = "Canonical" -} - -variable "jumpbox_linux_vm_offer" { - description = "The offer of the Linux jumpbox virtual machine source image" - type = string - default = "UbuntuServer" -} - -variable "jumpbox_linux_vm_sku" { - description = "The SKU of the Linux jumpbox virtual machine source image" - type = string - default = "18.04-LTS" -} - -variable "jumpbox_linux_vm_version" { - description = "The version of the Linux jumpbox virtual machine source image" - type = string - default = "latest" -} - -################################ -# Policy Configuration -################################ - -variable "create_policy_assignment" { - description = "Assign Policy to deployed resources?" - type = bool - default = false -} - -################################# -# Tier 0 Configuration -################################# - -variable "tier0_subid" { - description = "Subscription ID for the deployment" - type = string - default = "" -} - -variable "tier0_rgname" { - description = "Resource Group for the deployment" - type = string - default = "identity" -} - -variable "tier0_vnetname" { - description = "Virtual Network Name for the deployment" - type = string - default = "identity-vnet" -} - -variable "tier0_vnet_address_space" { - description = "Address space prefixes list of strings" - type = list(string) - default = ["10.0.110.0/26"] -} - -variable "tier0_subnets" { - description = "A complex object that describes subnets." - type = map(object({ - name = string - address_prefixes = list(string) - service_endpoints = list(string) - - enforce_private_link_endpoint_network_policies = bool - enforce_private_link_service_network_policies = bool - - nsg_name = string - nsg_rules = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) - - routetable_name = string - })) - default = { - "identitySubnet" = { - name = "identitySubnet" - address_prefixes = ["10.0.110.0/27"] - service_endpoints = ["Microsoft.Storage"] - - enforce_private_link_endpoint_network_policies = false - enforce_private_link_service_network_policies = false - - nsg_name = "identitySubnetNsg" - nsg_rules = { - "allow_ssh" = { - name = "allow_ssh" - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "22" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - }, - "allow_rdp" = { - name = "allow_rdp" - priority = "200" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "3389" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - } - } - - routetable_name = "identityRouteTable" - } - } -} - -################################# -# Tier 1 Configuration -################################# - -variable "tier1_subid" { - description = "Subscription ID for the deployment" - type = string - default = "" -} - -variable "tier1_rgname" { - description = "Resource Group for the deployment" - type = string - default = "operations" -} - -variable "tier1_vnetname" { - description = "Virtual Network Name for the deployment" - type = string - default = "operations-vnet" -} - -variable "log_analytics_workspace_name" { - description = "Log Analytics Workspace Name for the deployment" - type = string - default = "" -} - -variable "create_sentinel" { - description = "Create an Azure Sentinel Log Analytics Workspace Solution" - type = bool - default = true -} - -variable "tier1_vnet_address_space" { - description = "Address space prefixes for the virtual network" - type = list(string) - default = ["10.0.115.0/26"] -} - -variable "tier1_subnets" { - description = "A complex object that describes subnets." - type = map(object({ - name = string - address_prefixes = list(string) - service_endpoints = list(string) - - enforce_private_link_endpoint_network_policies = bool - enforce_private_link_service_network_policies = bool - - nsg_name = string - nsg_rules = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) - - routetable_name = string - })) - default = { - "operationsSubnet" = { - name = "operationsSubnet" - address_prefixes = ["10.0.115.0/27"] - service_endpoints = ["Microsoft.Storage"] - - enforce_private_link_endpoint_network_policies = false - enforce_private_link_service_network_policies = false - - nsg_name = "operationsSubnetNsg" - nsg_rules = { - "allow_ssh" = { - name = "allow_ssh" - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "22" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - }, - "allow_rdp" = { - name = "allow_rdp" - priority = "200" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "3389" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - } - } - - routetable_name = "operationsRouteTable" - } - } -} - -################################# -# Tier 2 Configuration -################################# - -variable "tier2_subid" { - description = "Subscription ID for the deployment" - type = string - default = "" -} - -variable "tier2_rgname" { - description = "Resource Group for the deployment" - type = string - default = "sharedServices" -} - -variable "tier2_vnetname" { - description = "Virtual Network Name for the deployment" - type = string - default = "sharedServices-vnet" -} - -variable "tier2_vnet_address_space" { - description = "Address space prefixes list of strings" - type = list(string) - default = ["10.0.120.0/26"] -} - -variable "tier2_subnets" { - description = "A complex object that describes subnets." - type = map(object({ - name = string - address_prefixes = list(string) - service_endpoints = list(string) - - enforce_private_link_endpoint_network_policies = bool - enforce_private_link_service_network_policies = bool - - nsg_name = string - nsg_rules = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) - - routetable_name = string - })) - default = { - "sharedServicesSubnet" = { - name = "sharedServicesSubnet" - address_prefixes = ["10.0.120.0/27"] - service_endpoints = ["Microsoft.Storage"] - - enforce_private_link_endpoint_network_policies = false - enforce_private_link_service_network_policies = false - - nsg_name = "sharedServicesSubnetNsg" - nsg_rules = { - "allow_ssh" = { - name = "allow_ssh" - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "22" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - }, - "allow_rdp" = { - name = "allow_rdp" - priority = "200" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "3389" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - } - } - - routetable_name = "sharedServicesRouteTable" - } - } -} diff --git a/src/terraform/modules/bastion/main.tf b/src/terraform/modules/bastion/main.tf deleted file mode 100644 index 0bfd97dd3..000000000 --- a/src/terraform/modules/bastion/main.tf +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -data "azurerm_resource_group" "bastion_host_rg" { - name = var.resource_group_name -} - -data "azurerm_virtual_network" "bastion_host_vnet" { - name = var.virtual_network_name - resource_group_name = var.resource_group_name -} - -resource "azurerm_subnet" "bastion_host_subnet" { - name = "AzureBastionSubnet" # the name of the subnet must be 'AzureBastionSubnet' - resource_group_name = var.resource_group_name - virtual_network_name = data.azurerm_virtual_network.bastion_host_vnet.name - address_prefixes = [cidrsubnet(var.subnet_address_prefix, 0, 0)] -} - -resource "azurerm_public_ip" "bastion_host_pip" { - name = var.public_ip_name - location = var.location - resource_group_name = var.resource_group_name - allocation_method = "Static" - sku = "Standard" - tags = var.tags -} - -resource "azurerm_bastion_host" "bastion_host" { - name = var.bastion_host_name - location = var.location - resource_group_name = var.resource_group_name - - ip_configuration { - name = var.ipconfig_name - subnet_id = azurerm_subnet.bastion_host_subnet.id - public_ip_address_id = azurerm_public_ip.bastion_host_pip.id - } - - tags = var.tags -} diff --git a/src/terraform/modules/bastion/outputs.tf b/src/terraform/modules/bastion/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/modules/bastion/variables.tf b/src/terraform/modules/bastion/variables.tf deleted file mode 100644 index c632bb5c1..000000000 --- a/src/terraform/modules/bastion/variables.tf +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "resource_group_name" { - description = "The name of the resource group the Bastion Host resides in" - type = string -} - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "virtual_network_name" { - description = "The name of the virtual network the Bastion Host resides in" - type = string -} - -variable "bastion_host_name" { - description = "The name of the Bastion Host" - type = string -} - -variable "subnet_address_prefix" { - description = "The address prefix for the Bastion Host (must be a /27 or larger)" - type = string -} - -variable "public_ip_name" { - description = "The name of the Bastion Host public IP address resource" - type = string -} - -variable "ipconfig_name" { - description = "The name of the Bastion Host IP configuration resource" - type = string -} - -variable "tags" { - description = "A mapping of tags which should be assigned to the resource." - type = map(string) -} diff --git a/src/terraform/modules/firewall/main.tf b/src/terraform/modules/firewall/main.tf deleted file mode 100644 index 52dc12993..000000000 --- a/src/terraform/modules/firewall/main.tf +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -data "azurerm_resource_group" "hub" { - name = var.resource_group_name -} - -data "azurerm_virtual_network" "hub" { - name = var.vnet_name - resource_group_name = data.azurerm_resource_group.hub.name -} - -data "azurerm_subnet" "fw_client_sn" { - name = var.firewall_client_subnet_name - virtual_network_name = data.azurerm_virtual_network.hub.name - resource_group_name = data.azurerm_resource_group.hub.name -} - -data "azurerm_subnet" "fw_mgmt_sn" { - name = var.firewall_management_subnet_name - virtual_network_name = data.azurerm_virtual_network.hub.name - resource_group_name = data.azurerm_resource_group.hub.name -} - -resource "azurerm_public_ip" "fw_client_pip" { - name = var.client_publicip_name - location = var.location - resource_group_name = data.azurerm_resource_group.hub.name - allocation_method = "Static" - sku = "Standard" - tags = var.tags -} - -resource "azurerm_public_ip" "fw_mgmt_pip" { - name = var.management_publicip_name - location = var.location - resource_group_name = data.azurerm_resource_group.hub.name - allocation_method = "Static" - sku = "Standard" - tags = var.tags -} - -resource "azurerm_firewall_policy" "firewallpolicy" { - name = var.firewall_policy_name - resource_group_name = data.azurerm_resource_group.hub.name - location = var.location - sku = var.firewall_sku - threat_intelligence_mode = "Alert" -} - -resource "azurerm_firewall" "firewall" { - name = var.firewall_name - location = var.location - resource_group_name = data.azurerm_resource_group.hub.name - sku_name = var.firewall_sku_name - sku_tier = var.firewall_sku - private_ip_ranges = var.disable_snat_ip_range - firewall_policy_id = azurerm_firewall_policy.firewallpolicy.id - tags = var.tags - dns_servers = null - zones = null - - ip_configuration { - name = var.client_ipconfig_name - subnet_id = "/subscriptions/${var.sub_id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/virtualNetworks/${var.vnet_name}/subnets/AzureFirewallSubnet" - public_ip_address_id = azurerm_public_ip.fw_client_pip.id - } - - management_ip_configuration { - name = var.management_ipconfig_name - subnet_id = "/subscriptions/${var.sub_id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/virtualNetworks/${var.vnet_name}/subnets/AzureFirewallManagementSubnet" - public_ip_address_id = azurerm_public_ip.fw_mgmt_pip.id - } -} - -resource "random_id" "storageaccount" { - byte_length = 12 -} - -resource "azurerm_storage_account" "loganalytics" { - name = format("%.24s", lower(replace("${azurerm_firewall.firewall.name}logs${random_id.storageaccount.id}", "/[[:^alnum:]]/", ""))) - resource_group_name = data.azurerm_resource_group.hub.name - location = var.location - account_kind = "StorageV2" - account_tier = "Standard" - account_replication_type = "LRS" - enable_https_traffic_only = true - tags = var.tags -} - -resource "azurerm_monitor_diagnostic_setting" "firewall-diagnostics" { - name = "${azurerm_firewall.firewall.name}-fw-diagnostics" - target_resource_id = "/subscriptions/${var.sub_id}/resourceGroups/${var.resource_group_name}/providers/Microsoft.Network/azureFirewalls/${var.firewall_name}" - storage_account_id = azurerm_storage_account.loganalytics.id - log_analytics_workspace_id = var.log_analytics_workspace_resource_id - - log { - category = "AzureFirewallApplicationRule" - enabled = true - - retention_policy { - days = 30 - enabled = true - } - } - - log { - category = "AzureFirewallNetworkRule" - enabled = true - - retention_policy { - days = 30 - enabled = true - } - } - - log { - category = "AzureFirewallDnsProxy" - enabled = true - - retention_policy { - days = 30 - enabled = true - } - } - - metric { - category = "AllMetrics" - retention_policy { - enabled = false - } - } -} - -resource "azurerm_monitor_diagnostic_setting" "publicip-diagnostics" { - name = "${azurerm_public_ip.fw_client_pip.name}-pip-diagnostics" - target_resource_id = azurerm_public_ip.fw_client_pip.id - storage_account_id = azurerm_storage_account.loganalytics.id - log_analytics_workspace_id = var.log_analytics_workspace_resource_id - - log { - category = "DDoSProtectionNotifications" - enabled = true - - retention_policy { - days = 30 - enabled = true - } - } - - log { - category = "DDoSMitigationFlowLogs" - enabled = true - - retention_policy { - days = 30 - enabled = true - } - } - - log { - category = "DDoSMitigationReports" - enabled = true - - retention_policy { - days = 30 - enabled = true - } - } - - metric { - category = "AllMetrics" - retention_policy { - enabled = false - } - } -} diff --git a/src/terraform/modules/firewall/outputs.tf b/src/terraform/modules/firewall/outputs.tf deleted file mode 100644 index bf430197f..000000000 --- a/src/terraform/modules/firewall/outputs.tf +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -output "firewall_public_ip" { - description = "The public IP for the firewall" - value = azurerm_public_ip.fw_client_pip.ip_address -} - -output "firewall_private_ip" { - description = "The private IP for the firewall" - value = azurerm_firewall.firewall.ip_configuration[0].private_ip_address -} - -output "firewall_name" { - description = "The name of the firewall" - value = azurerm_firewall.firewall.name -} diff --git a/src/terraform/modules/firewall/variables.tf b/src/terraform/modules/firewall/variables.tf deleted file mode 100644 index 15a93b50e..000000000 --- a/src/terraform/modules/firewall/variables.tf +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "sub_id" { - description = "The subscription ID to deploy the Firewall into" - type = string -} - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "resource_group_name" { - description = "A container that holds related resources for an Azure solution" - type = string -} - -variable "vnet_name" { - description = "The name of the Firewall virtual network" - type = string -} - -variable "vnet_address_space" { - description = "The address space to be used for the Firewall virtual network" - type = list(string) -} - -variable "firewall_sku_name" { - description = "SKU name of the Firewall. Possible values are AZFW_Hub and AZFW_VNet." - type = string -} - -variable "firewall_sku" { - description = "The SKU for Azure Firewall" - type = string -} - -variable "client_address_space" { - description = "The address space to be used for the Firewall subnets" - type = string -} - -variable "firewall_client_subnet_name" { - description = "The name of the Firewall client traffic subnet" - type = string -} - -variable "firewall_management_subnet_name" { - description = "The name of the Firewall management traffic subnet" - type = string -} - -variable "firewall_name" { - description = "The name of the Firewall" - type = string -} - -variable "firewall_policy_name" { - description = "The name of the firewall policy" - type = string -} - -variable "client_ipconfig_name" { - description = "The name of the Firewall Client IP Configuration" - type = string -} - -variable "client_publicip_name" { - description = "The name of the Firewall Client Public IP" - type = string -} - -variable "management_ipconfig_name" { - description = "The name of the Firewall Management IP Configuration" - type = string -} - -variable "management_publicip_name" { - description = "The name of the Firewall Management Public IP" - type = string -} - -variable "log_analytics_workspace_resource_id" { - description = "The resource id of the Log Analytics Workspace" - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - type = map(string) - default = {} -} - -# With forced tunneling on, Configure Azure Firewall to never SNAT regardless of the destination IP address, -# use 0.0.0.0/0 as your private IP address range. -# With this configuration, Azure Firewall can never route traffic directly to the Internet. -# see: https://docs.microsoft.com/en-us/azure/firewall/snat-private-range -variable "disable_snat_ip_range" { - description = "The address space to be used to ensure that SNAT is disabled." - default = ["0.0.0.0/0"] - type = list(any) -} diff --git a/src/terraform/modules/hub/main.tf b/src/terraform/modules/hub/main.tf deleted file mode 100644 index 7d4c3c2df..000000000 --- a/src/terraform/modules/hub/main.tf +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -module "hub-network" { - source = "../virtual-network" - location = var.location - resource_group_name = var.resource_group_name - vnet_name = var.vnet_name - vnet_address_space = var.vnet_address_space - log_analytics_workspace_resource_id = var.log_analytics_workspace_resource_id - tags = var.tags -} - -resource "azurerm_subnet" "fw_client" { - name = "AzureFirewallSubnet" - resource_group_name = module.hub-network.resource_group_name - virtual_network_name = module.hub-network.virtual_network_name - address_prefixes = [cidrsubnet(var.client_address_space, 0, 0)] -} - -resource "azurerm_subnet" "fw_mgmt" { - name = "AzureFirewallManagementSubnet" - resource_group_name = module.hub-network.resource_group_name - virtual_network_name = module.hub-network.virtual_network_name - address_prefixes = [cidrsubnet(var.management_address_space, 0, 0)] -} - -resource "azurerm_route_table" "routetable" { - name = "FirewallRouteTable" - resource_group_name = azurerm_subnet.fw_mgmt.resource_group_name - location = var.location - disable_bgp_route_propagation = true - tags = var.tags -} - -resource "azurerm_route" "default_route" { - name = "FirewallDefaultRoute" - resource_group_name = azurerm_route_table.routetable.resource_group_name - route_table_name = "FirewallRouteTable" - address_prefix = "0.0.0.0/0" - next_hop_type = "Internet" -} - -resource "time_sleep" "wait_30_seconds" { - depends_on = [ - azurerm_route.default_route - ] - - create_duration = "30s" -} - -resource "azurerm_subnet_route_table_association" "routetable" { - depends_on = [ - azurerm_route.default_route, - time_sleep.wait_30_seconds - ] - - subnet_id = azurerm_subnet.fw_mgmt.id - route_table_id = azurerm_route_table.routetable.id -} diff --git a/src/terraform/modules/hub/outputs.tf b/src/terraform/modules/hub/outputs.tf deleted file mode 100644 index 78b0bb59c..000000000 --- a/src/terraform/modules/hub/outputs.tf +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -output "resource_group_name" { - description = "The name of the resource group in which resources are created" - value = module.hub-network.resource_group_name -} - -output "resource_group_location" { - description = "The location of the resource group in which resources are created" - value = module.hub-network.resource_group_location -} - -output "virtual_network_name" { - description = "The name of the virtual network" - value = module.hub-network.virtual_network_name -} - -output "virtual_network_address_space" { - description = "List of address spaces that are used the virtual network." - value = module.hub-network.virtual_network_address_space -} - -output "virtual_network_id" { - description = "The id of the virtual network" - value = module.hub-network.virtual_network_id -} - -output "firewall_client_subnet_name" { - description = "Firewall client subnet name." - value = azurerm_subnet.fw_client.name -} - -output "firewall_management_subnet_name" { - description = "Firewall management subnet name." - value = azurerm_subnet.fw_mgmt.name -} - -output "firewall_client_subnet_id" { - description = "Firewall client subnet ID." - value = azurerm_subnet.fw_client.id -} - -output "firewall_mgmt_subnet_id" { - description = "Firewall management subnet ID." - value = azurerm_subnet.fw_mgmt.id -} - -output "log_analytics_storage_id" { - description = "Log Analytics Storage ID." - value = module.hub-network.log_analytics_storage_id -} diff --git a/src/terraform/modules/hub/variables.tf b/src/terraform/modules/hub/variables.tf deleted file mode 100644 index 6b221c3d7..000000000 --- a/src/terraform/modules/hub/variables.tf +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "resource_group_name" { - description = "A container that holds related resources for an Azure solution" - type = string -} - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "vnet_name" { - description = "The name of the virtual network" - type = string -} - -variable "vnet_address_space" { - description = "The address space to be used for the virtual network." - default = [] - type = list(string) -} - -variable "client_address_space" { - description = "The address space to be used for the Firewall virtual network subnet used for client traffic." - type = string -} - -variable "management_address_space" { - description = "The address space to be used for the Firewall virtual network subnet used for management traffic." - type = string -} - -variable "log_analytics_workspace_resource_id" { - description = "The Azure resource ID for the Log Analytics Workspace." - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - default = {} - type = map(string) -} diff --git a/src/terraform/modules/jumpbox/main.tf b/src/terraform/modules/jumpbox/main.tf deleted file mode 100644 index e2227ecd9..000000000 --- a/src/terraform/modules/jumpbox/main.tf +++ /dev/null @@ -1,121 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -resource "random_id" "jumpbox-keyvault" { - byte_length = 12 -} - -resource "azurerm_key_vault" "jumpbox-keyvault" { - name = format("%.24s", lower(replace("${var.keyvault_name}${random_id.jumpbox-keyvault.id}", "/[[:^alnum:]]/", ""))) - location = var.location - resource_group_name = var.resource_group_name - tenant_id = var.tenant_id - soft_delete_retention_days = 90 - sku_name = "standard" # 'standard' or 'premium' case sensitive - - access_policy { - tenant_id = var.tenant_id - object_id = var.object_id - - key_permissions = [ - "Create", - "Get", - ] - - secret_permissions = [ - "Set", - "Get", - "Delete", - "Purge", - "Recover" - ] - } - - tags = var.tags -} - -resource "azurerm_key_vault_secret" "jumpbox-username" { - name = "jumpbox-username" - value = var.admin_username - key_vault_id = azurerm_key_vault.jumpbox-keyvault.id -} - -resource "random_integer" "windows-jumpbox-password" { - min = 8 - max = 123 -} - -resource "random_password" "windows-jumpbox-password" { - length = random_integer.windows-jumpbox-password.result - upper = true - lower = true - numeric = true - special = true - min_upper = 1 - min_lower = 1 - min_numeric = 1 - min_special = 1 -} - -resource "azurerm_key_vault_secret" "windows-jumpbox-password" { - name = "windows-jumpbox-password" - value = random_password.windows-jumpbox-password.result - key_vault_id = azurerm_key_vault.jumpbox-keyvault.id -} - -resource "random_integer" "linux-jumpbox-password" { - min = 6 - max = 72 -} - -resource "random_password" "linux-jumpbox-password" { - length = random_integer.linux-jumpbox-password.result - upper = true - lower = true - numeric = true - special = true - min_upper = 1 - min_lower = 1 - min_numeric = 1 - min_special = 1 -} - -resource "azurerm_key_vault_secret" "linux-jumpbox-password" { - name = "linux-jumpbox-password" - value = random_password.linux-jumpbox-password.result - key_vault_id = azurerm_key_vault.jumpbox-keyvault.id -} - -module "windows-virtual-machine" { - source = "../windows-virtual-machine" - resource_group_name = var.resource_group_name - location = var.location - virtual_network_name = var.virtual_network_name - subnet_name = var.subnet_name - name = var.windows_name - size = var.windows_size - admin_username = var.admin_username - admin_password = random_password.windows-jumpbox-password.result - publisher = var.windows_publisher - offer = var.windows_offer - sku = var.windows_sku - image_version = var.windows_image_version - tags = var.tags -} - -module "linux-virtual-machine" { - source = "../linux-virtual-machine" - resource_group_name = var.resource_group_name - location = var.location - virtual_network_name = var.virtual_network_name - subnet_name = var.subnet_name - name = var.linux_name - size = var.linux_size - admin_username = var.admin_username - admin_password = random_password.linux-jumpbox-password.result - publisher = var.linux_publisher - offer = var.linux_offer - sku = var.linux_sku - image_version = var.linux_image_version - tags = var.tags -} diff --git a/src/terraform/modules/jumpbox/outputs.tf b/src/terraform/modules/jumpbox/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/modules/jumpbox/variables.tf b/src/terraform/modules/jumpbox/variables.tf deleted file mode 100644 index 4c0e576c4..000000000 --- a/src/terraform/modules/jumpbox/variables.tf +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "resource_group_name" { - description = "The name of the resource group the jumpbox resides in" - type = string -} - -variable "virtual_network_name" { - description = "The name of the virtual network the jumpbox resides in" - type = string -} - -variable "subnet_name" { - description = "The name of the subnet the jumpbox resides in" - type = string -} - -variable "location" { - description = "The region to deploy the jumpbox resides into" - type = string -} - -variable "keyvault_name" { - description = "The name of the keyvault to store jumpbox credentials in" - type = string -} - -variable "tenant_id" { - description = "The tenant ID of the keyvault to store jumpbox credentials in" - type = string -} - -variable "object_id" { - description = "The object ID with access the keyvault to store and retrieve jumpbox credentials" - type = string -} - -variable "admin_username" { - description = "The username used to administer jumpboxes" - default = "azureuser" - type = string -} - -variable "windows_name" { - description = "The name of the Windows virtual machine" - type = string -} - -variable "windows_size" { - description = "The size of the Windows virtual machine" - type = string -} - -variable "windows_publisher" { - description = "The publisher of the Windows virtual machine source image" - type = string -} - -variable "windows_offer" { - description = "The offer of the Windows virtual machine source image" - type = string -} - -variable "windows_sku" { - description = "The SKU of the Windows virtual machine source image" - type = string -} - -variable "windows_image_version" { - description = "The version of the Windows virtual machine source image" - type = string -} - -variable "linux_name" { - description = "The name of the Linux virtual machine" - type = string -} - -variable "linux_size" { - description = "The size of the Linux virtual machine" - type = string -} - -variable "linux_publisher" { - description = "The publisher of the Linux virtual machine source image" - type = string -} - -variable "linux_offer" { - description = "The offer of the Linux virtual machine source image" - type = string -} - -variable "linux_sku" { - description = "The SKU of the Linux virtual machine source image" - type = string -} - -variable "linux_image_version" { - description = "The version of the Linux virtual machine source image" - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - default = {} - type = map(string) -} diff --git a/src/terraform/modules/linux-virtual-machine/main.tf b/src/terraform/modules/linux-virtual-machine/main.tf deleted file mode 100644 index ef94234e6..000000000 --- a/src/terraform/modules/linux-virtual-machine/main.tf +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -data "azurerm_resource_group" "vm_resource_group" { - name = var.resource_group_name -} - -data "azurerm_subnet" "vm_subnet" { - name = var.subnet_name - virtual_network_name = var.virtual_network_name - resource_group_name = var.resource_group_name -} - -resource "azurerm_network_interface" "linux_vm" { - name = "${var.name}_NIC" - resource_group_name = var.resource_group_name - location = var.location - - ip_configuration { - name = "${var.name}_IPCONFIG" - subnet_id = data.azurerm_subnet.vm_subnet.id - private_ip_address_allocation = "Dynamic" - } - - tags = var.tags -} - -resource "azurerm_linux_virtual_machine" "linux_vm" { - name = var.name - computer_name = substr(var.name, 0, 14) # computer_name can only be 15 characters maximum - resource_group_name = var.resource_group_name - location = var.location - size = var.size - admin_username = var.admin_username - admin_password = var.admin_password - disable_password_authentication = false - network_interface_ids = [ - azurerm_network_interface.linux_vm.id - ] - - os_disk { - caching = "ReadWrite" - storage_account_type = "StandardSSD_LRS" - } - - source_image_reference { - publisher = var.publisher - offer = var.offer - sku = var.sku - version = var.image_version - } - - tags = var.tags -} diff --git a/src/terraform/modules/linux-virtual-machine/outputs.tf b/src/terraform/modules/linux-virtual-machine/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/modules/linux-virtual-machine/variables.tf b/src/terraform/modules/linux-virtual-machine/variables.tf deleted file mode 100644 index 4ab36e38c..000000000 --- a/src/terraform/modules/linux-virtual-machine/variables.tf +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "resource_group_name" { - description = "The name of the resource group the virtual machine resides in" - type = string -} - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "virtual_network_name" { - description = "The name of the virtual network the virtual machine resides in" - type = string -} - -variable "subnet_name" { - description = "The name of the subnet the virtual machine resides in" - type = string -} - -variable "name" { - description = "The name of the virtual machine" - type = string -} - -variable "size" { - description = "The size of the virtual machine" - type = string -} - -variable "admin_username" { - description = "The admin username of the virtual machine" - type = string -} - -variable "admin_password" { - description = "The admin password of the virtual machine" - type = string - sensitive = true -} - -variable "publisher" { - description = "The publisher of the virtual machine source image" - type = string -} - -variable "offer" { - description = "The offer of the virtual machine source image" - type = string -} - -variable "sku" { - description = "The SKU of the virtual machine source image" - type = string -} - -variable "image_version" { - description = "The version of the virtual machine source image" - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - default = {} - type = map(string) -} diff --git a/src/terraform/modules/policy-assignments/main.tf b/src/terraform/modules/policy-assignments/main.tf deleted file mode 100644 index 305ba7bd8..000000000 --- a/src/terraform/modules/policy-assignments/main.tf +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -data "azurerm_resource_group" "rg" { - name = var.resource_group_name -} - -resource "azurerm_resource_group_policy_assignment" "policy_assign" { - name = "NIST Assignment - ${data.azurerm_resource_group.rg.name}" - resource_group_id = data.azurerm_resource_group.rg.id - policy_definition_id = var.policy_id - location = data.azurerm_resource_group.rg.location - identity { - type = "SystemAssigned" - } - # Define parameters for value template file directed to environment - parameters = templatefile("${path.module}/nist-parameter-values/${var.environment}.json.tmpl", { - laws_instance_id = var.laws_instance_id - }) -} diff --git a/src/terraform/modules/policy-assignments/nist-parameter-values/public.json.tmpl b/src/terraform/modules/policy-assignments/nist-parameter-values/public.json.tmpl deleted file mode 100644 index df80a22c6..000000000 --- a/src/terraform/modules/policy-assignments/nist-parameter-values/public.json.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -{ - "listOfMembersToExcludeFromWindowsVMAdministratorsGroup": - { - "value": "admin" - }, - "listOfMembersToIncludeInWindowsVMAdministratorsGroup": - { - "value": "azureuser" - }, - "logAnalyticsWorkspaceIdforVMReporting": - { - "value": ${jsonencode(laws_instance_id)} - }, - "IncludeArcMachines": - { - "value": "true" - }, - "MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112": - { - "value": "1.2" - }, - "NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40": - { - "value": "Compliant" - }, - "requiredRetentionDays": - { - "value": "365" - }, - "resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6": - { - "value": "NetworkWatcherRG" - } -} \ No newline at end of file diff --git a/src/terraform/modules/policy-assignments/nist-parameter-values/usgovernment.json.tmpl b/src/terraform/modules/policy-assignments/nist-parameter-values/usgovernment.json.tmpl deleted file mode 100644 index 957c53ccb..000000000 --- a/src/terraform/modules/policy-assignments/nist-parameter-values/usgovernment.json.tmpl +++ /dev/null @@ -1,34 +0,0 @@ -{ - "listOfMembersToExcludeFromWindowsVMAdministratorsGroup": - { - "value": "admin" - }, - "listOfMembersToIncludeInWindowsVMAdministratorsGroup": - { - "value": "azureuser" - }, - "logAnalyticsWorkspaceIdforVMReporting": - { - "value": ${jsonencode(laws_instance_id)} - }, - "IncludeArcMachines": - { - "value": "true" - }, - "MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112": - { - "value": "1.2" - }, - "NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40": - { - "value": "Compliant" - }, - "requiredRetentionDays": - { - "value": "365" - }, - "resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6": - { - "value": "NetworkWatcherRG" - } -} \ No newline at end of file diff --git a/src/terraform/modules/policy-assignments/outputs.tf b/src/terraform/modules/policy-assignments/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/modules/policy-assignments/variables.tf b/src/terraform/modules/policy-assignments/variables.tf deleted file mode 100644 index 613c49737..000000000 --- a/src/terraform/modules/policy-assignments/variables.tf +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "policy_id" { - description = "The Azure policy ID for the NIST 800-53 R4 policy initiative." - type = string - default = "/providers/Microsoft.Authorization/policySetDefinitions/cf25b9c1-bd23-4eb6-bd2c-f4f3ac644a5f" -} - -variable "resource_group_name" { - description = "Resource group name for policy assignment." - type = string -} - -variable "environment" { - description = "The Terraform backend environment e.g. public or usgovernment. It defaults to public." - type = string - default = "public" -} - -variable "laws_instance_id" { - description = "The log analytics workspace ID which will be provided to the underlying policy rules via the policy parameters." - type = string -} - -# Full resource ID used if enabling activity diagnostic logging -variable "log_analytics_workspace_resource_id" { - description = "The resource id of the Log Analytics Workspace" - type = string -} diff --git a/src/terraform/modules/spoke/main.tf b/src/terraform/modules/spoke/main.tf deleted file mode 100644 index d1fa5a18c..000000000 --- a/src/terraform/modules/spoke/main.tf +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -module "spoke-network" { - source = "../virtual-network" - location = var.location - resource_group_name = var.spoke_rgname - vnet_name = var.spoke_vnetname - vnet_address_space = var.spoke_vnet_address_space - log_analytics_workspace_resource_id = var.laws_resource_id - - tags = var.tags -} - -module "subnets" { - depends_on = [module.spoke-network] - source = "../subnet" - for_each = var.subnets - - name = each.value.name - location = var.location - resource_group_name = var.spoke_rgname - virtual_network_name = var.spoke_vnetname - address_prefixes = each.value.address_prefixes - service_endpoints = lookup(each.value, "service_endpoints", []) - - private_endpoint_network_policies_enabled = lookup(each.value, "private_endpoint_network_policies_enabled", null) - private_link_service_network_policies_enabled = lookup(each.value, "private_link_service_network_policies_enabled", null) - - nsg_name = each.value.nsg_name - nsg_rules = each.value.nsg_rules - - routetable_name = each.value.routetable_name - firewall_ip_address = var.firewall_private_ip - - log_analytics_storage_id = module.spoke-network.log_analytics_storage_id - log_analytics_workspace_id = var.laws_workspace_id - log_analytics_workspace_location = var.laws_location - log_analytics_workspace_resource_id = var.laws_resource_id - - tags = var.tags -} diff --git a/src/terraform/modules/spoke/outputs.tf b/src/terraform/modules/spoke/outputs.tf deleted file mode 100644 index 3a3b8d1ae..000000000 --- a/src/terraform/modules/spoke/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -output "virtual_network_id" { - description = "The id of the virtual network" - value = module.spoke-network.virtual_network_id -} diff --git a/src/terraform/modules/spoke/variables.tf b/src/terraform/modules/spoke/variables.tf deleted file mode 100644 index a069db3d0..000000000 --- a/src/terraform/modules/spoke/variables.tf +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "location" { - description = "The region for spoke network deployment" - type = string -} - -variable "laws_location" { - description = "Log Analytics Workspace location" - type = string -} - -variable "laws_workspace_id" { - description = "Log Analytics Workspace workspace ID" - type = string -} - -variable "laws_resource_id" { - description = "Log Analytics Workspace Azure Resource ID" - type = string -} - -variable "firewall_private_ip" { - description = "Private IP of the Firewall" - type = string -} - -variable "spoke_rgname" { - description = "Resource Group for the spoke network deployment" - type = string -} - -variable "spoke_vnetname" { - description = "Virtual Network Name for the spoke network deployment" - type = string -} - -################################# -# Network configuration section -################################# -variable "spoke_vnet_address_space" { - description = "Address space prefixes for the spoke network" - type = list(string) -} - -variable "subnets" { - description = "A complex object that describes subnets for the spoke network" - type = map(object({ - name = string - address_prefixes = list(string) - service_endpoints = list(string) - - enforce_private_link_endpoint_network_policies = bool - enforce_private_link_service_network_policies = bool - - nsg_name = string - nsg_rules = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) - - routetable_name = string - })) -} - -variable "tags" { - description = "A map of tags to add to all resources" - type = map(string) -} diff --git a/src/terraform/modules/subnet/main.tf b/src/terraform/modules/subnet/main.tf deleted file mode 100644 index 0aac02a3c..000000000 --- a/src/terraform/modules/subnet/main.tf +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -resource "azurerm_subnet" "subnet" { - name = var.name - resource_group_name = var.resource_group_name - virtual_network_name = var.virtual_network_name - address_prefixes = var.address_prefixes - - service_endpoints = var.service_endpoints - - private_endpoint_network_policies_enabled = var.private_endpoint_network_policies_enabled - private_link_service_network_policies_enabled = var.private_link_service_network_policies_enabled -} - -resource "azurerm_network_security_group" "nsg" { - name = var.nsg_name - resource_group_name = azurerm_subnet.subnet.resource_group_name - location = var.location - - tags = var.tags -} - -resource "azurerm_network_security_rule" "nsgrules" { - for_each = var.nsg_rules - - name = each.value.name - priority = each.value.priority - direction = each.value.direction - access = each.value.access - protocol = each.value.protocol - source_port_range = each.value.source_port_range != "" ? each.value.source_port_range : "*" - destination_port_range = each.value.destination_port_range != "" ? each.value.destination_port_range : "*" - source_address_prefix = each.value.source_address_prefix != "" ? each.value.source_address_prefix : "*" - destination_address_prefix = each.value.destination_address_prefix != "" ? each.value.destination_address_prefix : "*" - resource_group_name = azurerm_network_security_group.nsg.resource_group_name - network_security_group_name = azurerm_network_security_group.nsg.name -} - -resource "azurerm_subnet_network_security_group_association" "nsg" { - subnet_id = azurerm_subnet.subnet.id - network_security_group_id = azurerm_network_security_group.nsg.id -} - -resource "azurerm_route_table" "routetable" { - name = var.routetable_name - resource_group_name = azurerm_subnet.subnet.resource_group_name - location = var.location - tags = var.tags -} - -resource "azurerm_route" "routetable" { - name = "default_route" - resource_group_name = azurerm_route_table.routetable.resource_group_name - route_table_name = azurerm_route_table.routetable.name - address_prefix = "0.0.0.0/0" - next_hop_type = "VirtualAppliance" - next_hop_in_ip_address = var.firewall_ip_address -} - -resource "azurerm_subnet_route_table_association" "routetable" { - subnet_id = azurerm_subnet.subnet.id - route_table_id = azurerm_route_table.routetable.id -} - -locals { - nsg_log_categories = ["NetworkSecurityGroupEvent", "NetworkSecurityGroupRuleCounter"] -} - -resource "azurerm_monitor_diagnostic_setting" "nsg" { - depends_on = [azurerm_network_security_group.nsg] - - name = "${azurerm_network_security_group.nsg.name}-nsg-diagnostics" - target_resource_id = azurerm_network_security_group.nsg.id - storage_account_id = var.log_analytics_storage_id - log_analytics_workspace_id = var.log_analytics_workspace_resource_id - - dynamic "log" { - for_each = local.nsg_log_categories - content { - category = log.value - enabled = true - - retention_policy { - days = 0 - enabled = false - } - } - } -} - -resource "azurerm_network_watcher_flow_log" "nsgfl" { - depends_on = [azurerm_network_security_rule.nsgrules, azurerm_network_security_group.nsg] - - name = var.name - network_watcher_name = "NetworkWatcher_${replace(var.location, " ", "")}" - resource_group_name = "NetworkWatcherRG" - - network_security_group_id = azurerm_network_security_group.nsg.id - storage_account_id = var.log_analytics_storage_id - enabled = true - version = 2 - - retention_policy { - enabled = true - days = var.flow_log_retention_in_days - } - - traffic_analytics { - enabled = true - workspace_id = var.log_analytics_workspace_id - workspace_region = var.log_analytics_workspace_location - workspace_resource_id = var.log_analytics_workspace_resource_id - interval_in_minutes = 10 - } -} diff --git a/src/terraform/modules/subnet/outputs.tf b/src/terraform/modules/subnet/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/modules/subnet/variables.tf b/src/terraform/modules/subnet/variables.tf deleted file mode 100644 index b503eac9c..000000000 --- a/src/terraform/modules/subnet/variables.tf +++ /dev/null @@ -1,103 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "name" { - description = "The name of the subnet" - type = string -} - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "resource_group_name" { - description = "The name of the subnet's resource group" - type = string -} - -variable "virtual_network_name" { - description = "The name of the subnet's virtual network" - type = string -} - -variable "address_prefixes" { - description = "The subnet address prefixes" - type = list(string) -} - -variable "service_endpoints" { - description = "The service endpoints to optimize for this subnet" - type = list(string) -} - -variable "private_endpoint_network_policies_enabled" { - description = "Enable or Disable network policies for the private endpoint on the subnet." - type = bool -} - -variable "private_link_service_network_policies_enabled" { - description = "Enable or Disable network policies for the private link service on the subnet." - type = bool -} - -variable "nsg_name" { - description = "The name of the subnet's virtual network" - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - type = map(string) -} - -variable "nsg_rules" { - description = "A collection of azurerm_network_security_rule" - type = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) -} - -variable "routetable_name" { - description = "The name of the subnet's route table" - type = string -} - -variable "firewall_ip_address" { - description = "The IP Address of the Firewall" - type = string -} - -variable "log_analytics_storage_id" { - description = "The id of the storage account that stores log analytics diagnostic logs" - type = string -} - -variable "log_analytics_workspace_id" { - description = "The id of the log analytics workspace" - type = string -} - -variable "log_analytics_workspace_location" { - description = "The location of the log analytics workspace" - type = string -} - -variable "log_analytics_workspace_resource_id" { - description = "The resource id of the log analytics workspace" - type = string -} - -variable "flow_log_retention_in_days" { - description = "The number of days to retain flow log data" - default = "7" - type = number -} diff --git a/src/terraform/modules/virtual-network/main.tf b/src/terraform/modules/virtual-network/main.tf deleted file mode 100644 index b0e2d5315..000000000 --- a/src/terraform/modules/virtual-network/main.tf +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -data "azurerm_resource_group" "rg" { - name = var.resource_group_name -} - -resource "azurerm_virtual_network" "vnet" { - name = var.vnet_name - location = var.location - resource_group_name = var.resource_group_name - address_space = var.vnet_address_space - tags = var.tags -} - -resource "random_id" "storageaccount" { - byte_length = 12 -} - -resource "azurerm_storage_account" "loganalytics" { - name = format("%.24s", lower(replace("${azurerm_virtual_network.vnet.name}logs${random_id.storageaccount.id}", "/[[:^alnum:]]/", ""))) - resource_group_name = var.resource_group_name - location = var.location - account_kind = "StorageV2" - account_tier = "Standard" - account_replication_type = "LRS" - enable_https_traffic_only = true - min_tls_version = "TLS1_2" - tags = var.tags -} diff --git a/src/terraform/modules/virtual-network/outputs.tf b/src/terraform/modules/virtual-network/outputs.tf deleted file mode 100644 index 7c68bc9ad..000000000 --- a/src/terraform/modules/virtual-network/outputs.tf +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -output "resource_group_name" { - description = "The name of the resource group in which resources are created" - value = data.azurerm_resource_group.rg.name -} - -output "resource_group_id" { - description = "The id of the resource group in which resources are created" - value = data.azurerm_resource_group.rg.id -} - -output "resource_group_location" { - description = "The location of the resource group in which resources are created" - value = data.azurerm_resource_group.rg.location -} - -output "virtual_network_name" { - description = "The name of the virtual network" - value = element(concat(azurerm_virtual_network.vnet.*.name, [""]), 0) -} - -output "virtual_network_id" { - description = "The id of the virtual network" - value = element(concat(azurerm_virtual_network.vnet.*.id, [""]), 0) -} - -output "virtual_network_address_space" { - description = "List of address spaces that are used the virtual network." - value = element(coalescelist(azurerm_virtual_network.vnet.*.address_space, [""]), 0) -} - -output "log_analytics_storage_id" { - description = "The id of the storage account that stores Log Analytics logs" - value = azurerm_storage_account.loganalytics.id -} diff --git a/src/terraform/modules/virtual-network/variables.tf b/src/terraform/modules/virtual-network/variables.tf deleted file mode 100644 index 52f61b639..000000000 --- a/src/terraform/modules/virtual-network/variables.tf +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "resource_group_name" { - description = "A container that holds related resources for an Azure solution" - type = string -} - -variable "vnet_name" { - description = "The name of the virtual network" - type = string -} - -variable "vnet_address_space" { - description = "The address space to be used for the virtual network" - type = list(string) -} - -variable "log_analytics_workspace_resource_id" { - description = "The resource ID of the Log Analytics Workspace to log events from the virtual network" - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - type = map(string) - default = {} -} diff --git a/src/terraform/modules/windows-virtual-machine/main.tf b/src/terraform/modules/windows-virtual-machine/main.tf deleted file mode 100644 index 21b2a8726..000000000 --- a/src/terraform/modules/windows-virtual-machine/main.tf +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -data "azurerm_resource_group" "vm_resource_group" { - name = var.resource_group_name -} - -data "azurerm_subnet" "vm_subnet" { - name = var.subnet_name - virtual_network_name = var.virtual_network_name - resource_group_name = var.resource_group_name -} - -resource "azurerm_network_interface" "windows_vm" { - name = "${var.name}_NIC" - resource_group_name = var.resource_group_name - location = var.location - - ip_configuration { - name = "${var.name}_IPCONFIG" - subnet_id = data.azurerm_subnet.vm_subnet.id - private_ip_address_allocation = "Dynamic" - } - - tags = var.tags -} - -resource "azurerm_windows_virtual_machine" "windows_vm" { - name = var.name - computer_name = substr(var.name, 0, 14) # computer_name can only be 15 characters maximum - resource_group_name = var.resource_group_name - location = var.location - size = var.size - admin_username = var.admin_username - admin_password = var.admin_password - network_interface_ids = [ - azurerm_network_interface.windows_vm.id, - ] - - os_disk { - caching = "ReadWrite" - storage_account_type = "StandardSSD_LRS" - } - - source_image_reference { - publisher = var.publisher - offer = var.offer - sku = var.sku - version = var.image_version - } - - tags = var.tags -} diff --git a/src/terraform/modules/windows-virtual-machine/outputs.tf b/src/terraform/modules/windows-virtual-machine/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/modules/windows-virtual-machine/variables.tf b/src/terraform/modules/windows-virtual-machine/variables.tf deleted file mode 100644 index 4ab36e38c..000000000 --- a/src/terraform/modules/windows-virtual-machine/variables.tf +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. - -variable "resource_group_name" { - description = "The name of the resource group the virtual machine resides in" - type = string -} - -variable "location" { - description = "The location/region to keep all your network resources. To get the list of all locations with table format from azure cli, run 'az account list-locations -o table'" - type = string -} - -variable "virtual_network_name" { - description = "The name of the virtual network the virtual machine resides in" - type = string -} - -variable "subnet_name" { - description = "The name of the subnet the virtual machine resides in" - type = string -} - -variable "name" { - description = "The name of the virtual machine" - type = string -} - -variable "size" { - description = "The size of the virtual machine" - type = string -} - -variable "admin_username" { - description = "The admin username of the virtual machine" - type = string -} - -variable "admin_password" { - description = "The admin password of the virtual machine" - type = string - sensitive = true -} - -variable "publisher" { - description = "The publisher of the virtual machine source image" - type = string -} - -variable "offer" { - description = "The offer of the virtual machine source image" - type = string -} - -variable "sku" { - description = "The SKU of the virtual machine source image" - type = string -} - -variable "image_version" { - description = "The version of the virtual machine source image" - type = string -} - -variable "tags" { - description = "A map of tags to add to all resources" - default = {} - type = map(string) -} diff --git a/src/terraform/tier3/main.tf b/src/terraform/tier3/main.tf deleted file mode 100644 index d52ba810a..000000000 --- a/src/terraform/tier3/main.tf +++ /dev/null @@ -1,188 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -terraform { - # It is recommended to use remote state instead of local - # If you are using Terraform Cloud, You can update these values in order to configure your remote state. - /* backend "remote" { - organization = "{{ORGANIZATION_NAME}}" - workspaces { - name = "{{WORKSPACE_NAME}}" - } - } - */ - backend "local" {} - - required_version = ">= 1.2.9" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "= 3.23.0" - } - } -} - -provider "azurerm" { - environment = var.environment - metadata_host = var.metadata_host - subscription_id = var.hub_subid - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "hub" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = var.hub_subid - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "tier1" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = var.tier1_subid - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -provider "azurerm" { - alias = "tier3" - environment = var.environment - metadata_host = var.metadata_host - subscription_id = var.tier3_subid - - features { - log_analytics_workspace { - permanently_delete_on_destroy = true - } - key_vault { - purge_soft_delete_on_destroy = true - } - } -} - -################################ -### STAGE 0: Scaffolding ### -################################ - -resource "azurerm_resource_group" "tier3" { - provider = azurerm.tier3 - - location = var.location - name = var.tier3_rgname - tags = var.tags -} - -################################ -### STAGE 1: Logging ### -################################ - -data "azurerm_log_analytics_workspace" "laws" { - provider = azurerm.tier1 - - name = var.laws_name - resource_group_name = var.laws_rgname -} - -// Central Logging -locals { - log_categories = ["Administrative", "Security", "ServiceHealth", "Alert", "Recommendation", "Policy", "Autoscale", "ResourceHealth"] -} - -resource "azurerm_monitor_diagnostic_setting" "tier3-central" { - count = var.tier3_subid != var.hub_subid ? 1 : 0 - provider = azurerm.tier3 - name = "tier3-central-diagnostics" - target_resource_id = "/subscriptions/${var.tier3_subid}" - - log_analytics_workspace_id = data.azurerm_log_analytics_workspace.laws.id - - dynamic "log" { - for_each = local.log_categories - content { - category = log.value - enabled = true - - retention_policy { - days = 0 - enabled = false - } - } - } -} - -################################ -### STAGE 2: Networking ### -################################ - -data "azurerm_virtual_network" "hub" { - name = var.hub_vnetname - resource_group_name = var.hub_rgname -} - -module "spoke-network-t3" { - providers = { azurerm = azurerm.tier3 } - depends_on = [azurerm_resource_group.tier3] - source = "../modules/spoke" - - location = azurerm_resource_group.tier3.location - - firewall_private_ip = var.firewall_private_ip - - laws_location = var.location - laws_workspace_id = data.azurerm_log_analytics_workspace.laws.workspace_id - laws_resource_id = data.azurerm_log_analytics_workspace.laws.id - - spoke_rgname = var.tier3_rgname - spoke_vnetname = var.tier3_vnetname - spoke_vnet_address_space = var.tier3_vnet_address_space - subnets = var.tier3_subnets - tags = var.tags -} - -resource "azurerm_virtual_network_peering" "t3-to-hub" { - provider = azurerm.tier3 - depends_on = [azurerm_resource_group.tier3, module.spoke-network-t3] - - name = "${var.tier3_vnetname}-to-${var.hub_vnetname}" - resource_group_name = var.tier3_rgname - virtual_network_name = var.tier3_vnetname - remote_virtual_network_id = data.azurerm_virtual_network.hub.id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} - -resource "azurerm_virtual_network_peering" "hub-to-t3" { - provider = azurerm.hub - depends_on = [module.spoke-network-t3] - - name = "${var.hub_vnetname}-to-${var.tier3_vnetname}" - resource_group_name = var.hub_rgname - virtual_network_name = var.hub_vnetname - remote_virtual_network_id = module.spoke-network-t3.virtual_network_id - allow_virtual_network_access = true - allow_forwarded_traffic = true -} diff --git a/src/terraform/tier3/outputs.tf b/src/terraform/tier3/outputs.tf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/terraform/tier3/variables.tf b/src/terraform/tier3/variables.tf deleted file mode 100644 index ec0ee4810..000000000 --- a/src/terraform/tier3/variables.tf +++ /dev/null @@ -1,165 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -################################# -# Global Configuration -################################# - -variable "environment" { - description = "The Terraform backend environment e.g. public or usgovernment" - type = string - default = "public" -} - -variable "metadata_host" { - description = "The metadata host for the Azure Cloud e.g. management.azure.com" - type = string - default = "management.azure.com" -} - -variable "location" { - description = "The Azure region for most Mission LZ resources" - type = string - default = "East US" -} - -variable "tags" { - description = "A map of key value pairs to apply as tags to resources provisioned in this deployment" - type = map(string) - default = { - "DeploymentType" : "MissionLandingZoneTF" - } -} - -################################# -# Hub Configuration -################################# - -variable "hub_subid" { - description = "Subscription ID for the Hub deployment" - type = string -} - -variable "hub_rgname" { - description = "Resource Group for the Hub deployment" - type = string -} - -variable "hub_vnetname" { - description = "Virtual Network Name for the Hub deployment" - type = string -} - -variable "firewall_private_ip" { - description = "Firewall IP to bind network to" - type = string -} - -################################# -# Tier 1 Configuration -################################# - -variable "tier1_subid" { - description = "Subscription ID for the Tier 1 deployment" - type = string -} - -variable "laws_name" { - description = "Log Analytics Workspace Name for the deployment" - type = string -} - -variable "laws_rgname" { - description = "The resource group that Log Analytics Workspace was deployed to" - type = string -} - -################################# -# Tier 3 Configuration -################################# -variable "tier3_subid" { - description = "Subscription ID for this Tier 3 deployment" - type = string -} - -variable "tier3_rgname" { - description = "Resource Group for this Tier 3 deployment" - type = string - default = "tier3-rg" -} - -variable "tier3_vnetname" { - description = "Virtual Network Name for this Tier 3 deployment" - type = string - default = "tier3-vnet" -} - -variable "tier3_vnet_address_space" { - description = "Address space prefixes list of strings" - type = list(string) - default = ["10.0.125.0/26"] -} - -variable "tier3_subnets" { - description = "A complex object that describes subnets." - type = map(object({ - name = string - address_prefixes = list(string) - service_endpoints = list(string) - - enforce_private_link_endpoint_network_policies = bool - enforce_private_link_service_network_policies = bool - - nsg_name = string - nsg_rules = map(object({ - name = string - priority = string - direction = string - access = string - protocol = string - source_port_range = string - destination_port_range = string - source_address_prefix = string - destination_address_prefix = string - })) - - routetable_name = string - })) - default = { - "tier3subnet" = { - name = "tier3Subnet" - address_prefixes = ["10.0.125.0/27"] - service_endpoints = ["Microsoft.Storage"] - - enforce_private_link_endpoint_network_policies = false - enforce_private_link_service_network_policies = false - - nsg_name = "tier3SubnetNsg" - nsg_rules = { - "allow_ssh" = { - name = "allow_ssh" - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "22" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - }, - "allow_rdp" = { - name = "allow_rdp" - priority = "200" - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "3389" - destination_port_range = "" - source_address_prefix = "*" - destination_address_prefix = "" - } - } - - routetable_name = "tier3RouteTable" - } - } -}