diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 5bb99e8792..403f4a8750 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -6,7 +6,7 @@ version: '3.7' services: rover: - image: aztfmod/rover:1.5.6-2309.0507 + image: aztfmod/rover:1.8.4-2405.2306 user: vscode labels: diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000000..09d6da5cd2 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,19 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/.github/workflows" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "devcontainers" # See documentation for possible values + directory: "/.devcontainer" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "terraform" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" \ No newline at end of file diff --git a/.github/workflows/developer.md b/.github/workflows/developer.md index 3f7ce7c58c..11baf95468 100644 --- a/.github/workflows/developer.md +++ b/.github/workflows/developer.md @@ -3,16 +3,17 @@ You can test the workflows on your local machine ## MacOS -Install act to run Github workflows on your local machine -``` +Install [Act](https://github.com/nektos/act) to run Github workflows on your local machine + +```bash brew install act ``` -from the root of the module +From the root of the module: -``` +```bash # Make sure you have a GH_TOKEN with repo and workflow privileges -export GH_TOKEN=xxx +export GH_TOKEN="$(gh auth token)" act --container-architecture linux/arm64 \ -s GITHUB_TOKEN=$GITHUB_TOKEN \ diff --git a/.github/workflows/landingzone-scenarios.yaml b/.github/workflows/landingzone-scenarios.yaml index 29e43f4e44..d09ef13ac1 100644 --- a/.github/workflows/landingzone-scenarios.yaml +++ b/.github/workflows/landingzone-scenarios.yaml @@ -46,7 +46,7 @@ jobs: outputs: jobs: ${{ steps.load_scenarios.outputs.jobs }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - id: load_scenarios run: | jobs=$( cat ./.github/workflows/${{ github.event.inputs.scenario }} | jq -c .) @@ -86,7 +86,7 @@ jobs: needs: [job] container: - image: aztfmod/rover:1.5.7-2310.0211 + image: aztfmod/rover:1.8.4-2405.2306 options: --user 0 steps: diff --git a/.github/workflows/on_push_fmt.yaml b/.github/workflows/on_push_fmt.yaml new file mode 100644 index 0000000000..ab5af599a4 --- /dev/null +++ b/.github/workflows/on_push_fmt.yaml @@ -0,0 +1,34 @@ +name: Terraform Format + +on: + push: + branches: + - main + +jobs: + terraform: + name: 'Terraform Format' + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Important: This is needed to push changes back to the repository + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + + - name: Terraform Format + run: terraform fmt -recursive + + - name: Commit changes + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git diff --quiet && git diff --staged --quiet || (git add -A && git commit -m "Apply terraform fmt") + + - name: Push changes + uses: ad-m/github-push-action@v0.8.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pr_lint.yaml b/.github/workflows/pr_lint.yaml new file mode 100644 index 0000000000..cdf8b68fef --- /dev/null +++ b/.github/workflows/pr_lint.yaml @@ -0,0 +1,46 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR Tflint + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + +env: + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + linting: + name: Format and Lint Checks + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Install Terraform Linter + uses: terraform-linters/setup-tflint@v4 + with: + tflint_version: ${{ env.TF_LINT_VERSION }} + + - name: Run TFLint with reviewdog + uses: reviewdog/action-tflint@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + reporter: github-pr-check + level: info + tflint_init: true diff --git a/.github/workflows/pr_tests-azuread.yaml b/.github/workflows/pr_tests-azuread.yaml new file mode 100644 index 0000000000..4b82311ca0 --- /dev/null +++ b/.github/workflows/pr_tests-azuread.yaml @@ -0,0 +1,96 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR azuread-tests + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'azuread*' + - 'modules/azuread/**' + - 'examples/azuread/**' + - '.github/workflows/*azuread.*' + +env: + SCENARIO: standalone-azuread.json + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + load_scenarios: + name: Load Test Scenarios Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.load_scenarios.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - id: load_scenarios + run: | + cases=$(cat ./.github/workflows/${{ env.SCENARIO }} | jq -c .) + echo "matrix=${cases}" >> $GITHUB_OUTPUT + + mock_plan_scenarios: + name: ${{ matrix.config_files }} + runs-on: ubuntu-latest + needs: load_scenarios + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=examples \ + init + + - name: Terraform Test example + id: tf_test + run: | + terraform -chdir=examples \ + test \ + -test-directory=./tests/mock \ + ${{ env.PARAMETER_FILES }} \ + -verbose \ No newline at end of file diff --git a/.github/workflows/pr_tests-compute.yaml b/.github/workflows/pr_tests-compute.yaml new file mode 100644 index 0000000000..7b4678b323 --- /dev/null +++ b/.github/workflows/pr_tests-compute.yaml @@ -0,0 +1,96 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR compute-tests + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'compute_*' + - 'modules/compute/**' + - 'examples/compute/**' + - '.github/workflows/*compute.*' + +env: + SCENARIO: standalone-compute.json + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + load_scenarios: + name: Load Test Scenarios Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.load_scenarios.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - id: load_scenarios + run: | + cases=$(cat ./.github/workflows/${{ env.SCENARIO }} | jq -c .) + echo "matrix=${cases}" >> $GITHUB_OUTPUT + + mock_plan_scenarios: + name: ${{ matrix.config_files }} + runs-on: ubuntu-latest + needs: load_scenarios + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=examples \ + init + + - name: Terraform Test example + id: tf_test + run: | + terraform -chdir=examples \ + test \ + -test-directory=./tests/mock \ + ${{ env.PARAMETER_FILES }} \ + -verbose \ No newline at end of file diff --git a/.github/workflows/pr_tests-dataplat.yaml b/.github/workflows/pr_tests-dataplat.yaml new file mode 100644 index 0000000000..6c1ed84706 --- /dev/null +++ b/.github/workflows/pr_tests-dataplat.yaml @@ -0,0 +1,102 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR dataplat-tests + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'mssql*' + - 'modules/analytics/**' + - 'modules/databases/**' + - 'modules/data_factory/**' + - 'modules/purview/**' + - 'examples/analytics/**' + - 'examples/databases/**' + - 'examples/data_factory/**' + - 'examples/purview/**' + - '.github/workflows/*dataplat.*' + +env: + SCENARIO: standalone-dataplat.json + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + load_scenarios: + name: Load Test Scenarios Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.load_scenarios.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - id: load_scenarios + run: | + cases=$(cat ./.github/workflows/${{ env.SCENARIO }} | jq -c .) + echo "matrix=${cases}" >> $GITHUB_OUTPUT + + mock_plan_scenarios: + name: ${{ matrix.config_files }} + runs-on: ubuntu-latest + needs: load_scenarios + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=examples \ + init + + - name: Terraform Test example + id: tf_test + run: | + terraform -chdir=examples \ + test \ + -test-directory=./tests/mock \ + ${{ env.PARAMETER_FILES }} \ + -verbose \ No newline at end of file diff --git a/.github/workflows/pr_tests-networking.yaml b/.github/workflows/pr_tests-networking.yaml new file mode 100644 index 0000000000..0f8579c651 --- /dev/null +++ b/.github/workflows/pr_tests-networking.yaml @@ -0,0 +1,96 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR networking-tests + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + paths: + - 'network*' + - 'modules/networking/**' + - 'examples/networking/**' + - '.github/workflows/*networking.*' + +env: + SCENARIO: standalone-networking.json + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + load_scenarios: + name: Load Test Scenarios Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.load_scenarios.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - id: load_scenarios + run: | + cases=$(cat ./.github/workflows/${{ env.SCENARIO }} | jq -c .) + echo "matrix=${cases}" >> $GITHUB_OUTPUT + + mock_plan_scenarios: + name: ${{ matrix.config_files }} + runs-on: ubuntu-latest + needs: load_scenarios + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=examples \ + init + + - name: Terraform Test example + id: tf_test + run: | + terraform -chdir=examples \ + test \ + -test-directory=./tests/mock \ + ${{ env.PARAMETER_FILES }} \ + -verbose \ No newline at end of file diff --git a/.github/workflows/pr_tests-scenarios.yaml b/.github/workflows/pr_tests-scenarios.yaml new file mode 100644 index 0000000000..5c1f2c2f55 --- /dev/null +++ b/.github/workflows/pr_tests-scenarios.yaml @@ -0,0 +1,92 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR all-tests + +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + +env: + SCENARIO: standalone-scenarios.json + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + load_scenarios: + name: Load Test Scenarios Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.load_scenarios.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + + - id: load_scenarios + run: | + cases=$(cat ./.github/workflows/${{ env.SCENARIO }} | jq -c .) + echo "matrix=${cases}" >> $GITHUB_OUTPUT + + mock_plan_scenarios: + name: ${{ matrix.config_files }} + runs-on: ubuntu-latest + needs: load_scenarios + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=examples \ + init + + - name: Terraform Test example + id: tf_test + run: | + terraform -chdir=examples \ + test \ + -test-directory=./tests/mock \ + ${{ env.PARAMETER_FILES }} \ + -verbose \ No newline at end of file diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 2fa5da4d75..322c5883d0 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: # Drafts your next Release notes as Pull Requests are merged into "master" - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@v6 #with: # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml # config-name: my-config.yml diff --git a/.github/workflows/rover.yaml b/.github/workflows/rover.yaml index 0b37069de5..3a60486cf1 100644 --- a/.github/workflows/rover.yaml +++ b/.github/workflows/rover.yaml @@ -46,7 +46,7 @@ jobs: needs: rover_setup container: - image: aztfmod/rover:1.5.7-2310.0211 + image: aztfmod/rover:1.8.4-2405.2306 options: --user 0 env: @@ -58,7 +58,7 @@ jobs: ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set Environment Variables run: | diff --git a/.github/workflows/standalone-scenarios-azuread.json b/.github/workflows/standalone-azuread.json similarity index 100% rename from .github/workflows/standalone-scenarios-azuread.json rename to .github/workflows/standalone-azuread.json diff --git a/.github/workflows/standalone-compute.json b/.github/workflows/standalone-compute.json index 8a3692d4da..a1effb7e50 100644 --- a/.github/workflows/standalone-compute.json +++ b/.github/workflows/standalone-compute.json @@ -2,13 +2,16 @@ "config_files": [ "compute/availability_set/100-simple-availabilityset", "compute/availability_set/101-availabilityset-with-proximity-placement-group", - "compute/azure_virtual_desktop/wvd_resources", "compute/azure_redhat_openshift/101_basic_private_cluster", "compute/azure_redhat_openshift/102_basic_public_cluster", + "compute/azure_virtual_desktop/wvd_resources", "compute/batch/batch_account/100-batch-account-storage", "compute/batch/batch_account/100-batch-account", "compute/batch/batch_account/200-batch-account-private-endpoint", "compute/batch/batch_application/100-batch-application", + "compute/container_app/101-simple-container-app-env", + "compute/container_app/102-simple-private-container-app-env", + "compute/container_app/103-private-container-app-env", "compute/container_groups/100-aci-rover-github-runner", "compute/container_groups/101-aci-nginx", "compute/container_registry/100-simple-acr", @@ -23,6 +26,7 @@ "compute/kubernetes_services/105-cluster-usermsi", "compute/kubernetes_services/107-agic-brownfield", "compute/kubernetes_services/108-single-cluster-remote-adgroup-admin", + "compute/kubernetes_services/109-single-cluster-istio", "compute/proximity_placement_group", "compute/virtual_machine_scale_set/100-linux-win-vmss-lb", "compute/virtual_machine_scale_set/101-linux-win-vmss-agw", @@ -45,6 +49,7 @@ "compute/virtual_machine/214-vm-generic_extensions_complex", "compute/virtual_machine/215-vm-keyvault-for-windows-extension", "compute/virtual_machine/216-vm-linux_diagnostic_extensions", - "compute/virtual_machine/217-vm-disk-encryption-set-msi" + "compute/virtual_machine/217-vm-disk-encryption-set-msi", + "compute/vmware_cluster/101-vmware_cluster" ] } diff --git a/.github/workflows/standalone-compute.yaml b/.github/workflows/standalone-compute.yaml deleted file mode 100644 index addc4b4ad5..0000000000 --- a/.github/workflows/standalone-compute.yaml +++ /dev/null @@ -1,152 +0,0 @@ -# -# Copyright (c) Microsoft Corporation -# Licensed under the MIT License. -# - -name: standalone-compute - -on: - push: - paths: - - 'compute_*' - - 'modules/compute/**' - - 'examples/compute/**' - - '.github/workflows/*compute.*' - -env: - TF_CLI_ARGS: "-no-color" - TF_CLI_ARGS_destroy: "-auto-approve -refresh=false" - ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }} - ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} - ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} - ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} - TF_REGISTRY_DISCOVERY_RETRY: 5 - TF_REGISTRY_CLIENT_TIMEOUT: 15 - ROVER_RUNNER: true - -jobs: - load_scenarios: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.load_scenarios.outputs.matrix }} - steps: - - uses: actions/checkout@v3 - - id: load_scenarios - run: | - cases=$(cat ./.github/workflows/standalone-compute.json | jq -c .) - echo "matrix=${cases}" >> $GITHUB_OUTPUT - - testcases: - name: test - runs-on: ubuntu-latest - needs: load_scenarios - - strategy: - fail-fast: false - matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} - - container: - image: aztfmod/rover:1.5.7-2310.0211 - options: --user 0 - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Create environment variables - run: | - cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} - FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) - echo STATE_FILE=${TF_DATA_DIR}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV - echo PLAN_FILE=${TF_DATA_DIR}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV - echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV - echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV - - - name: Login azure - run: | - az login --service-principal -u '${{ env.ARM_CLIENT_ID }}' -p '${{ env.ARM_CLIENT_SECRET }}' --tenant '${{ env.ARM_TENANT_ID }}' - az account set -s ${{ env.ARM_SUBSCRIPTION_ID }} - - - name: Terraform Init example - id: tf_init - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - init -upgrade=true | grep -P '^- (?=Downloading|Using|Finding|Installing)|^[^-]' - - - name: Terraform Plan example - id: tf_plan - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - plan \ - ${{ env.PARAMETER_FILES }} \ - -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ - -var var_folder_path=${{ env.CURRENT_FOLDER }} \ - -refresh=true \ - -input=false \ - -state=${{ env.STATE_FILE }} \ - -out=${{ env.PLAN_FILE }} - - - name: Terraform Apply example - id: tf_apply - if: steps.tf_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - apply \ - -parallelism=30 \ - -state=${{ env.STATE_FILE }} \ - ${{ env.PLAN_FILE }} - - - name: Terraform Destroy planning example - id: tf_destroy_plan - if: steps.tf_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - plan \ - ${{ env.PARAMETER_FILES }} \ - -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ - -var var_folder_path=${{ env.CURRENT_FOLDER }} \ - -refresh=true \ - -input=false \ - -destroy \ - -state=${{ env.STATE_FILE }} \ - -out=${{ env.PLAN_FILE }}-destroy - - - name: Terraform Destroy apply example - id: tf_destroy_apply - if: steps.tf_destroy_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - apply \ - -refresh=false \ - -parallelism=30 \ - -auto-approve \ - -state=${{ env.STATE_FILE }} \ - ${{ env.PLAN_FILE }}-destroy - - purge: - name: purge - runs-on: ubuntu-latest - if: ${{ failure() || cancelled() }} - - needs: [testcases] - - container: - image: aztfmod/rover:1.5.7-2310.0211 - options: --user 0 - - steps: - - name: Login azure - run: | - az login --service-principal -u '${{ env.ARM_CLIENT_ID }}' -p '${{ env.ARM_CLIENT_SECRET }}' --tenant '${{ env.ARM_TENANT_ID }}' - az account set -s ${{ env.ARM_SUBSCRIPTION_ID }} - - - name: Complete purge - run: | - for i in `az monitor diagnostic-settings subscription list -o tsv --query "value[?contains(name, '${{ github.run_id }}' )].name"`; do echo "purging subscription diagnostic-settings: $i" && $(az monitor diagnostic-settings subscription delete --name $i --yes); done - for i in `az monitor log-profiles list -o tsv --query '[].name'`; do az monitor log-profiles delete --name $i; done - for i in `az ad group list --query "[?contains(displayName, '${{ github.run_id }}')].id" -o tsv`; do echo "purging Azure AD group: $i" && $(az ad group delete --verbose --group $i || true); done - for i in `az ad app list --query "[?contains(displayName, '${{ github.run_id }}')].appId" -o tsv`; do echo "purging Azure AD app: $i" && $(az ad app delete --verbose --id $i || true); done - for i in `az keyvault list-deleted --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do az keyvault purge --name $i; done - for i in `az group list --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do echo "purging resource group: $i" && $(az group delete -n $i -y --no-wait || true); done - for i in `az role assignment list --query "[?contains(roleDefinitionName, '${{ github.run_id }}')].roleDefinitionName" -o tsv`; do echo "purging role assignment: $i" && $(az role assignment delete --role $i || true); done - for i in `az role definition list --query "[?contains(roleName, '${{ github.run_id }}')].roleName" -o tsv`; do echo "purging custom role definition: $i" && $(az role definition delete --name $i || true); done diff --git a/.github/workflows/standalone-dataplat.json b/.github/workflows/standalone-dataplat.json new file mode 100644 index 0000000000..1a1a565a55 --- /dev/null +++ b/.github/workflows/standalone-dataplat.json @@ -0,0 +1,76 @@ +{ + "config_files": [ + "cosmos_db/100-cosmos-db-sql-role-mapping", + "cosmos_db/100-simple-cosmos-db-cassandra", + "cosmos_db/100-simple-cosmos-db-gremlin", + "cosmos_db/100-simple-cosmos-db-mongo", + "cosmos_db/100-simple-cosmos-db-sql", + "cosmos_db/100-simple-cosmos-db-table", + "cosmos_db/101-decomposed-cosmosdb-sql", + "cosmos_db/101-private-endpoint-cosmos-db", + "data_explorer/101-kusto_clusters_basic", + "data_explorer/102-kusto_clusters_vnet", + "data_explorer/103-kusto_clusters_identity", + "data_explorer/104-kusto_cluster_database", + "data_explorer/105-kusto_attached_database_configuration", + "data_explorer/106-database_principal_assignment", + "data_explorer/107-private-endpoint", + "data_factory/101-data_factory", + "data_factory/102-data_factory_pipeline", + "data_factory/103-data_factory_trigger_schedule", + "data_factory/104-data_factory_dataset_azure_blob", + "data_factory/105-data_factory_dataset_cosmosdb_sqlapi", + "data_factory/106-data_factory_dataset_delimited_text", + "data_factory/107-data_factory_dataset_http", + "data_factory/108-data_factory_dataset_json", + "data_factory/109-data_factory_dataset_mysql", + "data_factory/110-data_factory_dataset_postgresql", + "data_factory/111-data_factory_dataset_sql_server_table", + "data_factory/112-data_factory_integration_runtime_azure_ssis", + "data_factory/113-data_factory_integration_runtime_azure_ssis_mssql_server", + "data_factory/114-data_factory_integration_runtime_self_hosted", + "data_factory/115-data_factory_runtime_self_hoste_databricks", + "data_factory/116-data_factory_linked_service_azure_databricks", + "data_protection/100-backup-vault-blob-storage", + "data_protection/101-backup-vault-disk", + "database_migration_services/100-dms", + "databricks/100-standard-databricks-no-vnet", + "databricks/101-standard-databricks-vnet", + "databricks/102-premium-aml", + "databricks/102-premium-databricks-vnet-private-endpoint", + "datalake/101-datalake-storage", + "machine_learning/100-aml", + "machine_learning/101-aml-vnet", + "machine_learning/102-aml-compute_instance", + "mariadb_server/100-simple-mariadb", + "mariadb_server/101-vnet-rule-mariadb", + "mariadb_server/102-private-endpoint-mariadb", + "mariadb_server/103-private-endpoint-with-fw-rule-mariadb", + "mssql_mi/200-mi", + "mssql_server/101-sqlserver-simple", + "mssql_server/102-sqlserver-extend", + "mssql_server/104-sqlserver-elastic_pools", + "mssql_server/105-sqlserver-failover_groups", + "mssql_server/107-sqlserver-db-retention-policy", + "mssql_server/108-sqlserver-db-diagnostics", + "mssql_server/109-sqlserver-network-firewall-rule", + "mysql_flexible_server/100-simple-mysql-flexible", + "mysql_flexible_server/101-delegated-subnet-with-fw-rule", + "mysql_flexible_server/102-advanced-mysql-flexible", + "mysql_server/100-simple-mysql", + "mysql_server/101-vnet-rule-mysql", + "mysql_server/102-private-endpoint-mysql", + "mysql_server/103-private-endpoint-with-fw-rule-mysql", + "postgresql_flexible_server/100-simple-postgresql-flexible", + "postgresql_flexible_server/101-delegated-subnet-with-fw-rule", + "postgresql_flexible_server/102-advanced-postgresql-flexible", + "postgresql_flexible_server/104-private-endpoint", + "postgresql_server/100-simple-postgresql", + "postgresql_server/101-vnet-rule-postgresql", + "postgresql_server/102-private-endpoint-postgresql", + "postgresql_server/103-private-endpoint-with-fw-rule", + "powerbi_embedded/100-simple-powerbi", + "purview/100-purview_account", + "purview/101-purview_account_private_link" + ] +} diff --git a/.github/workflows/standalone-networking.json b/.github/workflows/standalone-networking.json index c1a3a787c9..0697afeee1 100644 --- a/.github/workflows/standalone-networking.json +++ b/.github/workflows/standalone-networking.json @@ -36,6 +36,10 @@ "networking/private_dns/100-private-dns-vnet-links", "networking/private_links/endpoints/centralized", "networking/private_links/endpoints/static_ip", + "networking/virtual_network_gateway/100-expressroute-gateway", + "networking/virtual_network_gateway/101-vpn-site-to-site", + "networking/virtual_network_gateway/102-vpn-site-to-site-active-active", + "networking/virtual_network_gateway/103-vpn-site-to-site-connection", "networking/virtual_network/100-import-rg", "networking/virtual_network/100-simple-vnet-subnets-nsgs", "networking/virtual_network/100-subnet-delegation", @@ -44,7 +48,16 @@ "networking/virtual_network/201-nsg-flow-logs-v1", "networking/virtual_subnets/100-simple-subnet-rbac", "networking/virtual_wan/100-vwan-multi-hubs", + "networking/virtual_wan/101-vwan-hub-firewall-legacy", + "networking/virtual_wan/102-vwan-hub-firewall-secured-vhub", + "networking/virtual_wan/102a-vwan-hub-firewall-secured-vhub-fw-mgr", + "networking/virtual_wan/103-vwan-hub-gw-legacy", + "networking/virtual_wan/104-vwan-hub-gw-spp", + "networking/virtual_wan/105-vwan-hub-route-table", "networking/virtual_wan/106-vwan-hub-routes", - "networking/virtual_wan/108-vwan-vpn-site" + "networking/virtual_wan/108-vwan-vpn-site", + "networking/virtual_wan/109-vwan-vpn-gateway-connection", + "networking/virtual_wan/110-vwan-hub-gw-p2s-keyvault-cert", + "networking/virtual_wan/111-vwan-vpn-gateway-connection-with-nat" ] } diff --git a/.github/workflows/standalone-networking.yaml b/.github/workflows/standalone-networking.yaml deleted file mode 100644 index 1993780eca..0000000000 --- a/.github/workflows/standalone-networking.yaml +++ /dev/null @@ -1,152 +0,0 @@ -# -# Copyright (c) Microsoft Corporation -# Licensed under the MIT License. -# - -name: standalone-networking - -on: - push: - paths: - - 'network*' - - 'modules/networking/**' - - 'examples/networking/**' - - '.github/workflows/*networking.*' - -env: - TF_CLI_ARGS: "-no-color" - TF_CLI_ARGS_destroy: "-auto-approve -refresh=false" - ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }} - ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} - ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} - ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} - TF_REGISTRY_DISCOVERY_RETRY: 5 - TF_REGISTRY_CLIENT_TIMEOUT: 15 - ROVER_RUNNER: true - -jobs: - load_scenarios: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.load_scenarios.outputs.matrix }} - steps: - - uses: actions/checkout@v3 - - id: load_scenarios - run: | - cases=$(cat ./.github/workflows/standalone-networking.json | jq -c .) - echo "matrix=${cases}" >> $GITHUB_OUTPUT - - testcases: - name: test - runs-on: ubuntu-latest - needs: load_scenarios - - strategy: - fail-fast: false - matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} - - container: - image: aztfmod/rover:1.5.7-2310.0211 - options: --user 0 - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Create environment variables - run: | - cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} - FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) - echo STATE_FILE=${TF_DATA_DIR}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV - echo PLAN_FILE=${TF_DATA_DIR}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV - echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV - echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV - - - name: Login azure - run: | - az login --service-principal -u '${{ env.ARM_CLIENT_ID }}' -p '${{ env.ARM_CLIENT_SECRET }}' --tenant '${{ env.ARM_TENANT_ID }}' - az account set -s ${{ env.ARM_SUBSCRIPTION_ID }} - - - name: Terraform Init example - id: tf_init - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - init -upgrade=true | grep -P '^- (?=Downloading|Using|Finding|Installing)|^[^-]' - - - name: Terraform Plan example - id: tf_plan - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - plan \ - ${{ env.PARAMETER_FILES }} \ - -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ - -var var_folder_path=${{ env.CURRENT_FOLDER }} \ - -refresh=true \ - -input=false \ - -state=${{ env.STATE_FILE }} \ - -out=${{ env.PLAN_FILE }} - - - name: Terraform Apply example - id: tf_apply - if: steps.tf_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - apply \ - -parallelism=30 \ - -state=${{ env.STATE_FILE }} \ - ${{ env.PLAN_FILE }} - - - name: Terraform Destroy planning example - id: tf_destroy_plan - if: steps.tf_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - plan \ - ${{ env.PARAMETER_FILES }} \ - -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ - -var var_folder_path=${{ env.CURRENT_FOLDER }} \ - -refresh=true \ - -input=false \ - -destroy \ - -state=${{ env.STATE_FILE }} \ - -out=${{ env.PLAN_FILE }}-destroy - - - name: Terraform Destroy apply example - id: tf_destroy_apply - if: steps.tf_destroy_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - apply \ - -refresh=false \ - -parallelism=30 \ - -auto-approve \ - -state=${{ env.STATE_FILE }} \ - ${{ env.PLAN_FILE }}-destroy - - purge: - name: purge - runs-on: ubuntu-latest - if: ${{ failure() || cancelled() }} - - needs: [testcases] - - container: - image: aztfmod/rover:1.5.7-2310.0211 - options: --user 0 - - steps: - - name: Login azure - run: | - az login --service-principal -u '${{ env.ARM_CLIENT_ID }}' -p '${{ env.ARM_CLIENT_SECRET }}' --tenant '${{ env.ARM_TENANT_ID }}' - az account set -s ${{ env.ARM_SUBSCRIPTION_ID }} - - - name: Complete purge - run: | - for i in `az monitor diagnostic-settings subscription list -o tsv --query "value[?contains(name, '${{ github.run_id }}' )].name"`; do echo "purging subscription diagnostic-settings: $i" && $(az monitor diagnostic-settings subscription delete --name $i --yes); done - for i in `az monitor log-profiles list -o tsv --query '[].name'`; do az monitor log-profiles delete --name $i; done - for i in `az ad group list --query "[?contains(displayName, '${{ github.run_id }}')].id" -o tsv`; do echo "purging Azure AD group: $i" && $(az ad group delete --verbose --group $i || true); done - for i in `az ad app list --query "[?contains(displayName, '${{ github.run_id }}')].appId" -o tsv`; do echo "purging Azure AD app: $i" && $(az ad app delete --verbose --id $i || true); done - for i in `az keyvault list-deleted --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do az keyvault purge --name $i; done - for i in `az group list --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do echo "purging resource group: $i" && $(az group delete -n $i -y --no-wait || true); done - for i in `az role assignment list --query "[?contains(roleDefinitionName, '${{ github.run_id }}')].roleDefinitionName" -o tsv`; do echo "purging role assignment: $i" && $(az role assignment delete --role $i || true); done - for i in `az role definition list --query "[?contains(roleName, '${{ github.run_id }}')].roleName" -o tsv`; do echo "purging custom role definition: $i" && $(az role definition delete --name $i || true); done diff --git a/.github/workflows/standalone-regressor-tf100.yaml b/.github/workflows/standalone-regressor-tf100.yaml index c5efcfd152..60bf4d639b 100644 --- a/.github/workflows/standalone-regressor-tf100.yaml +++ b/.github/workflows/standalone-regressor-tf100.yaml @@ -18,11 +18,10 @@ on: type: choice default: 'standalone-scenarios.json' options: - - standalone-scenarios-azuread.json + - standalone-azuread.json - standalone-scenarios.json - standalone-compute.json - standalone-networking.json - - standalone-scenarios-longrunners.json env: TF_CLI_ARGS: '-no-color' @@ -41,7 +40,7 @@ jobs: outputs: matrix: ${{ steps.load_scenarios.outputs.matrix }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - id: load_scenarios run: | cases=$(( @@ -58,12 +57,12 @@ jobs: matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} container: - image: aztfmod/rover:1.5.7-2310.0211 + image: aztfmod/rover:1.8.4-2405.2306 options: --user 0 steps: - name: Checkout with tag ${{ github.event.inputs.base_version }} - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ github.event.inputs.base_version }} @@ -107,7 +106,7 @@ jobs: ${{ env.PLAN_FILE }} - name: Checkout from selected branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Terraform Init example with selected branch run: | @@ -178,7 +177,7 @@ jobs: needs: [testcases] container: - image: aztfmod/rover:1.5.7-2310.0211 + image: aztfmod/rover:1.8.4-2405.2306 options: --user 0 steps: diff --git a/.github/workflows/standalone-scenarios-additional.json b/.github/workflows/standalone-scenarios-additional.json index 2e0450829d..61d601e344 100644 --- a/.github/workflows/standalone-scenarios-additional.json +++ b/.github/workflows/standalone-scenarios-additional.json @@ -1,6 +1,7 @@ { "config_files": [ "cognitive_services/100-cognitive-services-account", + "cognitive_services/101-cognitive-services-account-managed-identity", "compute/batch/batch_certificate/100-batch-certificate - path", "compute/batch/batch_job/100-batch-job - quotas", "compute/batch/batch_pool/100-batch-pool - quotas", @@ -14,11 +15,6 @@ "consumption_budget/105-consumption-budget-subscription-aks", "messaging/signalr/100-signalr-simple", "mssql_mi/200-mi-two-regions", - "networking/virtual_network_gateway/100-expressroute-gateway", - "networking/virtual_network_gateway/101-vpn-site-to-site", - "networking/virtual_network_gateway/102-vpn-site-to-site-active-active", - "networking/virtual_network_gateway/103-vpn-site-to-site-connection", - "networking/virtual_wan/100-vwan-multi-hubs", "networking/virtual_wan/101-vwan-hub-firewall-legacy", "networking/virtual_wan/102-vwan-hub-firewall-new", "networking/virtual_wan/103-vwan-hub-gw", diff --git a/.github/workflows/standalone-scenarios-longrunners.json b/.github/workflows/standalone-scenarios-longrunners.json deleted file mode 100644 index 653d5955ce..0000000000 --- a/.github/workflows/standalone-scenarios-longrunners.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "config_files": [ - "apim/100-basic", - "apim/101-api", - "apim/102-diagnostics", - "apim/103-api_operations", - "apim/104-backend", - "apim/105-api_policy", - "apim/106-api_operation_tag", - "apim/107-api_operation_policy", - "apim/108-api_management_user", - "apim/110-api_management_diagnostic", - "apim/111-api_management_certificate", - "apim/112-api_management_gateway", - "apim/113-api_management_gateway_api", - "apim/114-api-management-group", - "apim/115-api_management_private_virtual_network", - "apim/116-api_management_subscription", - "apim/117-api_management_product", - "app_gateway/301-agw-v1", - "compute/vmware_cluster/101-vmware_cluster", - "networking/virtual_network_gateway/100-expressroute-gateway", - "networking/virtual_network_gateway/101-vpn-site-to-site", - "networking/virtual_network_gateway/102-vpn-site-to-site-active-active", - "networking/virtual_network_gateway/103-vpn-site-to-site-connection", - "networking/virtual_wan/101-vwan-hub-firewall-legacy", - "networking/virtual_wan/102-vwan-hub-firewall-secured-vhub", - "networking/virtual_wan/102a-vwan-hub-firewall-secured-vhub-fw-mgr", - "networking/virtual_wan/103-vwan-hub-gw-legacy", - "networking/virtual_wan/104-vwan-hub-gw-spp", - "networking/virtual_wan/105-vwan-hub-route-table", - "networking/virtual_wan/109-vwan-vpn-gateway-connection", - "redis_cache/100-redis-standard", - "redis_cache/101-redis-diagnostics", - "redis_cache/102-redis-private", - "webapps/appservice-environment/102-simple_asev3" - ] -} diff --git a/.github/workflows/standalone-scenarios.json b/.github/workflows/standalone-scenarios.json index 4b15d939ea..6f6380c0bf 100644 --- a/.github/workflows/standalone-scenarios.json +++ b/.github/workflows/standalone-scenarios.json @@ -1,5 +1,23 @@ { "config_files": [ + "apim/100-basic", + "apim/101-api", + "apim/102-diagnostics", + "apim/103-api_operations", + "apim/104-backend", + "apim/105-api_policy", + "apim/106-api_operation_tag", + "apim/107-api_operation_policy", + "apim/108-api_management_user", + "apim/110-api_management_diagnostic", + "apim/111-api_management_certificate", + "apim/112-api_management_gateway", + "apim/113-api_management_gateway_api", + "apim/114-api-management-group", + "apim/115-api_management_private_virtual_network", + "apim/116-api_management_subscription", + "apim/117-api_management_product", + "apim/118-api_management_platform_stv2", "app_config/100-simple", "app_config/101-private-link", "app_insights/100-all-attributes", @@ -21,6 +39,7 @@ "azuread/105-azuread-application-with-optional-claims", "azuread/201-groups-and-roles", "communication/communication_services/101-communication_service", + "diagnostics_profiles/100-multiple-destinations", "compute/availability_set/100-simple-availabilityset", "compute/availability_set/101-availabilityset-with-proximity-placement-group", "compute/azure_virtual_desktop/wvd_resources", @@ -67,7 +86,6 @@ "cosmos_db/100-simple-cosmos-db-mongo", "cosmos_db/100-simple-cosmos-db-sql", "cosmos_db/100-simple-cosmos-db-table", - "cosmos_db/100-cosmos-db-sql-role-mapping", "cosmos_db/101-decomposed-cosmosdb-sql", "cosmos_db/101-private-endpoint-cosmos-db", "data_explorer/101-kusto_clusters_basic", @@ -103,27 +121,27 @@ "diagnostics_profiles/100-multiple-destinations", "diagnostics_profiles/101-log-analytics-destination-type-profile", "diagnostics_profiles/200-diagnostics-eventhub-namespaces", + "diagnostics_profiles/200-diagnostics-eventhub-namespaces", + "diagnostics_profiles/201-multi-eventhub-diagnostics", "diagnostics_profiles/201-multi-eventhub-diagnostics", "digital_twins/100-basic", "digital_twins/101-adt-servicebus", "digital_twins/102-digital_twins_instance_eventhub", - "diagnostics_profiles/100-multiple-destinations", - "diagnostics_profiles/200-diagnostics-eventhub-namespaces", - "diagnostics_profiles/201-multi-eventhub-diagnostics", "eventhub/100-simple-eventhub-namespace", "eventhub/101-evh-namespace-with-private-endpoint", "eventhub/102-namespace-and-evh-with-auth-rules", "eventhub/103-eventhub-consumer-groups", "eventhub/104-namespace-and-evh-with-storage", - "keyvault/101-keyvault-policies", - "keyvault/102-keyvault-cert-issuer", - "keyvault/104-keyvault-dynamic-secret", - "keyvault/105-keyvault-dynamic-certificate", "iot/100-iot-hub", "iot/101-iot-hub-endpoints-and-file-upload", "iot/103-iot-hub-with-dps", "iot/110-iot-central-application", "iot/111-iot-security-solution", + "keyvault/101-keyvault-policies", + "keyvault/102-keyvault-cert-issuer", + "keyvault/104-keyvault-dynamic-secret", + "keyvault/105-keyvault-dynamic-certificate", + "load_test/100-load-test", "logic_app/100-logic_app_workflow", "logic_app/102-logic_app_integration_account", "logic_app/103-logic_app_action_http", @@ -132,20 +150,19 @@ "logic_app/106-logic_app_trigger_recurrence", "logic_app/107-logic_app_trigger_custom", "logic_app/109-logic_app_standard_vnet_integration", - "machine_learning/100-aml", - "machine_learning/101-aml-vnet", - "machine_learning/102-aml-compute_instance", - "maps/101-azure-maps-account", + "maintenance_configuration/100-maintenance-configuration", + "maintenance_configuration/101-maintenance-configuration-schedule", + "maintenance_configuration/200-maintenance-configuration-assignment-vm-windows", + "maintenance_configuration/201-maintenance-configuration-assignment-vm-linux", "managed_service_identity/100-msi-levels", - "mariadb_server/100-simple-mariadb", - "mariadb_server/101-vnet-rule-mariadb", - "mariadb_server/102-private-endpoint-mariadb", - "mariadb_server/103-private-endpoint-with-fw-rule-mariadb", + "maps/101-azure-maps-account", "messaging/eventgrid/100-simple-eventgrid-topic", "messaging/eventgrid/101-simple-eventgrid-topic-private-endpoint", "messaging/eventgrid/102-eventgrid_subscription", "messaging/eventgrid/200-simple-eventgrid-domain-topic", + "messaging/eventgrid/300-simple-eventgrid-system-topic", "messaging/servicebus/100-servicebus-services", + "messaging/servicebus/200-servicebus-privatelink", "messaging/web_pubsub/100-simple-web-pubsub", "messaging/web_pubsub/101-web-pubsub-hub", "messaging/web_pubsub/102-web-pubsub-usermsi", @@ -155,40 +172,24 @@ "monitoring/102-monitor_activity_log_alert", "monitoring/103-monitor_metric_alert", "monitoring/104-log_analytics_storage_insights", - "mssql_server/101-sqlserver-simple", - "mssql_server/102-sqlserver-extend", - "mssql_server/104-sqlserver-elastic_pools", - "mssql_server/105-sqlserver-failover_groups", - "mssql_server/107-sqlserver-db-retention-policy", - "mssql_server/108-sqlserver-db-diagnostics", - "mssql_server/109-sqlserver-network-firewall-rule", - "mysql_flexible_server/100-simple-mysql-flexible", - "mysql_flexible_server/101-delegated-subnet-with-fw-rule", - "mysql_flexible_server/102-advanced-mysql-flexible", - "mysql_server/100-simple-mysql", - "mysql_server/101-vnet-rule-mysql", - "mysql_server/102-private-endpoint-mysql", - "mysql_server/103-private-endpoint-with-fw-rule-mysql", "netapp/101-nfs", "netapp/102-nfs-export-policy", - "postgresql_flexible_server/100-simple-postgresql-flexible", - "postgresql_flexible_server/101-delegated-subnet-with-fw-rule", - "postgresql_flexible_server/102-advanced-postgresql-flexible", - "postgresql_server/100-simple-postgresql", - "postgresql_server/101-vnet-rule-postgresql", - "postgresql_server/102-private-endpoint-postgresql", - "postgresql_server/103-private-endpoint-with-fw-rule", - "powerbi_embedded/100-simple-powerbi", - "purview/100-purview_account", - "purview/101-purview_account_private_link", "recovery_vault/101-simple-asrv", "recovery_vault/102-asr-protection", "recovery_vault/103-asr-with-private-endpoint", "recovery_vault/104-backupvault-with-private-endpoint", "recovery_vault/105-asr-with-network-mapping", + "recovery_vault/106-backupvault-with-sqldatabase-saphana", + "recovery_vault/107-asr-diagnostics", + "redis_cache/100-redis-standard", + "redis_cache/101-redis-diagnostics", + "redis_cache/102-redis-private", "redis_cache/103-redis-private-endpoints", "role_mapping/100-simple-role-mapping", "role_mapping/101-function-app-managed-identity", + "search_service/100-search-service-both-apikeys-and-azuread", + "search_service/101-search-service-only-api-keys", + "search_service/102-search-service-only-azuread", "sentinel/101-automation_rule", "sentinel/104-ar_fusion", "sentinel/105-ar_ml_behavior_analytics", @@ -206,9 +207,11 @@ "storage_accounts/107-storage-account-management-policy", "storage_accounts/109-storage-account-advanced-options-cmk", "storage_accounts/110-file-share-with-acl", + "storage_accounts/112-storage-account-with-defender", "storage_container/101-storage_container", "synapse_analytics/100-synapse", "synapse_analytics/101-synapse-sparkpool", + "webapps/appservice-environment/102-simple_asev3", "webapps/appservice/101-appservice-simple", "webapps/appservice/102-appservice-slots", "webapps/appservice/103-appservice-extend", diff --git a/.github/workflows/standalone-tf100.yaml b/.github/workflows/standalone-tf100.yaml deleted file mode 100644 index 1ef75d3a8f..0000000000 --- a/.github/workflows/standalone-tf100.yaml +++ /dev/null @@ -1,161 +0,0 @@ -# -# Copyright (c) Microsoft Corporation -# Licensed under the MIT License. -# - -name: standalone-tf100 - -on: - workflow_dispatch: - inputs: - scenario: - description: "Select the scenario you want to run:" - required: false - type: choice - default: "standalone-scenarios.json" - options: - - standalone-scenarios-azuread.json - - standalone-scenarios.json - - standalone-compute.json - - standalone-networking.json - - standalone-scenarios-longrunners.json - -env: - TF_CLI_ARGS: "-no-color" - TF_CLI_ARGS_destroy: "-auto-approve -refresh=false" - ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }} - ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} - ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} - ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} - TF_REGISTRY_DISCOVERY_RETRY: 5 - TF_REGISTRY_CLIENT_TIMEOUT: 15 - ROVER_RUNNER: true - -jobs: - load_scenarios: - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.load_scenarios.outputs.matrix }} - steps: - - uses: actions/checkout@v3 - - id: load_scenarios - run: | - cases=$(( - cat ./.github/workflows/${{ github.event.inputs.scenario }}) | jq -c .) - echo "matrix=${cases}" >> $GITHUB_OUTPUT - - testcases: - name: test - runs-on: ubuntu-latest - needs: load_scenarios - - strategy: - max-parallel: 20 - fail-fast: false - matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} - - container: - image: aztfmod/rover:1.5.7-2310.0211 - options: --user 0 - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Create environment variables - run: | - cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} - FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) - echo STATE_FILE=${TF_DATA_DIR}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV - echo PLAN_FILE=${TF_DATA_DIR}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV - echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV - echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV - - - name: Login azure - run: | - az login --service-principal -u '${{ env.ARM_CLIENT_ID }}' -p '${{ env.ARM_CLIENT_SECRET }}' --tenant '${{ env.ARM_TENANT_ID }}' - az account set -s ${{ env.ARM_SUBSCRIPTION_ID }} - - - name: Terraform Init example - id: tf_init - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - init -upgrade=true | grep -P '^- (?=Downloading|Using|Finding|Installing)|^[^-]' - - - name: Terraform Plan example - id: tf_plan - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - plan \ - ${{ env.PARAMETER_FILES }} \ - -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ - -var var_folder_path=${{ env.CURRENT_FOLDER }} \ - -refresh=true \ - -input=false \ - -state=${{ env.STATE_FILE }} \ - -out=${{ env.PLAN_FILE }} - - - name: Terraform Apply example - id: tf_apply - if: steps.tf_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - apply \ - -parallelism=30 \ - -state=${{ env.STATE_FILE }} \ - ${{ env.PLAN_FILE }} - - - name: Terraform Destroy planning example - id: tf_destroy_plan - if: steps.tf_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - plan \ - ${{ env.PARAMETER_FILES }} \ - -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ - -var var_folder_path=${{ env.CURRENT_FOLDER }} \ - -refresh=true \ - -input=false \ - -destroy \ - -state=${{ env.STATE_FILE }} \ - -out=${{ env.PLAN_FILE }}-destroy - - - name: Terraform Destroy apply example - id: tf_destroy_apply - if: steps.tf_destroy_plan.outcome == 'success' - run: | - terraform -chdir=${GITHUB_WORKSPACE}/examples \ - apply \ - -refresh=false \ - -parallelism=30 \ - -auto-approve \ - -state=${{ env.STATE_FILE }} \ - ${{ env.PLAN_FILE }}-destroy - - purge: - name: purge - runs-on: ubuntu-latest - if: ${{ failure() || cancelled() }} - - needs: [testcases] - - container: - image: aztfmod/rover:1.5.7-2310.0211 - options: --user 0 - - steps: - - name: Login azure - run: | - az login --service-principal -u '${{ env.ARM_CLIENT_ID }}' -p '${{ env.ARM_CLIENT_SECRET }}' --tenant '${{ env.ARM_TENANT_ID }}' - az account set -s ${{ env.ARM_SUBSCRIPTION_ID }} - - - name: Complete purge - run: | - for i in `az monitor diagnostic-settings subscription list -o tsv --query "value[?contains(name, '${{ github.run_id }}' )].name"`; do echo "purging subscription diagnostic-settings: $i" && $(az monitor diagnostic-settings subscription delete --name $i --yes); done - for i in `az monitor log-profiles list -o tsv --query '[].name'`; do az monitor log-profiles delete --name $i; done - for i in `az ad group list --query "[?contains(displayName, '${{ github.run_id }}')].id" -o tsv`; do echo "purging Azure AD group: $i" && $(az ad group delete --verbose --group $i || true); done - for i in `az ad app list --query "[?contains(displayName, '${{ github.run_id }}')].appId" -o tsv`; do echo "purging Azure AD app: $i" && $(az ad app delete --verbose --id $i || true); done - for i in `az keyvault list-deleted --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do az keyvault purge --name $i; done - for i in `az group list --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do echo "purging resource group: $i" && $(az group delete -n $i -y --no-wait || true); done - for i in `az role assignment list --query "[?contains(roleDefinitionName, '${{ github.run_id }}')].roleDefinitionName" -o tsv`; do echo "purging role assignment: $i" && $(az role assignment delete --role $i || true); done - for i in `az role definition list --query "[?contains(roleName, '${{ github.run_id }}')].roleName" -o tsv`; do echo "purging custom role definition: $i" && $(az role definition delete --name $i || true); done diff --git a/.github/workflows/weekly_dispatch.yaml b/.github/workflows/weekly_dispatch.yaml new file mode 100644 index 0000000000..fc601ff4d7 --- /dev/null +++ b/.github/workflows/weekly_dispatch.yaml @@ -0,0 +1,34 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR Dispatch Workflow + +on: + schedule: + - cron: '0 5 * * 5' + +env: + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + dispatch: + runs-on: ubuntu-latest + strategy: + matrix: + scenario: + - standalone-scenarios-azuread.json + - standalone-scenarios.json + - standalone-compute.json + - standalone-networking.json + - standalone-dataplat.json + + steps: + - name: Repository Dispatch + uses: peter-evans/repository-dispatch@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + event-type: int-${{ matrix.scenario }} + client-payload: '{"scenario": "${{ (matrix.scenario) }}", "sha": "${{ github.event.pull_request.head.sha }}"}' diff --git a/.github/workflows/weekly_workflow.yaml b/.github/workflows/weekly_workflow.yaml new file mode 100644 index 0000000000..9b645ac6ac --- /dev/null +++ b/.github/workflows/weekly_workflow.yaml @@ -0,0 +1,247 @@ +# +# Copyright (c) Microsoft Corporation +# Licensed under the MIT License. +# + +name: PR tests + +on: + repository_dispatch: + types: [int-*] + workflow_dispatch: + inputs: + scenario: + description: "Select the scenario you want to run:" + required: false + type: choice + default: "standalone-networking.json" + options: + - standalone-azuread.json + - standalone-scenarios.json + - standalone-compute.json + - standalone-networking.json + - standalone-dataplat.json + +env: + DEFAULT_SCENARIO: "standalone-networking.json" + TF_VERSION: "1.8.4" + TF_LINT_VERSION: "v0.50.3" + +jobs: + load_scenarios: + name: Load Test Scenarios Matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.load_scenarios.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + - id: load_scenarios + run: | + echo "Scenario: ${{ github.event.client_payload.scenario }}" + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + cases=$(cat ./.github/workflows/${{ github.event.inputs.scenario }} | jq -c .) + else + cases=$(cat ./.github/workflows/${{ github.event.client_payload.scenario }} | jq -c .) + fi + echo "matrix=${cases}" >> $GITHUB_OUTPUT + + mock_plan_scenarios: + name: Test-${{ matrix.config_files }} + runs-on: ubuntu-latest + needs: load_scenarios + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=examples \ + init + + - name: Terraform Test example + id: tf_test + run: | + terraform -chdir=examples \ + test \ + -test-directory=./tests/mock \ + ${{ env.PARAMETER_FILES }} \ + -verbose + + terraform_integration_tests: + permissions: + id-token: write + contents: read + + name: Integration-${{ matrix.config_files }} + runs-on: ubuntu-latest + if: always() + needs: [load_scenarios, mock_plan_scenarios] + + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.load_scenarios.outputs.matrix)}} + + environment: + name: 'integration' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Create environment variables + run: | + cd ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} + FILE_NAME=$(echo ${{ matrix.config_files }} | sed 's./..g' | xargs) + echo STATE_FILE=${HOME}/tfstates/${FILE_NAME}.tfstate >> $GITHUB_ENV + echo PLAN_FILE=${HOME}/tfstates/${FILE_NAME}.plan >> $GITHUB_ENV + echo CURRENT_FOLDER=${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} >> $GITHUB_ENV + echo PARAMETER_FILES=$(find ${GITHUB_WORKSPACE}/examples/${{ matrix.config_files }} | grep .tfvars | sed 's/.*/-var-file=&/' | xargs) >> $GITHUB_ENV + + - name: Install Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ env.TF_VERSION }} + + - name: Configure Terraform plugin cache + run: | + echo "TF_PLUGIN_CACHE_DIR=$HOME/.terraform.d/plugin-cache" >>"$GITHUB_ENV" + mkdir --parents "$HOME/.terraform.d/plugin-cache" + + - name: Cache Terraform + uses: actions/cache@v4 + with: + path: | + ~/.terraform.d/plugin-cache + key: ${{ runner.os }}-terraform-${{ hashFiles('**/.terraform.lock.hcl') }} + restore-keys: | + ${{ runner.os }}-terraform- + + - name: Azure Login + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Terraform Init example + id: tf_init + run: | + terraform -chdir=${GITHUB_WORKSPACE}/examples \ + init | grep -P '^- (?=Downloading|Using|Finding|Installing)|^[^-]' + + - name: Terraform Plan example + id: tf_plan + run: | + terraform -chdir=${GITHUB_WORKSPACE}/examples \ + plan \ + ${{ env.PARAMETER_FILES }} \ + -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ + -var var_folder_path=${{ env.CURRENT_FOLDER }} \ + -refresh=true \ + -input=false \ + -state=${{ env.STATE_FILE }} \ + -out=${{ env.PLAN_FILE }} + + - name: Terraform Apply example + id: tf_apply + run: | + terraform -chdir=${GITHUB_WORKSPACE}/examples \ + apply \ + -state=${{ env.STATE_FILE }} \ + ${{ env.PLAN_FILE }} + + - name: Terraform Destroy Plan + id: tf_destroy_plan + run: | + terraform -chdir=${GITHUB_WORKSPACE}/examples \ + plan \ + ${{ env.PARAMETER_FILES }} \ + -var tags='{testing_job_id='"${{ github.run_id }}"'}' \ + -var var_folder_path=${{ env.CURRENT_FOLDER }} \ + -refresh=true \ + -input=false \ + -destroy \ + -state=${{ env.STATE_FILE }} \ + -out=${{ env.PLAN_FILE }}-destroy + + - name: Terraform Destroy Apply + id: tf_destroy_apply + run: | + terraform -chdir=${GITHUB_WORKSPACE}/examples \ + apply \ + -refresh=false \ + -auto-approve \ + -state=${{ env.STATE_FILE }} \ + ${{ env.PLAN_FILE }}-destroy + + purge: + permissions: + id-token: write + contents: read + + name: Purge Integration Environment + runs-on: ubuntu-latest + if: ${{ failure() || cancelled() }} + + needs: [load_scenarios, terraform_integration_tests] + + environment: + name: 'integration' + + steps: + - name: Azure Login + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Purge based on run_id + run: | + for i in `az monitor diagnostic-settings subscription list -o tsv --query "value[?contains(name, '${{ github.run_id }}' )].name"`; do echo "purging subscription diagnostic-settings: $i" && $(az monitor diagnostic-settings subscription delete --name $i --yes); done + for i in `az monitor log-profiles list -o tsv --query '[].name'`; do az monitor log-profiles delete --name $i; done + for i in `az ad group list --query "[?contains(displayName, '${{ github.run_id }}')].id" -o tsv`; do echo "purging Azure AD group: $i" && $(az ad group delete --verbose --group $i || true); done + for i in `az ad app list --query "[?contains(displayName, '${{ github.run_id }}')].appId" -o tsv`; do echo "purging Azure AD app: $i" && $(az ad app delete --verbose --id $i || true); done + for i in `az keyvault list-deleted --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do az keyvault purge --name $i; done + for i in `az group list --query "[?tags.testing_job_id=='${{ github.run_id }}'].name" -o tsv`; do echo "purging resource group: $i" && $(az group delete -n $i -y --no-wait || true); done + for i in `az role assignment list --query "[?contains(roleDefinitionName, '${{ github.run_id }}')].roleDefinitionName" -o tsv`; do echo "purging role assignment: $i" && $(az role assignment delete --role $i || true); done + for i in `az role definition list --query "[?contains(roleName, '${{ github.run_id }}')].roleName" -o tsv`; do echo "purging custom role definition: $i" && $(az role definition delete --name $i || true); done \ No newline at end of file diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000000..fd7865f524 --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,18 @@ +#Tflint config file +config { + call_module_type = "all" + force = false + disabled_by_default = false +} + +# Adds azurerm plugin +plugin "azurerm" { + enabled = true + version = "0.25.1" + source = "github.com/terraform-linters/tflint-ruleset-azurerm" +} + +# Will be enabled progressively as we add more types +rule "terraform_typed_variables" { + enabled = false +} \ No newline at end of file diff --git a/README.md b/README.md index ff399e16ee..1ee782818d 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,17 @@ # Cloud Adoption Framework for Azure - Terraform module -Microsoft [Cloud Adoption Framework for Azure](https://aka.ms/caf) provides you with guidance and best practices to adopt Azure. +> :warning: This solution, offered by the Open-Source community, will no longer receive contributions from Microsoft. Customers are encouraged to transition to [Microsoft Azure Verified Modules](https://aka.ms/avm) for Microsoft support and updates. -This module allows you to create resources on Microsoft Azure, is used by the Cloud Adoption Framework for Azure (CAF) landing zones to provision resources in an Azure subscription and can deploy resources being directly invoked from the Terraform registry. +This module allows you to create resources on Microsoft Azure, is used by the Azure Terraform SRE to provision resources in an Azure subscription and can deploy resources being directly invoked from the Terraform registry. ## Prerequisites -- Setup your **environment** using the following guide [Getting Started](https://github.com/Azure/caf-terraform-landingzones/blob/master/documentation/getting_started/getting_started.md) or you use it online with [GitHub Codespaces](https://github.com/features/codespaces). +- Setup your **environment** using the following guide [Getting Started](https://github.com/aztfmod/caf-terraform-landingzones/blob/master/documentation/getting_started/getting_started.md) or you use it online with [GitHub Codespaces](https://github.com/features/codespaces). - Access to an **Azure subscription**. - ## Getting started -This module can be used inside [:books: Azure Terraform Landing zones](https://aka.ms/caf/terraform), or can be used as standalone, directly from the [Terraform registry](https://registry.terraform.io/modules/aztfmod/caf/azurerm/) +This module can be used inside [:books: Azure Terraform Landing zones](https://aztfmod.github.io/documentation/), or can be used as standalone, directly from the [Terraform registry](https://registry.terraform.io/modules/aztfmod/caf/azurerm/) ```terraform module "caf" { @@ -28,28 +27,18 @@ For a complete set of examples you can review the [full library here](https://gi

- - ## Community Feel free to open an issue for feature or bug, or to submit a PR, [Please check out the WIKI for coding standards, common patterns and PR checklist.](https://github.com/aztfmod/terraform-azurerm-caf/wiki) -In case you have any question, you can reach out to tf-landingzones at microsoft dot com. - You can also reach us on [Gitter](https://gitter.im/aztfmod/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. +the rights to use your contribution. For details, visit . When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. - -## Code of conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/api_management.tf b/api_management.tf index acb5eb095e..9bb39eeb67 100644 --- a/api_management.tf +++ b/api_management.tf @@ -7,6 +7,7 @@ module "api_management" { settings = each.value vnets = local.combined_objects_networking + public_ip_addresses = local.combined_objects_public_ip_addresses base_tags = local.global_settings.inherit_tags resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : null diff --git a/azuread_users.tf b/azuread_users.tf index f75e57cc13..ac8d3d4860 100644 --- a/azuread_users.tf +++ b/azuread_users.tf @@ -4,7 +4,7 @@ module "azuread_users" { source = "./modules/azuread/users" - depends_on = [module.keyvault_access_policies, time_sleep.azurerm_role_assignment_for.0] + depends_on = [module.keyvault_access_policies, time_sleep.azurerm_role_assignment_for[0]] for_each = local.azuread.azuread_users client_config = local.client_config diff --git a/billing_invoice_section.tf b/billing_invoice_section.tf new file mode 100644 index 0000000000..59eaf7f725 --- /dev/null +++ b/billing_invoice_section.tf @@ -0,0 +1,13 @@ +module "invoice_section" { + source = "./modules/billing/invoice_sections" + for_each = var.invoice_sections + + global_settings = local.global_settings + client_config = local.client_config + settings = each.value + base_tags = local.global_settings.inherit_tags +} + +output "invoice_sections" { + value = module.invoice_section +} \ No newline at end of file diff --git a/cognitive_service.tf b/cognitive_service.tf index 04659f9f28..b920b21464 100644 --- a/cognitive_service.tf +++ b/cognitive_service.tf @@ -4,9 +4,19 @@ module "cognitive_services_account" { client_config = local.client_config global_settings = local.global_settings + base_tags = local.global_settings.inherit_tags + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region] settings = each.value + resource_groups = local.combined_objects_resource_groups + vnets = local.combined_objects_networking + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + diagnostics = local.combined_diagnostics + diagnostic_profiles = try(each.value.diagnostic_profiles, {}) + + managed_identities = local.combined_objects_managed_identities } output "cognitive_services_account" { diff --git a/compute_virtual_machines_scale_sets.tf b/compute_virtual_machines_scale_sets.tf index 48abe654d2..8ef1ac29cb 100644 --- a/compute_virtual_machines_scale_sets.tf +++ b/compute_virtual_machines_scale_sets.tf @@ -3,18 +3,20 @@ module "virtual_machine_scale_sets" { source = "./modules/compute/virtual_machine_scale_set" depends_on = [ + module.application_gateways, + module.application_security_groups, module.availability_sets, module.dynamic_keyvault_secrets, - module.keyvault_access_policies, module.keyvault_access_policies_azuread_apps, - module.proximity_placement_groups, - #module.load_balancers, - module.application_gateways, - module.application_security_groups, - module.packer_service_principal, + module.keyvault_access_policies, + module.load_balancers, module.packer_build, - module.proximity_placement_groups + module.packer_service_principal, + module.proximity_placement_groups, + # triggers cyclic dependency + #time_sleep.azurerm_role_assignment_for[0] ] + for_each = local.compute.virtual_machine_scale_sets availability_sets = local.combined_objects_availability_sets diff --git a/container_app_dapr_components.tf b/container_app_dapr_components.tf new file mode 100644 index 0000000000..0cf0342b17 --- /dev/null +++ b/container_app_dapr_components.tf @@ -0,0 +1,15 @@ +module "container_app_dapr_components" { + source = "./modules/compute/container_app_dapr_component" + for_each = local.compute.container_app_dapr_components + + base_tags = local.global_settings.inherit_tags + container_app_environment_id = can(each.value.container_app_environment_id) ? each.value.container_app_environment_id : local.combined_objects_container_app_environments[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.container_app_environment_key].id + client_config = local.client_config + global_settings = local.global_settings + settings = each.value +} + +output "container_app_dapr_components" { + value = module.container_app_dapr_components +} + diff --git a/container_app_environment_certificates.tf b/container_app_environment_certificates.tf new file mode 100644 index 0000000000..65dc7832a2 --- /dev/null +++ b/container_app_environment_certificates.tf @@ -0,0 +1,15 @@ +module "container_app_environment_certificates" { + source = "./modules/compute/container_app_environment_certificate" + for_each = local.compute.container_app_environment_certificates + + base_tags = local.global_settings.inherit_tags + container_app_environment_id = can(each.value.container_app_environment_id) ? each.value.container_app_environment_id : local.combined_objects_container_app_environments[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.container_app_environment_key].id + client_config = local.client_config + global_settings = local.global_settings + settings = each.value +} + +output "container_app_environment_certificates" { + value = module.container_app_environment_certificates +} + diff --git a/container_app_environment_storages.tf b/container_app_environment_storages.tf new file mode 100644 index 0000000000..6bc36024c3 --- /dev/null +++ b/container_app_environment_storages.tf @@ -0,0 +1,18 @@ +module "container_app_environment_storages" { + source = "./modules/compute/container_app_environment_storage" + for_each = local.compute.container_app_environment_storages + + base_tags = local.global_settings.inherit_tags + container_app_environment_id = can(each.value.container_app_environment_id) ? each.value.container_app_environment_id : local.combined_objects_container_app_environments[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.container_app_environment_key].id + client_config = local.client_config + global_settings = local.global_settings + combined_resources = { + storage_accounts = local.combined_objects_storage_accounts + } + settings = each.value +} + +output "container_app_environment_storages" { + value = module.container_app_environment_storages +} + diff --git a/container_app_environments.tf b/container_app_environments.tf new file mode 100644 index 0000000000..15a7066b6a --- /dev/null +++ b/container_app_environments.tf @@ -0,0 +1,21 @@ +module "container_app_environments" { + source = "./modules/compute/container_app_environment" + for_each = local.compute.container_app_environments + + location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] + resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name + base_tags = local.global_settings.inherit_tags + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : try(local.combined_objects_networking[try(each.value.vnet.lz_key, local.client_config.landingzone_key)][each.value.vnet.vnet_key].subnets[each.value.vnet.subnet_key].id, null) + client_config = local.client_config + combined_diagnostics = local.combined_diagnostics + diagnostic_profiles = try(each.value.diagnostic_profiles, {}) + diagnostics = local.combined_diagnostics + global_settings = local.global_settings + settings = each.value +} + +output "container_app_environments" { + value = module.container_app_environments +} + diff --git a/container_apps.tf b/container_apps.tf new file mode 100644 index 0000000000..45164e9463 --- /dev/null +++ b/container_apps.tf @@ -0,0 +1,27 @@ +module "container_apps" { + source = "./modules/compute/container_app" + for_each = local.compute.container_apps + + location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] + resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name + base_tags = local.global_settings.inherit_tags + container_app_environment_id = can(each.value.container_app_environment_id) ? each.value.container_app_environment_id : local.combined_objects_container_app_environments[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.container_app_environment_key].id + client_config = local.client_config + combined_diagnostics = local.combined_diagnostics + diagnostic_profiles = try(each.value.diagnostic_profiles, {}) + diagnostics = local.combined_diagnostics + combined_resources = { + keyvaults = local.combined_objects_keyvaults + managed_identities = local.combined_objects_managed_identities + container_app_environment_certificates = local.combined_objects_container_app_environment_certificates + container_app_environment_storages = local.combined_objects_container_app_environment_storages + } + global_settings = local.global_settings + settings = each.value +} + +output "container_apps" { + value = module.container_apps +} + diff --git a/data_explorer.tf b/data_explorer.tf index ee06f70ee5..7d4b408304 100644 --- a/data_explorer.tf +++ b/data_explorer.tf @@ -7,9 +7,11 @@ module "kusto_clusters" { settings = each.value location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name + private_endpoints = try(each.value.private_endpoints, {}) base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} combined_resources = { + private_dns = local.combined_objects_private_dns vnets = local.combined_objects_networking pips = local.combined_objects_public_ip_addresses managed_identities = local.combined_objects_managed_identities diff --git a/databricks_access_connectors.tf b/databricks_access_connectors.tf new file mode 100644 index 0000000000..87975da0bb --- /dev/null +++ b/databricks_access_connectors.tf @@ -0,0 +1,18 @@ +module "databricks_access_connectors" { + source = "./modules/analytics/databricks_access_connector" + for_each = local.database.databricks_access_connectors + + client_config = local.client_config + global_settings = local.global_settings + name = each.value.name + settings = each.value + resource_groups = local.combined_objects_resource_groups + base_tags = local.global_settings.inherit_tags + remote_objects = { + managed_identities = local.combined_objects_managed_identities + } +} + +output "databricks_access_connectors" { + value = module.databricks_access_connectors +} diff --git a/event_hubs.tf b/event_hubs.tf index 821acd542a..052558890c 100644 --- a/event_hubs.tf +++ b/event_hubs.tf @@ -109,9 +109,6 @@ module "event_hubs" { resource_group_name = local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name } -output "event_hubs" { - value = module.event_hubs -} module "event_hub_auth_rules" { source = "./modules/event_hubs/hubs/auth_rules" diff --git a/eventgrid.tf b/eventgrid.tf index 343c4c184e..aa75ed9408 100755 --- a/eventgrid.tf +++ b/eventgrid.tf @@ -5,6 +5,7 @@ module "eventgrid_domain" { global_settings = local.global_settings client_config = local.client_config settings = each.value + base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location @@ -25,6 +26,7 @@ module "eventgrid_topic" { global_settings = local.global_settings client_config = local.client_config settings = each.value + base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location @@ -112,6 +114,7 @@ module "eventgrid_system_topic" { subscriptions = local.combined_objects_subscriptions } } + output "eventgrid_system_topic" { value = module.eventgrid_system_topic } @@ -139,6 +142,6 @@ module "azurerm_eventgrid_system_topic_event_subscription" { } } -output "azurerm_eventgrid_system_topic_event_subscription" { - value = module.azurerm_eventgrid_system_topic_event_subscription -} \ No newline at end of file +#output "eventgrid_system_event_subscription" { +# value = module.eventgrid_system_event_subscription +#} diff --git a/examples/apim/118-api_management_platform_stv2/configuration.tfvars b/examples/apim/118-api_management_platform_stv2/configuration.tfvars new file mode 100644 index 0000000000..59892b21df --- /dev/null +++ b/examples/apim/118-api_management_platform_stv2/configuration.tfvars @@ -0,0 +1,181 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "uksouth" + } + inherit_tags = true + tags = { + example = "apim/118-stv2.*" + } +} + +resource_groups = { + rg_example_apim_uks = { + name = "example-apim-uks" # prefix-rg-example-apim-uks + region = "region1" + tags = { + level = "level3" + } + } +} + +vnets = { + # Example vNet + vnet_example_uks = { + resource_group_key = "rg_example_apim_uks" + region = "region1" + vnet = { + name = "example-uks" # prefix-vnet-example-uks + address_space = ["10.0.0.0/16"] + } + subnets = { + + # Example subnet for APIM private endpoint + + snet_example_apim_uks = { + name = "example-apim-uks" #prefix-snet-example-apim-uks + cidr = ["10.0.1.0/24"] + nsg_key = "nsg_example_apim_uks" + # route_table_key = "" + service_endpoints = ["Microsoft.KeyVault", "Microsoft.Storage", "Microsoft.Sql", "Microsoft.EventHub", "Microsoft.ServiceBus"] # service endpoints required for APIM + } + } + } +} + +network_security_group_definition = { + # This entry is applied to all subnets with no NSG defined + empty_nsg_no_log = {} + + # Example NSG for APIM + nsg_example_apim_uks = { + name = "example-apim-uks" # prefix-nsg-example-apim-uks + version = 1 + resource_group_key = "rg_example_apim_uks" + nsg = [ + { + name = "Inbound-ApiManagement", + priority = "1000" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "3443" + source_address_prefix = "ApiManagement" + destination_address_prefix = "VirtualNetwork" + }, + { + name = "Inbound-AzureLoadBalancer", + priority = "1010" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "6390" + source_address_prefix = "AzureLoadBalancer" + destination_address_prefix = "VirtualNetwork" + }, + { + name = "Outbound-Storage", + priority = "1000" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "Storage" + }, + { + name = "Outbound-SQL", + priority = "1010" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "1443" + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "SQL" + }, + { + name = "Outbound-AzureKeyVault", + priority = "1020" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "AzureKeyVault" + }, + { + name = "Outbound-AzureMonitor", + priority = "1030" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_ranges = ["443", "1886"] + source_address_prefix = "VirtualNetwork" + destination_address_prefix = "AzureMonitor" + }, + ] + } +} + +public_ip_addresses = { + + # Public IP for the example APIM Instance + pip_apim_uks = { + name = "example-apim-uks" # prefix-pip-example-apim-uks + region = "region1" + resource_group_key = "rg_example_apim_uks" + sku = "Standard" # must be 'Standard' SKU + + # Standard SKU Public IP Addresses that do not specify a zone are zone redundant by default. + allocation_method = "Static" + ip_version = "IPv4" + idle_timeout_in_minutes = "4" + domain_name_label = "example-apim-uks" + } +} + +api_management = { + apim_uks = { + name = "example-uks" # prefix-apim-example-uks + resource_group_key = "rg_example_apim_uks" + publisher_name = "apim.example.sre.com" + publisher_email = "example.apim@sre.com" + sku_name = "Developer_1" # https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/api_management#sku_name + region = "region1" + + # Required to deploy APIM on platform verions stv2.* + public_ip_address = { + key = "pip_apim_uks" + # lz_key = "" + } + + virtual_network_type = "Internal" # The type of virtual network you want to use, valid values include: None, External, Internal. Defaults to None. + virtual_network_configuration = { + vnet_key = "vnet_example_uks" + subnet_key = "snet_example_apim_uks" + # lz_key = "" + } + + identity = { + type = "UserAssigned" + managed_identity_keys = ["msi_apim_uks"] + } + + portal = { + host_name = "example.apim.com" + } + } +} + +managed_identities = { + msi_apim_uks = { + name = "example-apim-uks" # prefix-msi-example-apim-uks + resource_group_key = "rg_example_apim_uks" + } +} diff --git a/examples/azuread/107-azuread-application-with-single-page-application/configuration.tfvars b/examples/azuread/107-azuread-application-with-single-page-application/configuration.tfvars index 60ddaeb879..be32857be7 100644 --- a/examples/azuread/107-azuread-application-with-single-page-application/configuration.tfvars +++ b/examples/azuread/107-azuread-application-with-single-page-application/configuration.tfvars @@ -51,6 +51,13 @@ azuread_applications = { id = "d4c3605a-b327-35c5-f04d-77f7fcdd4995" type = "Admin" value = "app" + }, + { + admin_consent_description = "Allow to administer app2." + admin_consent_display_name = "Administer app2" + enabled = true + type = "Admin" + value = "app2" } ] } diff --git a/examples/cognitive_services/101-cognitive-services-account-managed-identity/configuration.tfvars b/examples/cognitive_services/101-cognitive-services-account-managed-identity/configuration.tfvars new file mode 100644 index 0000000000..62c98ec3e1 --- /dev/null +++ b/examples/cognitive_services/101-cognitive-services-account-managed-identity/configuration.tfvars @@ -0,0 +1,71 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "westus" + } + random_length = 5 +} + +resource_groups = { + test-rg = { + name = "rg-cognitive-test" + } +} + +managed_identities = { + cognitive_msi = { + name = "cognitive-msi" + resource_group_key = "test-rg" + } +} + +cognitive_services_account = { + test_account-1 = { + resource_group = { + # accepts either id or key to get resource group id + # id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1" + # lz_key = "examples" + key = "test-rg" + } + name = "cs-test-1" + kind = "OpenAI" + sku_name = "S0" + public_network_access_enabled = true + + identity = { + type = "SystemAssigned, UserAssigned" // Can be "SystemAssigned, UserAssigned" or "SystemAssigned" or "UserAssigned" + key = "cognitive_msi" // A must with "SystemAssigned, UserAssigned" and "UserAssigned" + } + + tags = { + env = "test" + } + # custom_subdomain_name = "cs-test-1" + # network_acls = { + # default_action = "Allow" + # ip_rules = ["10.10.10.0/16"] + # } + } + test_account-2 = { + resource_group = { + # accepts either id or key to get resource group id + # id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1" + # lz_key = "examples" + key = "test-rg" + } + name = "cs-test-2" + kind = "QnAMaker" + sku_name = "F0" + + identity = { + type = "SystemAssigned" + } + + tags = { + env = "test" + } + qna_runtime_endpoint = "https://cs-alz-caf-test-2.azurewebsites.net" + + } +} + diff --git a/examples/compute/azure_redhat_openshift/101_basic_private_cluster/aro.tfvars b/examples/compute/azure_redhat_openshift/101_basic_private_cluster/aro.tfvars index 9f9ecf1fde..71c634ecc4 100644 --- a/examples/compute/azure_redhat_openshift/101_basic_private_cluster/aro.tfvars +++ b/examples/compute/azure_redhat_openshift/101_basic_private_cluster/aro.tfvars @@ -49,7 +49,7 @@ aro_clusters = { # secret = "your_secret" # secret_id = "resource_id_of_the_secret" #} - version = "4.10.40" + version = "4.13.23" resource_group = { # cant be an existing RG, you can specify the name of the RG to create with id="" or just a name="" # id = "resource_group_id" diff --git a/examples/compute/azure_redhat_openshift/102_basic_public_cluster/aro.tfvars b/examples/compute/azure_redhat_openshift/102_basic_public_cluster/aro.tfvars index e7601597a7..b62efbb214 100644 --- a/examples/compute/azure_redhat_openshift/102_basic_public_cluster/aro.tfvars +++ b/examples/compute/azure_redhat_openshift/102_basic_public_cluster/aro.tfvars @@ -48,7 +48,7 @@ aro_clusters = { # secret = "your_secret" # secret_id = "resource_id_of_the_secret" #} - version = "4.10.40" + version = "4.13.23" resource_group = { # cant be an existing RG, you can specify the name of the RG to create with id="" or just a name="" # id = "resource_group_id" diff --git a/examples/compute/container_app/101-simple-container-app-env/configuration.tfvars b/examples/compute/container_app/101-simple-container-app-env/configuration.tfvars new file mode 100644 index 0000000000..9cb5029007 --- /dev/null +++ b/examples/compute/container_app/101-simple-container-app-env/configuration.tfvars @@ -0,0 +1,52 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "canadacentral" + } +} + +resource_groups = { + rg1 = { + name = "container-app-001" + region = "region1" + } +} + +diagnostic_log_analytics = { + central_logs_region1 = { + region = "region1" + name = "logs" + resource_group_key = "rg1" + } +} + +container_app_environments = { + cae1 = { + name = "cont-app-env-001" + region = "region1" + resource_group_key = "rg1" + log_analytics_key = "central_logs_region1" + } +} + +container_apps = { + ca1 = { + name = "nginx-app" + container_app_environment_key = "cae1" + resource_group_key = "rg1" + + revision_mode = "Single" + template = { + container = { + cont1 = { + name = "nginx" + image = "nginx:latest" + cpu = 0.5 + memory = "1Gi" + } + } + min_replicas = 1 + max_replicas = 1 + } + } +} diff --git a/examples/compute/container_app/102-simple-private-container-app-env/configuration.tfvars b/examples/compute/container_app/102-simple-private-container-app-env/configuration.tfvars new file mode 100644 index 0000000000..cbe2d15b8e --- /dev/null +++ b/examples/compute/container_app/102-simple-private-container-app-env/configuration.tfvars @@ -0,0 +1,86 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "canadacentral" + } +} + +resource_groups = { + rg1 = { + name = "container-app-001" + region = "region1" + } +} + +diagnostic_log_analytics = { + central_logs_region1 = { + region = "region1" + name = "logs" + resource_group_key = "rg1" + } +} + +vnets = { + cae_re1 = { + resource_group_key = "rg1" + region = "region1" + vnet = { + name = "container-app-network" + address_space = ["100.64.0.0/20"] + } + specialsubnets = {} + subnets = { + cae1 = { + name = "container-app-snet" + cidr = ["100.64.0.0/21"] + nsg_key = "empty_nsg" + } + } + + } +} + +network_security_group_definition = { + # This entry is applied to all subnets with no NSG defined + empty_nsg = {} +} + +container_app_environments = { + cae1 = { + name = "cont-app-env-001" + region = "region1" + resource_group_key = "rg1" + log_analytics_key = "central_logs_region1" + vnet = { + vnet_key = "cae_re1" + subnet_key = "cae1" + } + internal_load_balancer_enabled = true + + tags = { + environment = "testing" + } + } +} + +container_apps = { + ca1 = { + name = "nginx-app" + container_app_environment_key = "cae1" + resource_group_key = "rg1" + + revision_mode = "Single" + template = { + container = { + cont1 = { + name = "nginx" + image = "nginx:latest" + cpu = 0.5 + memory = "1Gi" + } + } + min_replicas = 1 + max_replicas = 1 + } + } +} diff --git a/examples/compute/container_app/103-private-container-app-env/configuration.tfvars b/examples/compute/container_app/103-private-container-app-env/configuration.tfvars new file mode 100644 index 0000000000..8a0f24fc42 --- /dev/null +++ b/examples/compute/container_app/103-private-container-app-env/configuration.tfvars @@ -0,0 +1,280 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "canadacentral" + } +} + +resource_groups = { + rg1 = { + name = "container-app-001" + region = "region1" + } +} + +diagnostic_log_analytics = { + central_logs_region1 = { + region = "region1" + name = "logs" + resource_group_key = "rg1" + } +} + +vnets = { + cae_re1 = { + resource_group_key = "rg1" + region = "region1" + vnet = { + name = "container-app-network" + address_space = ["100.64.0.0/20"] + } + specialsubnets = {} + subnets = { + cae1 = { + name = "container-app-snet" + cidr = ["100.64.0.0/21"] + nsg_key = "empty_nsg" + } + } + + } +} + +network_security_group_definition = { + # This entry is applied to all subnets with no NSG defined + empty_nsg = {} +} + +managed_identities = { + msi1 = { + name = "ca-identity-001" + resource_group_key = "rg1" + } +} + +storage_accounts = { + sa1 = { + name = "sa1caes001" + resource_group_key = "rg1" + account_kind = "FileStorage" + account_tier = "Premium" + account_replication_type = "LRS" + min_tls_version = "TLS1_2" + large_file_share_enabled = true + + file_shares = { + fs1 = { + name = "fs1" + quota = "100" + } + } + } +} + +container_app_environments = { + cae1 = { + name = "cont-app-env-001" + region = "region1" + resource_group_key = "rg1" + log_analytics_key = "central_logs_region1" + vnet = { + vnet_key = "cae_re1" + subnet_key = "cae1" + } + internal_load_balancer_enabled = true + zone_redundancy_enabled = true + + tags = { + environment = "testing" + } + } +} + +container_app_dapr_components = { + dapr1 = { + name = "dapr-component-001" + container_app_environment_key = "cae1" + component_type = "state.azure.blobstorage" + version = "v1" + ignore_errors = false + init_timeout = "1m" + secret = [ + { + name = "dapr-secret1" + value = "ccecewEWewce" + } + ] + metadata = [ + { + name = "dapr-meta1" + value = "ccweceww" + }, + { + name = "dapr-meta2" + secret_name = "dapr-secret1" + } + ] + } +} + +container_app_environment_certificates = { + caec1 = { + name = "caec-cert-001" + container_app_environment_key = "cae1" + certificate_blob_base64 = "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRQ3lKR2o4dXlrTUN3UmIKcEx6NU9YWTJUcy9WaWpLKzZIV2ZVZTI2QlgxMzYwOXluWkZRbXhURHJkVlR1RXcrT1czcGxEUUlMTGZQSWNlZwozYzdCYnI0VlNNazhvNWFhaTFSclZKemxKMlUvNWlDK3l1Uk0wSFV5Y09RbE01K1NiU3QyY1gvSCtScTlOdTM0CmJBVXRIM0s4NE9yb2ZnRFBPb3dsRjdrSm0yL29WaGRkeTVqOU9DWUpIUmFSZys3R1ZlSnFDaHQ0NjNkYjlBMloKYXZ5a0VTb3EvWGpxR1NGTEpGRjBXb0ZFSklMRE0xY3ZyZWJRNEl6NTMwSWVDTHFqRjI5NzhOcFJGMTk2TTBKOApiVVk0STNtNTk3Nk04Vk8zVWxWUk53cThkZWc1YVVkeW04eVQ2T2cxaTlEZVZLRnlaOHVWaHJKZFI1WUNKMzI1CmxqeERiQUpyQWdNQkFBRUNnZ0VBTVp3WUxNSEdkWmNmMkpHeEdzclkwOWp3NGl3Qlk4OEM2cUo3VE1HNHBrdSsKclZHYUpWTjYzZCtzT0F0c0dDd1FJdXRsN2h6ZDkyNFYxUVBRVDJnU3dZU3FuaHVFbG5kVXhDc2xJbC90UDNWTQpDellmakJERmdvMlR5NVJyelBCZ0dUVVVlOUV3bEI4VytJYkVqa05peFp6eGJsdWd5QlVxOEMyQ0YxM1ZOV05GClRSc1c1SXpiUnpaQm9Rd1U0aFQ5NWJGNkxkcHp1NWRFNjY5eEZrSmh6cWVlczNqWkVLK3BvVWV0VjFneEt1TkUKUW5MN1ZPQXdraFp5UjR4cXg2cVZPaEw0QlFSempJSDUzRlJBRWFiWmZhUVRDMm0wVlNzMndlOFJhaFFTOEFrYwptNitpWkJHcVFhQ0lLVDBQSkhNbi9GaFVQTHNwZEU3b1Z5WXc4UU5OS1FLQmdRRE9Wa0hVU25oOFhCR2VwMExXClVtdmtRQ1VvcXMzZnhKMmh3VjMxZ2IwZEt4OUZPU25qMkRlUHFic2hsVWdBMW4vcnFXQ05aNnhNazh3OWh2dDkKSXlkWWg3TWVjK3l4VTYxaElET1ZkcUxFS2d1UWZ5akZ1NzNUYTNIRDlKOEZvazBmWmFINWxMd3k1NHUvVjBWSApmaUpzZ3RTOTZVZnRuUC93ZnRWZUlpdFFEd0tCZ1FEZEJPVkt5S2xyUWFuWVptVGRTVUxFaE1TQnRDdm50ZTM4ClgvM3NwRms5WE45Z0NzUnpoekozQkM3NzA4SUlOdVZJV1kzRzBoYUNRNDMweURna29SNm8yWTlNSU1TNkQwWUQKREVXaXM5c2pEQlFQNEMrMXc1ZVlKRWFWUllaeE1vMXBsZitrNk5DK3ZaSXYxQXlPQTQ1S0twUDhZSmdmNk5GQQpNY2h0UVRkTDVRS0JnSDlOZEp2M3ZsSnJzMnRCSXRsOFRKaXNnc0NPY1NwbjhpRkVYaVlFZjVzcGFjZVp0eUNkCjI5bkZESEZ4MnRTNWduN3hKMkxXM2RUNU12K2E4anFJbjlQZEZVUHFuZFBpSG94WUE3dHBVSTdhcWZ2aW1GTTIKdTYxZkV2ZWxTeDk4dlR4cnhmMW9LSnozZ3A3d3h3dU81TW95QmZPTnBCVVQwa3ljMUNPWnpVTTlBb0dBWjZ6aQpPZUJDeUpNMnJ0SHBRbndaRzhJRHc2dldaSXpNby9RTFVyUU5RR0dPVHFqK1dncnpPeXoxTlIreUJ0UnBYVFRVCjhveWVEbUROK0NMcll4TkpKSDlaWHFhSVlaYkVpcTE1Qk1kRlpmMUdjK1AvdlUyUWtNZURiSVgrZUo3MEFyRmcKQitWRjloTkt2YkRFYXVGMEg0bzFmTTk2ekkwVGl2OVBPeUM2WlprQ2dZQVdkUjNxYVJrUzJuVVNiT2hrS2s2ZgoyK0xkRWMwcmFuSE5EYW9kMzZTbDYrRm5RbVNSWC90QTB3UUFnZnhoRERlWENGR3lnV1EvKytTUmt3a0g1Nnp2CjYxb0lCWmlEdkd5YkYrb251dDRJRnlTU0NQM3BiQ2ExeHpVNVNUaVgzMTdOVUVkUG00M3hOVS96eVA3MFlid1UKc01rd1AvUXFmaVcyTVhVcTRoaEU3QT09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0KLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURiekNDQWxlZ0F3SUJBZ0lRUFMwL2ZLTlhWWUpoWW5YVm9zU0wxREFOQmdrcWhraUc5dzBCQVFzRkFEQVcKTVJRd0VnWURWUVFERXd0bGVHRnRjR3hsTG1OdmJUQWVGdzB5TWpBM01qWXhORFUxTlROYUZ3MHpNakEzTWpNeApORFUxTlROYU1GY3hDekFKQmdOVkJBWVRBbFZUTVJ3d0dnWURWUVFLRXhORmVHRnRjR3hsSUZObGJHWWdVMmxuCmJtVmtNUlF3RWdZRFZRUUxFd3RsZUdGdGNHeGxMbU52YlRFVU1CSUdBMVVFQXhNTFpYaGhiWEJzWlM1amIyMHcKZ2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3lKR2o4dXlrTUN3UmJwTHo1T1hZMgpUcy9WaWpLKzZIV2ZVZTI2QlgxMzYwOXluWkZRbXhURHJkVlR1RXcrT1czcGxEUUlMTGZQSWNlZzNjN0JicjRWClNNazhvNWFhaTFSclZKemxKMlUvNWlDK3l1Uk0wSFV5Y09RbE01K1NiU3QyY1gvSCtScTlOdTM0YkFVdEgzSzgKNE9yb2ZnRFBPb3dsRjdrSm0yL29WaGRkeTVqOU9DWUpIUmFSZys3R1ZlSnFDaHQ0NjNkYjlBMlphdnlrRVNvcQovWGpxR1NGTEpGRjBXb0ZFSklMRE0xY3ZyZWJRNEl6NTMwSWVDTHFqRjI5NzhOcFJGMTk2TTBKOGJVWTRJM201Cjk3Nk04Vk8zVWxWUk53cThkZWc1YVVkeW04eVQ2T2cxaTlEZVZLRnlaOHVWaHJKZFI1WUNKMzI1bGp4RGJBSnIKQWdNQkFBR2plREIyTUE0R0ExVWREd0VCL3dRRUF3SUZvREFkQmdOVkhTVUVGakFVQmdnckJnRUZCUWNEQVFZSQpLd1lCQlFVSEF3SXdEQVlEVlIwVEFRSC9CQUl3QURBZkJnTlZIU01FR0RBV2dCVEFxYWFkZ1diNGFLc1IyS2VFCmZlQ1NBNEFqZlRBV0JnTlZIUkVFRHpBTmdndGxlR0Z0Y0d4bExtTnZiVEFOQmdrcWhraUc5dzBCQVFzRkFBT0MKQVFFQVhSRkVraTVTbXJkL2p5OGk5TzBhYmpDSWczd0NpQkxaU0V0aE1MZ3hIbjZwUDN4K0xialZ3OGdOb0FQNApUNndaTmdhWkYvSlF0c09UQ2Ird0thenc0b1IvOE5xajFIWjdWT0hERU5yWVdPaG5nSjl0MFh1TC90OU1UaXBXCnRkR21wT0xVMURReU9VRFlJbWhhY05IVUxaeHd4TFdVU1F4Y25SSUJRTjdjemZ1NjFmcFp0dWFhMkhTYzIrVDkKNjFKeG5hRERlWldzQXQ1MXp3bjk0M3h2V3BFQjB1dGVKQnVIVWNUbUxGalVoaVV4RmxSM3Q0dWI0bDdPR1pmWgoxUG90OE4wM2lmNUN1N2lldGRhSUczYW4wNWZKYnJFTXVBaXFEdWtjb3FnNmxVRzlyZVdHQnRKUlBIMHMwRHNxCkVXNFM5Tzc2eHhUTWxLai9Tdlh2WHVkVUVBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" + certificate_password = "" + } +} + +container_app_environment_storages = { + caes1 = { + name = "caes-storage-001" + container_app_environment_key = "cae1" + storage_account = { + account_key = "sa1" + } + share_name = "fs1" + access_mode = "ReadWrite" + } +} + +container_apps = { + ca1 = { + name = "nginx-app" + container_app_environment_key = "cae1" + resource_group_key = "rg1" + + revision_mode = "Single" + template = { + container = { + cont1 = { + name = "nginx" + image = "nginx:latest" + cpu = 0.5 + memory = "1Gi" + liveness_probe = { + port = 80 + transport = "HTTP" + } + readiness_probe = { + port = 80 + transport = "HTTP" + } + startup_probe = { + port = 80 + transport = "HTTP" + } + env = [ + { + name = "VAR1" + value = "value1" + }, + { + name = "VAR2" + value = 2 + }, + { + name = "SECRET_VAR" + secret_name = "secret1" + } + ] + volume_mounts = { + vol1 = { + name = "vol1" + path = "/mnt/vol1" + } + } + } + } + + min_replicas = 1 + max_replicas = 3 + + http_scale_rule = { + rule1 = { + name = "azure-http-rule" + concurrent_requests = 50 + } + } + + volume = { + vol1 = { + name = "vol1" + storage_name = "caes-storage-001" + storage_type = "AzureFile" + } + } + } + ingress = { + external_enabled = false + target_port = 80 + transport = "http" + allow_insecure_connections = true + traffic_weight = { + blue = { + label = "blue" + latest_revision = false + revision_suffix = "blue" + percentage = 70 + } + green = { + label = "green" + latest_revision = true + revision_suffix = "green" + percentage = 30 + } + } + custom_domain = { + example = { + certificate_key = "caec1" + name = "example.com" + } + } + } + secret = [ + { + name = "secret1" + value = "djwHJcwjh" + }, + { + name = "secret2" + value = "cdjGHjew" + } + ] + identity = { + type = "UserAssigned" // Possible options are 'SystemAssigned, UserAssigned' 'SystemAssigned' or 'UserAssigned' + managed_identity_keys = [ + "msi1" + ] + } + # registry = { + # server = "testacr.azurecr.io" + # identity = { + # key = "msi1" + # } + # } + }, + ca2 = { + name = "dapr-app" + container_app_environment_key = "cae1" + resource_group_key = "rg1" + + revision_mode = "Single" + dapr = { + app_id = "nodeapp" + app_port = 3000 + } + template = { + container = { + cont1 = { + name = "nodeapp" + image = "daprio/daprd:edge" + cpu = 0.5 + memory = "1Gi" + } + } + min_replicas = 1 + max_replicas = 1 + } + } +} diff --git a/examples/compute/kubernetes_services/101-single-cluster/aks.tfvars b/examples/compute/kubernetes_services/101-single-cluster/aks.tfvars index dbbf22f00e..87218b10ff 100644 --- a/examples/compute/kubernetes_services/101-single-cluster/aks.tfvars +++ b/examples/compute/kubernetes_services/101-single-cluster/aks.tfvars @@ -18,6 +18,8 @@ aks_clusters = { resource_group_key = "aks_re1" os_type = "Linux" + cost_analysis_enabled = true + identity = { type = "SystemAssigned" } @@ -61,11 +63,12 @@ aks_clusters = { key = "aks_nodepool_system" #resource_id = "/subscriptions/97958dac-xxxx-xxxx-xxxx-9f436fa73bd4/resourceGroups/qxgc-rg-aks-re1/providers/Microsoft.Network/virtualNetworks/qxgc-vnet-aks/subnets/qxgc-snet-aks_nodepool_system" } - enabled_auto_scaling = false - enable_node_public_ip = false - max_pods = 30 - node_count = 1 - os_disk_size_gb = 512 + enabled_auto_scaling = false + enable_node_public_ip = false + max_pods = 30 + node_count = 1 + os_disk_size_gb = 512 + temporary_name_for_rotation = "temp" tags = { "project" = "system services" } @@ -80,4 +83,4 @@ aks_clusters = { } } } -} \ No newline at end of file +} diff --git a/examples/compute/kubernetes_services/108-single-cluster-remote-adgroup-admin/aks.tfvars b/examples/compute/kubernetes_services/108-single-cluster-remote-adgroup-admin/aks.tfvars index f147de340c..da406c0403 100644 --- a/examples/compute/kubernetes_services/108-single-cluster-remote-adgroup-admin/aks.tfvars +++ b/examples/compute/kubernetes_services/108-single-cluster-remote-adgroup-admin/aks.tfvars @@ -39,7 +39,7 @@ aks_clusters = { addon_profile = { oms_agent = { - log_analytics_key = "central_logs_region1" + log_analytics_key = "central_logs_region1" msi_auth_for_monitoring_enabled = true } } diff --git a/examples/compute/kubernetes_services/109-single-cluster-istio/aks.tfvars b/examples/compute/kubernetes_services/109-single-cluster-istio/aks.tfvars new file mode 100644 index 0000000000..89661ee997 --- /dev/null +++ b/examples/compute/kubernetes_services/109-single-cluster-istio/aks.tfvars @@ -0,0 +1,88 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "australiaeast" + } +} + +resource_groups = { + aks_re1 = { + name = "aks-re1" + region = "region1" + } +} + +aks_clusters = { + cluster_re1 = { + name = "akscluster-re1-001" + resource_group_key = "aks_re1" + os_type = "Linux" + + identity = { + type = "SystemAssigned" + } + + vnet_key = "spoke_aks_re1" + + network_profile = { + network_plugin = "azure" + load_balancer_sku = "standard" + } + + # enable_rbac = true + role_based_access_control = { + enabled = true + azure_active_directory = { + managed = true + } + } + + oms_agent = { + log_analytics_key = "central_logs_region1" + } + + service_mesh_profile = { + internal_ingress_gateway_enabled = true + mode = "Istio" + } + + # admin_groups = { + # # ids = [] + # # azuread_groups = { + # # keys = [] + # # } + # } + + load_balancer_profile = { + # Only one option can be set + managed_outbound_ip_count = 1 + } + + default_node_pool = { + name = "sharedsvc" + vm_size = "Standard_F4s_v2" + #subnet_key = "aks_nodepool_system" + subnet = { + key = "aks_nodepool_system" + #resource_id = "/subscriptions/97958dac-xxxx-xxxx-xxxx-9f436fa73bd4/resourceGroups/qxgc-rg-aks-re1/providers/Microsoft.Network/virtualNetworks/qxgc-vnet-aks/subnets/qxgc-snet-aks_nodepool_system" + } + enabled_auto_scaling = false + enable_node_public_ip = false + max_pods = 30 + node_count = 1 + os_disk_size_gb = 512 + tags = { + "project" = "system services" + } + } + + node_resource_group_name = "aks-nodes-re1" + + addon_profile = { + azure_keyvault_secrets_provider = { + secret_rotation_enabled = true + secret_rotation_interval = "2m" + } + } + } +} diff --git a/examples/compute/kubernetes_services/109-single-cluster-istio/diagnostics.tfvars b/examples/compute/kubernetes_services/109-single-cluster-istio/diagnostics.tfvars new file mode 100644 index 0000000000..ab1f3ee038 --- /dev/null +++ b/examples/compute/kubernetes_services/109-single-cluster-istio/diagnostics.tfvars @@ -0,0 +1,7 @@ +diagnostic_log_analytics = { + central_logs_region1 = { + region = "region1" + name = "logs" + resource_group_key = "aks_re1" + } +} diff --git a/examples/compute/kubernetes_services/109-single-cluster-istio/networking.tfvars b/examples/compute/kubernetes_services/109-single-cluster-istio/networking.tfvars new file mode 100644 index 0000000000..7707a24d01 --- /dev/null +++ b/examples/compute/kubernetes_services/109-single-cluster-istio/networking.tfvars @@ -0,0 +1,190 @@ +vnets = { + spoke_aks_re1 = { + resource_group_key = "aks_re1" + region = "region1" + vnet = { + name = "aks" + address_space = ["100.64.48.0/22"] + } + specialsubnets = {} + subnets = { + aks_nodepool_system = { + name = "aks_nodepool_system" + cidr = ["100.64.48.0/24"] + nsg_key = "azure_kubernetes_cluster_nsg" + } + aks_nodepool_user1 = { + name = "aks_nodepool_user1" + cidr = ["100.64.49.0/24"] + nsg_key = "azure_kubernetes_cluster_nsg" + } + aks_nodepool_user2 = { + name = "aks_nodepool_user2" + cidr = ["100.64.50.0/24"] + nsg_key = "azure_kubernetes_cluster_nsg" + } + AzureBastionSubnet = { + name = "AzureBastionSubnet" #Must be called AzureBastionSubnet + cidr = ["100.64.51.64/27"] + nsg_key = "azure_bastion_nsg" + } + private_endpoints = { + name = "private_endpoints" + cidr = ["100.64.51.0/27"] + enforce_private_link_endpoint_network_policies = true + } + jumpbox = { + name = "jumpbox" + cidr = ["100.64.51.128/27"] + nsg_key = "azure_bastion_nsg" + } + } + + } +} + +network_security_group_definition = { + # This entry is applied to all subnets with no NSG defined + empty_nsg = {} + azure_kubernetes_cluster_nsg = { + nsg = [ + { + name = "aks-http-in-allow", + priority = "100" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "80" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "aks-https-in-allow", + priority = "110" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "aks-api-out-allow-1194", + priority = "100" + direction = "Outbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "1194" + source_address_prefix = "*" + destination_address_prefix = "AzureCloud" + }, + { + name = "aks-api-out-allow-9000", + priority = "110" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "9000" + source_address_prefix = "*" + destination_address_prefix = "AzureCloud" + }, + { + name = "aks-ntp-out-allow", + priority = "120" + direction = "Outbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "123" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "aks-https-out-allow-443", + priority = "130" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + ] + } + azure_bastion_nsg = { + + nsg = [ + { + name = "bastion-in-allow", + priority = "100" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "*" + destination_address_prefix = "*" + }, + { + name = "bastion-control-in-allow-443", + priority = "120" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "135" + source_address_prefix = "GatewayManager" + destination_address_prefix = "*" + }, + { + name = "Kerberos-password-change", + priority = "121" + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "4443" + source_address_prefix = "GatewayManager" + destination_address_prefix = "*" + }, + { + name = "bastion-vnet-out-allow-22", + priority = "103" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "VirtualNetwork" + }, + { + name = "bastion-vnet-out-allow-3389", + priority = "101" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "3389" + source_address_prefix = "*" + destination_address_prefix = "VirtualNetwork" + }, + { + name = "bastion-azure-out-allow", + priority = "120" + direction = "Outbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "443" + source_address_prefix = "*" + destination_address_prefix = "AzureCloud" + } + ] + } +} diff --git a/examples/compute/virtual_machine/113-single-linux-custom-data-template/configuration.tfvars b/examples/compute/virtual_machine/113-single-linux-custom-data-template/configuration.tfvars index 35822f8398..42b9ea57b3 100644 --- a/examples/compute/virtual_machine/113-single-linux-custom-data-template/configuration.tfvars +++ b/examples/compute/virtual_machine/113-single-linux-custom-data-template/configuration.tfvars @@ -63,23 +63,23 @@ virtual_machines = { disable_password_authentication = true custom_data = { - templatefile = "compute/virtual_machine/113-single-linux-custom-data-template/custom_data.tpl" - my_value = "my_value" + templatefile = "compute/virtual_machine/113-single-linux-custom-data-template/custom_data.tpl" + my_value = "my_value" } dynamic_custom_data = { vnets = { - vnet_region1 ={} + vnet_region1 = {} } storage_accounts = { sa1 = { - file_share = "share1" - file_share_directory = "dir1" + file_share = "share1" + file_share_directory = "dir1" } } keyvault_keys = { key1 = { keyvault_key = "example_vm_rg1" - name = "disk-key" + name = "disk-key" } } } diff --git a/examples/compute/virtual_machine/212-vm-disk-encryption-set/configurations.tfvars b/examples/compute/virtual_machine/212-vm-disk-encryption-set/configurations.tfvars index 56bdeaed0f..615d94cd16 100644 --- a/examples/compute/virtual_machine/212-vm-disk-encryption-set/configurations.tfvars +++ b/examples/compute/virtual_machine/212-vm-disk-encryption-set/configurations.tfvars @@ -152,6 +152,7 @@ virtual_machines = { disk_encryption_set_key = "set1" # lz_key = "" # for remote disk_encryption_set + # disk_encryption_set_id = "/subscription/xxx/id" # for disk_encryption_set_id } source_image_reference = { diff --git a/examples/data_explorer/107-private-endpoint/configuration.tfvars b/examples/data_explorer/107-private-endpoint/configuration.tfvars new file mode 100644 index 0000000000..f831afb6e6 --- /dev/null +++ b/examples/data_explorer/107-private-endpoint/configuration.tfvars @@ -0,0 +1,75 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "eastus" + } +} + +resource_groups = { + rg1 = { + name = "dedicated-test" + region = "region1" + } +} +kusto_clusters = { + kc1 = { + name = "kustocluster" + auto_stop_enabled = false + resource_group = { + key = "rg1" + #lz_key = "" + #name = "" + } + region = "region1" + + sku = { + name = "Dev(No SLA)_Standard_E2a_v4" + capacity = 1 + } + + private_endpoints = { + pe1 = { + name = "kusto-shared" + resource_group_key = "rg1" + vnet_key = "vnet_region1" + subnet_key = "private_endpoints" + private_service_connection = { + name = "kusto-shared" + is_manual_connection = false + subresource_names = ["cluster"] + } + private_dns = { + keys = ["kusto"] + } + } + } + } +} + +## Networking configuration +vnets = { + vnet_region1 = { + resource_group_key = "rg1" + region = "region1" + + vnet = { + name = "kusto" + address_space = ["10.10.0.0/24"] + } + + subnets = { + private_endpoints = { + name = "private-endpoint" + cidr = ["10.10.0.0/25"] + enforce_private_link_endpoint_network_policies = true + } + } + } +} + +private_dns = { + kusto = { + name = "privatelink.westeurope.kusto.windows.net" + resource_group_key = "rg1" + } +} diff --git a/examples/databricks_access_connectors/100-databricks_access_connectors/configuration.tfvars b/examples/databricks_access_connectors/100-databricks_access_connectors/configuration.tfvars new file mode 100644 index 0000000000..e7ece91817 --- /dev/null +++ b/examples/databricks_access_connectors/100-databricks_access_connectors/configuration.tfvars @@ -0,0 +1,34 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "australiaeast" + } +} + +resource_groups = { + dac_test = { + name = "rg-databricks-access-connectors" + } +} + +databricks_access_connectors = { + dac_1 = { + name = "example-name" + resource_group_key = "dac_test" + identity = { + type = "UserAssigned" #SystemAssigned + managed_identity_keys = ["dac_test"] + } + tags = { + test = "test" + test1 = "test1" + } + } +} + +managed_identities = { + dac_test = { + name = "mi-dac-test" + resource_group_key = "dac_test" + } +} diff --git a/examples/digital_twins/101-adt-servicebus/configuration.tfvars b/examples/digital_twins/101-adt-servicebus/configuration.tfvars index 94209583e9..de91dda74c 100644 --- a/examples/digital_twins/101-adt-servicebus/configuration.tfvars +++ b/examples/digital_twins/101-adt-servicebus/configuration.tfvars @@ -1,7 +1,7 @@ global_settings = { default_region = "region1" regions = { - region1 = "southeastasia" + region1 = "australiaeast" } } @@ -106,6 +106,7 @@ servicebus_namespaces = { sku = "Premium" # Basic | standard | Premium capacity = 1 # capacity only for Premium: 1,2,4,8,16 otherwise 0 # zone_redundant = false # only true for Premium + premium_messaging_partitions = 1 # tags = {} # optional namespace_auth_rules = { rule1 = { diff --git a/examples/identity/active_directory_domain_service/100-active_directory_domain_service-replica/configuration.tfvars b/examples/identity/active_directory_domain_service/100-active_directory_domain_service-replica/configuration.tfvars index 72b9319c3e..e0adc702d1 100644 --- a/examples/identity/active_directory_domain_service/100-active_directory_domain_service-replica/configuration.tfvars +++ b/examples/identity/active_directory_domain_service/100-active_directory_domain_service-replica/configuration.tfvars @@ -37,9 +37,10 @@ active_directory_domain_service = { resource_group = { key = "rg" } - domain_name = "widgetslogin.net" - sku = "Enterprise" - filtered_sync_enabled = false + domain_name = "widgetslogin.net" + sku = "Enterprise" + filtered_sync_enabled = false + domain_configuration_type = "FullySynced" initial_replica_set = { region = "region1" @@ -79,4 +80,4 @@ active_directory_domain_service_replica_set = { key = "aadds" } } -} \ No newline at end of file +} diff --git a/examples/iot/100-iot-hub/configuration.tfvars b/examples/iot/100-iot-hub/configuration.tfvars index 28769ed613..835b5ddaf8 100644 --- a/examples/iot/100-iot-hub/configuration.tfvars +++ b/examples/iot/100-iot-hub/configuration.tfvars @@ -43,7 +43,7 @@ iot_hub_certificate = { key = "iothub1" } is_verified = true - certificate_content = "iot/100-iot-hub/cert.pem" + certificate_content = "examples/iot/100-iot-hub/cert.pem" } } diff --git a/examples/iot/103-iot-hub-with-dps/configuration.tfvars b/examples/iot/103-iot-hub-with-dps/configuration.tfvars index 11b85e838c..5a89365040 100644 --- a/examples/iot/103-iot-hub-with-dps/configuration.tfvars +++ b/examples/iot/103-iot-hub-with-dps/configuration.tfvars @@ -67,7 +67,7 @@ iot_dps_certificate = { key = "dps1" } resource_group_key = "ioth_region1" - certificate_content = "iot/103-iot-hub-with-dps/cert.pem" + certificate_content = "examples/iot/103-iot-hub-with-dps/cert.pem" } } diff --git a/examples/load_test/100-load-test/configuration.tfvars b/examples/load_test/100-load-test/configuration.tfvars new file mode 100644 index 0000000000..ecce19bdee --- /dev/null +++ b/examples/load_test/100-load-test/configuration.tfvars @@ -0,0 +1,33 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "uksouth" + } +} + +resource_groups = { + load-test-region1 = { + name = "load-test-rg" + region = "region1" + } +} + +load_test = { + example_load_test = { + name = "example-load-test" + resource_group_key = "load-test-region1" + identity = { + type = "UserAssigned" + managed_identity_keys = ["load_test"] + } + } +} + +managed_identities = { + load_test = { + name = "load-test" + resource_group = { + key = "load-test-region1" + } + } +} diff --git a/examples/logic_app/110-logic_app_vnet_integration_private_endpoint_managed_identity/configuration.tfvars b/examples/logic_app/110-logic_app_vnet_integration_private_endpoint_managed_identity/configuration.tfvars new file mode 100644 index 0000000000..da855810fa --- /dev/null +++ b/examples/logic_app/110-logic_app_vnet_integration_private_endpoint_managed_identity/configuration.tfvars @@ -0,0 +1,97 @@ +resource_groups = { + la_test = { + name = "rg-logic-app" + } +} + +vnets = { + vnet = { + resource_group_key = "la_test" + vnet = { + name = "la-vnet" + address_space = ["10.0.0.0/24"] + } + subnets = { + private_endpoints_sn = { + name = "private-endpoints" + cidr = ["10.0.0.32/27"] + enforce_private_link_endpoint_network_policies = false + enforce_private_link_service_network_policies = false + } + la_test_subnet = { + name = "logic_apps" + cidr = ["10.0.0.64/27"] + delegation = { + name = "functions" + service_delegation = "Microsoft.Web/serverFarms" + actions = ["Microsoft.Network/virtualNetworks/subnets/action"] + } + } + } + } +} + +storage_accounts = { + sa1 = { + name = "la_sa" + resource_group_key = "la_test" + account_tier = "Standard" + account_replication_type = "LRS" + } +} + +managed_identities = { + logicapp_msi = { + name = "logicapp1-msi" + resource_group_key = "la_test" + } +} + + +app_service_plans = { + asp1 = { + name = "appserviceplan1" + resource_group_key = "la_test" + kind = "elastic" + + sku = { + tier = "WorkflowStandard" + size = "WS1" + } + } +} + +logic_app_standard = { + las1 = { + name = "logicapp1" + resource_group_key = "la_test" + app_service_plan_key = "asp1" + storage_account_key = "sa1" + version = "~4" + # Required for virtual network integration + vnet_integration = { + vnet_key = "vnet" + subnet_key = "la_test_subnet" + # lz_key = "" + # subnet_id = "" + } + identity = { + type = "UserAssigned" #SystemAssigned + key = "logicapp_msi" + #lz_key = "" + #identity_ids = ["/subscriptions/sub-id/resourceGroups/rg-id/providers/Microsoft.ManagedIdentity/userAssignedIdentities/msi-id"] + } + private_endpoints = { + pe_la = { + private_service_connection = { + name = "pe_la_sc" + subresource_names = ["sites"] + } + name = "pe_la" + vnet_key = "vnet" + subnet_key = "private_endpoints_sn" + #lz_key = "" + } + } + } +} \ No newline at end of file diff --git a/examples/main.tf b/examples/main.tf index 64a74b9c1d..1834c20c66 100644 --- a/examples/main.tf +++ b/examples/main.tf @@ -57,6 +57,9 @@ provider "azurerm" { features {} } + +provider "azuread" {} + data "azurerm_client_config" "default" {} locals { diff --git a/examples/maintenance_configuration/100-maintenance-configuration/configuration.tfvars b/examples/maintenance_configuration/100-maintenance-configuration/configuration.tfvars new file mode 100644 index 0000000000..82e88aa232 --- /dev/null +++ b/examples/maintenance_configuration/100-maintenance-configuration/configuration.tfvars @@ -0,0 +1,26 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "northeurope" + } +} + +resource_groups = { + rg1 = { + name = "rsg_umc" + region = "region1" + } +} + +maintenance_configuration = { + mc_re1 = { + name = "example-mc" + region = "region1" + resource_group_key = "rg1" + scope = "Host" + # tags = {} # optional + } +} + + + diff --git a/examples/maintenance_configuration/101-maintenance-configuration-schedule/configuration.tfvars b/examples/maintenance_configuration/101-maintenance-configuration-schedule/configuration.tfvars new file mode 100644 index 0000000000..1f4383d71c --- /dev/null +++ b/examples/maintenance_configuration/101-maintenance-configuration-schedule/configuration.tfvars @@ -0,0 +1,41 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "northeurope" + } +} + +resource_groups = { + rg1 = { + name = "rsg_umc" + region = "region1" + } +} + +maintenance_configuration = { + mc_re1 = { + name = "example-mc" + region = "region1" + resource_group_key = "rg1" + scope = "InGuestPatch" + in_guest_user_patch_mode = "User" + window = { + start_date_time = "2023-06-08 15:04" + duration = "03:55" + time_zone = "Romance Standard Time" + recur_every = "2Day" + } + + install_patches = { + windows = { + classifications_to_include = ["Critical", "Security"] + # kb_numbers_to_exclude = ["KB123456", "KB789012"] + # kb_numbers_to_include = ["KB345678", "KB901234"] + } + reboot = "IfRequired" + } + # tags = {} # optional + } +} + + diff --git a/examples/maintenance_configuration/200-maintenance-configuration-assignment-vm-windows/configuration.tfvars b/examples/maintenance_configuration/200-maintenance-configuration-assignment-vm-windows/configuration.tfvars new file mode 100644 index 0000000000..dc7b8369b2 --- /dev/null +++ b/examples/maintenance_configuration/200-maintenance-configuration-assignment-vm-windows/configuration.tfvars @@ -0,0 +1,156 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "northeurope" + } +} + +resource_groups = { + rg1 = { + name = "rsg_umc" + region = "region1" + } +} + +keyvaults = { + example_vm_rg1 = { + name = "vmsecrets" + resource_group_key = "rg1" + sku_name = "standard" + creation_policies = { + logged_in_user = { + secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] + } + } + } +} + +vnets = { + vnet_region1 = { + resource_group_key = "rg1" + vnet = { + name = "virtual_machines" + address_space = ["10.100.100.0/24"] + } + specialsubnets = {} + subnets = { + example = { + name = "examples" + cidr = ["10.100.100.0/29"] + } + } + + } +} + +public_ip_addresses = { + example_vm_pip1_rg1 = { + name = "example_vm_pip1" + resource_group_key = "rg1" + sku = "Standard" + allocation_method = "Static" + ip_version = "IPv4" + idle_timeout_in_minutes = "4" + + } +} + +virtual_machines = { + + # Configuration to deploy a bastion host linux virtual machine + example_vm1 = { + resource_group_key = "rg1" + provision_vm_agent = true + # when boot_diagnostics_storage_account_key is empty string "", boot diagnostics will be put on azure managed storage + # when boot_diagnostics_storage_account_key is a non-empty string, it needs to point to the key of a user managed storage defined in diagnostic_storage_accounts + # if boot_diagnostics_storage_account_key is not defined, but global_settings.resource_defaults.virtual_machines.use_azmanaged_storage_for_boot_diagnostics is true, boot diagnostics will be put on azure managed storage + + os_type = "windows" + + # the auto-generated ssh key in keyvault secret. Secret name being {VM name}-ssh-public and {VM name}-ssh-private + keyvault_key = "example_vm_rg1" + + # Define the number of networking cards to attach the virtual machine + networking_interfaces = { + nic0 = { + # Value of the keys from networking.tfvars + vnet_key = "vnet_region1" + subnet_key = "example" + name = "0" + enable_ip_forwarding = false + internal_dns_name_label = "nic0" + public_ip_address_key = "example_vm_pip1_rg1" + } + } + + virtual_machine_settings = { + windows = { + name = "example_vm1" + size = "Standard_F2" + admin_username = "adminuser" + + + # Spot VM to save money + priority = "Spot" + eviction_policy = "Deallocate" + + patch_mode = "AutomaticByPlatform" + bypass_platform_safety_checks_on_user_schedule_enabled = true + # When you want to load the file from the folder in the custom_data always use the relative path from the caf_solution in landing zones + custom_data = "../../examples/compute/virtual_machine/101-single-windows-vm/scripts/custom.ps1" + # Value of the nic keys to attach the VM. The first one in the list is the default nic + network_interface_keys = ["nic0"] + + os_disk = { + name = "example_vm1-os" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference = { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + } + } + } +} + +maintenance_configuration = { + mc_re1 = { + name = "example-mc" + region = "region1" + resource_group_key = "rg1" + scope = "InGuestPatch" + in_guest_user_patch_mode = "User" + window = { + start_date_time = "2023-06-08 15:04" + duration = "03:55" + time_zone = "Romance Standard Time" + recur_every = "2Day" + } + + install_patches = { + windows = { + classifications_to_include = ["Critical", "Security"] + # kb_numbers_to_exclude = ["KB123456", "KB789012"] + # kb_numbers_to_include = ["KB345678", "KB901234"] + } + reboot = "IfRequired" + } + # tags = {} # optional + } +} + +maintenance_assignment_virtual_machine = { + example = { + region = "region1" + maintenance_configuration_key = "mc_re1" + virtual_machine = { + key = "example_vm1" + } + } +} diff --git a/examples/maintenance_configuration/201-maintenance-configuration-assignment-vm-linux/configuration.tfvars b/examples/maintenance_configuration/201-maintenance-configuration-assignment-vm-linux/configuration.tfvars new file mode 100644 index 0000000000..2da8bdcddc --- /dev/null +++ b/examples/maintenance_configuration/201-maintenance-configuration-assignment-vm-linux/configuration.tfvars @@ -0,0 +1,213 @@ + +global_settings = { + default_region = "region1" + regions = { + region1 = "australiaeast" + } + + inherit_tags = true + + resource_defaults = { + virtual_machines = { + # set the below to enable az managed boot diagostics for vms + # this will be override if a user managed storage account is defined for the vm + # use_azmanaged_storage_for_boot_diagnostics = true + } + } +} + +resource_groups = { + vm_region1 = { + name = "example-virtual-machine-rg1" + } +} + +# Virtual machines +virtual_machines = { + + # Configuration to deploy a bastion host linux virtual machine + example_vm1 = { + resource_group_key = "vm_region1" + provision_vm_agent = true + # when boot_diagnostics_storage_account_key is empty string "", boot diagnostics will be put on azure managed storage + # when boot_diagnostics_storage_account_key is a non-empty string, it needs to point to the key of a user managed storage defined in diagnostic_storage_accounts + # if boot_diagnostics_storage_account_key is not defined, but global_settings.resource_defaults.virtual_machines.use_azmanaged_storage_for_boot_diagnostics is true, boot diagnostics will be put on azure managed storage + + os_type = "linux" + + # the auto-generated ssh key in keyvault secret. Secret name being {VM name}-ssh-public and {VM name}-ssh-private + keyvault_key = "example_vm_rg1" + + # Define the number of networking cards to attach the virtual machine + # Option to use when BYOI (Bring your Own Interface) + # networking_interface_ids = ["/subscriptions//resourceGroups//providers/Microsoft.Network/networkInterfaces/"] + + networking_interfaces = { + nic0 = { + # Value of the keys from networking.tfvars + vnet_key = "vnet_region1" + subnet_key = "example" + primary = true + name = "0" + enable_ip_forwarding = false + internal_dns_name_label = "nic0" + public_ip_address_key = "example_vm_pip1_rg1" + # example with external network objects + # subnet_id = "/subscriptions/sub-id/resourceGroups/test-manual/providers/Microsoft.Network/virtualNetworks/vnet/subnets/default" + # public_address_id = "/subscriptions/sub-id/resourceGroups/test-manual/providers/Microsoft.Network/publicIPAddresses/arnaudip" + # nsg_id = "/subscriptions/sub-id/resourceGroups/test-manual/providers/Microsoft.Network/networkSecurityGroups/nsgtest" + + } + } + + virtual_machine_settings = { + linux = { + name = "example_vm1" + size = "Standard_F2" + admin_username = "adminuser" + disable_password_authentication = true + + # Spot VM to save money + priority = "Spot" + eviction_policy = "Deallocate" + + patch_mode = "AutomaticByPlatform" + bypass_platform_safety_checks_on_user_schedule_enabled = true + + # Value of the nic keys to attach the VM. The first one in the list is the default nic + network_interface_keys = ["nic0"] + + os_disk = { + name = "example_vm1-os" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + identity = { + type = "SystemAssigned" #SystemAssigned OR UserAssigned OR SystemAssigned, UserAssigned + # remote = { + # remote_kz_key = { # remote lz key + # managed_identity_keys = [""] # remote msi resource key + # } + # } + # managed_identity_keys = [""] //local msi resource key + } + source_image_reference = { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "18.04-LTS" + version = "latest" + } + + } + } + data_disks = { + data1 = { + name = "server1-data1" + storage_account_type = "Standard_LRS" + # Only Empty is supported. More community contributions required to cover other scenarios + create_option = "Empty" + disk_size_gb = "10" + lun = 1 + zones = ["1"] + } + } + } +} + + +keyvaults = { + example_vm_rg1 = { + name = "vmlinuxakv" + resource_group_key = "vm_region1" + sku_name = "standard" + soft_delete_enabled = true + purge_protection_enabled = true + enabled_for_disk_encryption = true + creation_policies = { + logged_in_user = { + secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] + key_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore", "Decrypt", "Encrypt", "UnwrapKey", "WrapKey", "Verify", "Sign", "Purge"] + } + } + } +} + +keyvault_keys = { + key1 = { + keyvault_key = "example_vm_rg1" + resource_group_key = "vm_region1" + name = "disk-key" + key_type = "RSA" + key_size = "2048" + key_opts = ["encrypt", "decrypt", "sign", "verify", "wrapKey", "unwrapKey"] + tags = { + encryption = "rsa-204" + new_tag = "yes" } + } +} + +vnets = { + vnet_region1 = { + resource_group_key = "vm_region1" + vnet = { + name = "virtual_machines" + address_space = ["10.100.100.0/24"] + } + specialsubnets = {} + subnets = { + example = { + name = "examples" + cidr = ["10.100.100.0/29"] + } + } + + } +} + +public_ip_addresses = { + example_vm_pip1_rg1 = { + name = "example_vm_pip1" + resource_group_key = "vm_region1" + sku = "Standard" + allocation_method = "Static" + ip_version = "IPv4" + idle_timeout_in_minutes = "4" + + } +} + +maintenance_configuration = { + mc_re1 = { + name = "example-mc" + region = "region1" + resource_group_key = "vm_region1" + scope = "InGuestPatch" + in_guest_user_patch_mode = "User" + window = { + start_date_time = "2023-06-08 15:04" + duration = "03:55" + time_zone = "Romance Standard Time" + recur_every = "2Day" + } + + install_patches = { + linux = { + classifications_to_include = ["Critical", "Security"] + # package_names_mask_to_exclude = ["ppt"] + # package_names_mask_to_include = ["apt"] + } + reboot = "IfRequired" + } + # tags = {} # optional + } +} + +maintenance_assignment_virtual_machine = { + example = { + region = "region1" + maintenance_configuration_key = "mc_re1" + virtual_machine = { + key = "example_vm1" + } + } +} diff --git a/examples/messaging/eventgrid/300-simple-eventgrid-system-topic/configuration.tfvars b/examples/messaging/eventgrid/300-simple-eventgrid-system-topic/configuration.tfvars new file mode 100644 index 0000000000..02a3923f16 --- /dev/null +++ b/examples/messaging/eventgrid/300-simple-eventgrid-system-topic/configuration.tfvars @@ -0,0 +1,64 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "southeastasia" + } +} + +resource_groups = { + evg_examples = { + name = "eventgrid" + region = "region1" + } +} + +storage_accounts = { + sa1 = { + name = "0665ba08d3ae" + resource_group_key = "evg_examples" + account_kind = "BlobStorage" + account_tier = "Standard" + # account_replication_type = "LRS" + containers = { + dev = { + name = "random" + } + } + } +} + +eventgrid_system_topic = { + egt1 = { + name = "egt1" + resource_group = { + key = "evg_examples" + } + region = "region1" + + # topic_type can be one of these, more resource types can be supported + # Microsoft.AppConfiguration.ConfigurationStores + # Microsoft.Communication.CommunicationServices + # Microsoft.ContainerRegistry.Registries + # Microsoft.Devices.IoTHubs + # Microsoft.EventGrid.Domains + # Microsoft.EventGrid.Topics + # Microsoft.Eventhub.Namespaces + # Microsoft.KeyVault.vaults + # Microsoft.MachineLearningServices.Workspaces + # Microsoft.Maps.Accounts + # Microsoft.Media.MediaServices + # Microsoft.Resources.ResourceGroups + # Microsoft.Resources.Subscriptions + # Microsoft.ServiceBus.Namespaces + # Microsoft.SignalRService.SignalR + # Microsoft.Storage.StorageAccounts + # Microsoft.Web.ServerFarms + # Microsoft.Web.Sites + topic_type = "Microsoft.Storage.StorageAccounts" + + source_resource = { + type = "storage_accounts" + key = "sa1" + } + } +} diff --git a/examples/servicebus/200-servicebus-privatelink/configuration.tfvars b/examples/messaging/servicebus/200-servicebus-privatelink/configuration.tfvars similarity index 100% rename from examples/servicebus/200-servicebus-privatelink/configuration.tfvars rename to examples/messaging/servicebus/200-servicebus-privatelink/configuration.tfvars diff --git a/examples/module.tf b/examples/module.tf index b7d44ef80a..f2fbbc1c6c 100644 --- a/examples/module.tf +++ b/examples/module.tf @@ -93,31 +93,36 @@ module "example" { communication_services = var.communication_services } compute = { - aks_clusters = var.aks_clusters - aro_clusters = var.aro_clusters - availability_sets = var.availability_sets - azure_container_registries = var.azure_container_registries - batch_accounts = var.batch_accounts - batch_applications = var.batch_applications - batch_certificates = var.batch_certificates - batch_jobs = var.batch_jobs - batch_pools = var.batch_pools - bastion_hosts = var.bastion_hosts - container_groups = var.container_groups - dedicated_host_groups = var.dedicated_host_groups - dedicated_hosts = var.dedicated_hosts - machine_learning_compute_instance = var.machine_learning_compute_instance - proximity_placement_groups = var.proximity_placement_groups - runbooks = var.runbooks - virtual_machine_scale_sets = var.virtual_machine_scale_sets - virtual_machines = var.virtual_machines - vmware_private_clouds = var.vmware_private_clouds - vmware_clusters = var.vmware_clusters - vmware_express_route_authorizations = var.vmware_express_route_authorizations - wvd_applications = var.wvd_applications - wvd_application_groups = var.wvd_application_groups - wvd_host_pools = var.wvd_host_pools - wvd_workspaces = var.wvd_workspaces + aks_clusters = var.aks_clusters + aro_clusters = var.aro_clusters + availability_sets = var.availability_sets + azure_container_registries = var.azure_container_registries + batch_accounts = var.batch_accounts + batch_applications = var.batch_applications + batch_certificates = var.batch_certificates + batch_jobs = var.batch_jobs + batch_pools = var.batch_pools + bastion_hosts = var.bastion_hosts + container_apps = var.container_apps + container_app_dapr_components = var.container_app_dapr_components + container_app_environments = var.container_app_environments + container_app_environment_certificates = var.container_app_environment_certificates + container_app_environment_storages = var.container_app_environment_storages + container_groups = var.container_groups + dedicated_host_groups = var.dedicated_host_groups + dedicated_hosts = var.dedicated_hosts + machine_learning_compute_instance = var.machine_learning_compute_instance + proximity_placement_groups = var.proximity_placement_groups + runbooks = var.runbooks + virtual_machine_scale_sets = var.virtual_machine_scale_sets + virtual_machines = var.virtual_machines + vmware_private_clouds = var.vmware_private_clouds + vmware_clusters = var.vmware_clusters + vmware_express_route_authorizations = var.vmware_express_route_authorizations + wvd_applications = var.wvd_applications + wvd_application_groups = var.wvd_application_groups + wvd_host_pools = var.wvd_host_pools + wvd_workspaces = var.wvd_workspaces } diagnostics = { diagnostic_event_hub_namespaces = var.diagnostic_event_hub_namespaces @@ -136,6 +141,7 @@ module "example" { databricks_workspaces = var.databricks_workspaces database_migration_services = var.database_migration_services databricks_workspaces = var.databricks_workspaces + databricks_access_connectors = var.databricks_access_connectors machine_learning_workspaces = var.machine_learning_workspaces mariadb_servers = var.mariadb_servers mariadb_databases = var.mariadb_databases @@ -260,6 +266,7 @@ module "example" { vnets = var.vnets virtual_subnets = var.virtual_subnets vpn_gateway_connections = var.vpn_gateway_connections + vpn_gateway_nat_rules = var.vpn_gateway_nat_rules vpn_sites = var.vpn_sites } @@ -417,5 +424,15 @@ module "example" { } powerbi_embedded = var.powerbi_embedded + load_test = var.load_test + preview_features = var.preview_features + + maintenance = { + maintenance_configuration = var.maintenance_configuration + maintenance_assignment_virtual_machine = var.maintenance_assignment_virtual_machine + } + search_services = { + search_services = var.search_services + } } diff --git a/examples/mssql_mi/200-mi/configuration.tfvars b/examples/mssql_mi/200-mi/configuration.tfvars index 72c3278848..8eea3a3122 100644 --- a/examples/mssql_mi/200-mi/configuration.tfvars +++ b/examples/mssql_mi/200-mi/configuration.tfvars @@ -21,7 +21,7 @@ vnets = { resource_group_key = "networking_region1" vnet = { name = "sqlmi-rg1" - address_space = ["172.25.88.0/21"] + address_space = ["172.25.88.0/21", "10.2.0.0/24"] } subnets = { sqlmi1 = { @@ -39,6 +39,12 @@ vnets = { ] } } + subnet02 = { + name = "subnet02" + cidr = ["10.2.0.0/24"] + nsg_key = "subnet02" + route_table_key = "sqlmi1" + } } } } @@ -71,6 +77,19 @@ mssql_managed_instances = { storageSizeInGB = 32 vCores = 8 + private_endpoints = { + privatelink-sqlmi = { + name = "pe-sqlmi1" + vnet_key = "sqlmi_region1" + subnet_key = "subnet02" + resource_group_key = "sqlmi_region1" + private_service_connection = { + name = "conn-sqlmi1" + is_manual_connection = false + subresource_names = ["managedInstance"] + } + } + } } } diff --git a/examples/mssql_mi/200-mi/nsg.tfvars b/examples/mssql_mi/200-mi/nsg.tfvars index a01fed2440..d5bb2718bb 100644 --- a/examples/mssql_mi/200-mi/nsg.tfvars +++ b/examples/mssql_mi/200-mi/nsg.tfvars @@ -83,4 +83,7 @@ network_security_group_definition = { } ] } + subnet02 = { + nsg = [] + } } diff --git a/examples/mysql_flexible_server/103-mysql-flexible-private-endpoint/configuration.tfvars b/examples/mysql_flexible_server/103-mysql-flexible-private-endpoint/configuration.tfvars new file mode 100644 index 0000000000..f65925a736 --- /dev/null +++ b/examples/mysql_flexible_server/103-mysql-flexible-private-endpoint/configuration.tfvars @@ -0,0 +1,110 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "australiaeast" + } +} + +resource_groups = { + mysql_region1 = { + name = "mysql-region1" + region = "region1" + } + security_region1 = { + name = "security-region1" + } +} + +mysql_flexible_server = { + primary_region1 = { + name = "vks-flexible-testservers" + version = "8.0.21" #Possible values are 5.7, and 8.0.21 + sku_name = "GP_Standard_D2ds_v4" + zone = 1 + resource_group = { + key = "mysql_region1" + # lz_key = "" # Set the lz_key if the resource group is remote. + } + + private_dns_zone_id = "dns_zone1" + + # Auto-generated administrator credentials stored in azure keyvault when not set (recommended). + #administrator_username = "psqladmin" + #administrator_password = "ComplxP@ssw0rd!" + keyvault = { + key = "mysql_region1" # (Required) when auto-generated administrator credentials needed. + # lz_key = "" # Set the lz_key if the keyvault is remote. + } + + # [Optional] Server Configurations + mysql_configurations = { + mysql_configurations = { + name = "interactive_timeout" + value = "600" + } + + } + # [Optional] Database Configurations + mysql_databases = { + flex_mysql_database = { + name = "exampledb" + collation = "utf8mb3_unicode_ci" + charset = "utf8mb3" + } + } + + tags = { + server = "MysqlFlexible" + } + + private_endpoints = { + private-link-level4 = { + name = "sales-sql-rg1" + vnet_key = "vnet_region1" + subnet_key = "private_dns" + resource_group_key = "sql_region1" + + private_service_connection = { + name = "sales-sql-rg1" + is_manual_connection = false + subresource_names = ["mysqlServer"] + } + } + } + + } + +} + +keyvaults = { + mysql_region1 = { + name = "mysql-region123" + resource_group_key = "security_region1" + sku_name = "standard" + soft_delete_enabled = true + creation_policies = { + logged_in_user = { + secret_permissions = ["Set", "Get", "List", "Delete", "Purge"] + } + } + } +} + +vnets = { + vnet_region1 = { + resource_group_key = "mysql_region1" + region = "region1" + vnet = { + name = "mysql" + address_space = ["10.10.0.0/24"] + } + subnets = { + private_dns = { + name = "private-dns" + cidr = ["10.10.0.0/25"] + enforce_private_link_endpoint_network_policies = true + enforce_private_link_service_network_policies = false + } + } + } +} \ No newline at end of file diff --git a/examples/networking/app_gateway/301-agw-v1/agw_application.tfvars b/examples/networking/app_gateway/301-agw-v1/agw_application.tfvars index fbfceda541..538a3d300c 100644 --- a/examples/networking/app_gateway/301-agw-v1/agw_application.tfvars +++ b/examples/networking/app_gateway/301-agw-v1/agw_application.tfvars @@ -16,6 +16,18 @@ application_gateway_applications_v1 = { # key = "" # } } + demo2 = { + name = "demo_pool02" + fqdns = ["babc-app-ptsg-5sspdemoappap2-lo.babc-ase-ase01-pd.appserviceenvironment.net"] + } + demo3 = { + name = "demo_pool03" + fqdns = ["babc-app-ptsg-5sspdemoappap3-lo.babc-ase-ase01-pd.appserviceenvironment.net"] + } + demo4 = { + name = "demo_pool04" + fqdns = ["babc-app-ptsg-5sspdemoappap4-lo.babc-ase-ase01-pd.appserviceenvironment.net"] + } } http_settings = { @@ -83,12 +95,14 @@ application_gateway_applications_v1 = { url_path_maps = { demo = { - name = "test_path_map" - paths = "/test/*" - rule_name = "test_path_rule" - backend_pool_key = "demo" - http_settings_key = "demo" - rewrite_rule_set_key = "rrs1" + name = "test_path_map" + paths = "/test/*" + rule_name = "test_path_rule" + default_backend_pool_key = "demo" + backend_pool_key = "demo" + default_http_settings_key = "demo" + http_settings_key = "demo" + rewrite_rule_set_key = "rrs1" } } @@ -97,14 +111,21 @@ application_gateway_applications_v1 = { name = "rule1-demo" url_path_map_key = "demo" paths = "/test/rule1/*" - backend_pool_key = "demo" + backend_pool_key = "demo2" http_settings_key = "demo" } rule2 = { name = "rule2-demo" url_path_map_key = "demo" paths = "/test/rule2/*" - backend_pool_key = "demo" + backend_pool_key = "demo3" + http_settings_key = "demo" + } + rule3 = { + name = "rule3-demo" + url_path_map_key = "demo" + paths = "/test/rule3/*" + backend_pool_key = "demo4" http_settings_key = "demo" } } diff --git a/examples/networking/private_links/endpoints/100-azure-open-ai-private-endpoint/configuration.tfvars b/examples/networking/private_links/endpoints/100-azure-open-ai-private-endpoint/configuration.tfvars new file mode 100644 index 0000000000..e694349351 --- /dev/null +++ b/examples/networking/private_links/endpoints/100-azure-open-ai-private-endpoint/configuration.tfvars @@ -0,0 +1,76 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "uksouth" + } +} + +resource_groups = { + rg1 = { + name = "example-rg1" + } +} + +cognitive_services_account = { + my_account = { + resource_group = { + key = "rg1" + } + name = "pineconellmdemoopenai1" + kind = "OpenAI" + sku_name = "S0" + custom_subdomain_name = "cs-alz-caf-test-b" + #log_analytics_key = "la1" + } +} + +vnets = { + vnet1 = { + resource_group_key = "rg1" + vnet = { + name = "VNet" + address_space = ["10.0.0.0/16"] + } + specialsubnets = {} + subnets = { + private_endpoints_subnet = { + name = "PrivateEndpoints" + cidr = ["10.0.16.0/24"] + enforce_private_endpoint_network_policies = true + enforce_private_link_endpoint_network_policies = false + } + } + } +} + +private_dns = { + dns1 = { + name = "privatelink.openai.azure.com" + resource_group_key = "rg1" + vnet_links = { + vnet_link_01 = { + name = "vnet_link_01" + vnet_key = "vnet1" + } + } + } +} + +private_endpoints = { + vnet1 = { + vnet_key = "vnet1" + subnet_keys = ["private_endpoints_subnet"] + resource_group_key = "rg1" + cognitive_services_account = { + my_account = { + private_service_connection = { + name = "CognitiveServicesPrivateEndpoint" + } + private_dns = { + zone_group_name = "privatelink.openai.azure.com" + keys = ["dns1"] + } + } + } + } +} \ No newline at end of file diff --git a/examples/networking/virtual_network_gateway/103-vpn-site-to-site-connection/configuration.tfvars b/examples/networking/virtual_network_gateway/103-vpn-site-to-site-connection/configuration.tfvars index a0932a6965..72638fb57a 100644 --- a/examples/networking/virtual_network_gateway/103-vpn-site-to-site-connection/configuration.tfvars +++ b/examples/networking/virtual_network_gateway/103-vpn-site-to-site-connection/configuration.tfvars @@ -78,7 +78,7 @@ virtual_network_gateway_connections = { connection1 = { name = "connection" resource_group_key = "vpngw" - type = "IPSec" + type = "IPsec" region = "region1" virtual_network_gateway_key = "gateway1" local_network_gateway_key = "local1" diff --git a/examples/networking/virtual_wan/106-vwan-hub-routes/virtual_wan.tfvars b/examples/networking/virtual_wan/106-vwan-hub-routes/virtual_wan.tfvars index 2f1b32e29b..cd0789bfcd 100644 --- a/examples/networking/virtual_wan/106-vwan-hub-routes/virtual_wan.tfvars +++ b/examples/networking/virtual_wan/106-vwan-hub-routes/virtual_wan.tfvars @@ -20,14 +20,15 @@ virtual_wans = { hubs = { hub_re1 = { - hub_name = "hub-re1" - region = "region1" - hub_address_prefix = "10.0.3.0/24" - deploy_p2s = false - p2s_config = {} - deploy_s2s = false - s2s_config = {} - deploy_er = false + hub_name = "hub-re1" + region = "region1" + hub_address_prefix = "10.0.3.0/24" + virtual_router_auto_scale_min_capacity = 4 + deploy_p2s = false + p2s_config = {} + deploy_s2s = false + s2s_config = {} + deploy_er = false routes = { route1 = { address_prefixes = ["10.0.5.0/25"] diff --git a/examples/networking/virtual_wan/109-vwan-vpn-gateway-connection/virtual_wan.tfvars b/examples/networking/virtual_wan/109-vwan-vpn-gateway-connection/virtual_wan.tfvars index f10f32afe2..0464a1b3f1 100644 --- a/examples/networking/virtual_wan/109-vwan-vpn-gateway-connection/virtual_wan.tfvars +++ b/examples/networking/virtual_wan/109-vwan-vpn-gateway-connection/virtual_wan.tfvars @@ -43,7 +43,7 @@ virtual_hub_route_tables = { virtual_wan_key = "vwan_re1" virtual_hub_key = "hub_re1" - labels = ["label1"] + labels = ["label1", "default"] } routetable2 = { name = "example-vhubroutetable2" @@ -143,22 +143,26 @@ vpn_gateway_connections = { } routing = { # Optional - associated_route_table = { - # id = "" # Set the Resource ID of an existing Virtual WAN Route Table - # lz_key = "" # Set the 'lz_key' of a Route Table created in a remote deployment - key = "routetable1" # Set the 'key' of the Route Table created in this (or a remote) deployment - } + # associated_route_table = { # Can only be Default Route Table https://learn.microsoft.com/en-us/azure/virtual-wan/about-virtual-hub-routing#considerations + # id = "" # Set the Resource ID of an existing Virtual WAN Route Table + # lz_key = "" # Set the 'lz_key' of a Route Table created in a remote deployment + # key = "routetable1" # Set the 'key' of the Route Table created in this (or a remote) deployment + # } propagated_route_table = { - routetable1 = { - # id = "" # Set the Resource ID of an existing Virtual WAN Route Table - # lz_key = "" # Set the 'lz_key' of a Route Table created in a remote deployment - key = "routetable1" # Set the 'key' of the Route Table created in this (or a remote) deployment - } - routetable2 = { - # id = "" # Set the Resource ID of an existing Virtual WAN Route Table - # lz_key = "" # Set the 'lz_key' of a Route Table created in a remote deployment - key = "routetable2" # Set the 'key' of the Route Table created in this (or a remote) deployment + route_tables = { + routetable1 = { + # id = "" # Set the Resource ID of an existing Virtual WAN Route Table + # lz_key = "" # Set the 'lz_key' of a Route Table created in a remote deployment + key = "routetable1" # Set the 'key' of the Route Table created in this (or a remote) deployment + labels = ["label1"] # Optional + } + routetable2 = { + # id = "" # Set the Resource ID of an existing Virtual WAN Route Table + # lz_key = "" # Set the 'lz_key' of a Route Table created in a remote deployment + key = "routetable2" # Set the 'key' of the Route Table created in this (or a remote) deployment + labels = ["label2", "default"] # Optional + } } } } diff --git a/examples/networking/virtual_wan/110-vwan-hub-gw-p2s-keyvault-cert/virtual_wan.tfvars b/examples/networking/virtual_wan/110-vwan-hub-gw-p2s-keyvault-cert/virtual_wan.tfvars new file mode 100644 index 0000000000..6dea339306 --- /dev/null +++ b/examples/networking/virtual_wan/110-vwan-hub-gw-p2s-keyvault-cert/virtual_wan.tfvars @@ -0,0 +1,98 @@ +global_settings = { + default_region = "region1" + regions = { + region1 = "australiaeast" + } +} + +provider_azurerm_features_keyvault = { + // set to true to cleanup the CI + purge_soft_delete_on_destroy = true +} + +resource_groups = { + hub_re1 = { + name = "vnet-hub-re1" + region = "region1" + } +} + +keyvaults = { + vwan-kv = { + name = "vwan-kv" + resource_group_key = "hub_re1" + sku_name = "standard" + creation_policies = { + logged_in_user = { + secret_permissions = ["Set", "Get", "List", "Delete", "Purge"] + } + } + secrets = { + ca_cert = { + name = "ca-cert" + value = < value + if try(value.id, null) == null + } +} diff --git a/modules/billing/invoice_sections/main.tf b/modules/billing/invoice_sections/main.tf new file mode 100644 index 0000000000..4b5407c44a --- /dev/null +++ b/modules/billing/invoice_sections/main.tf @@ -0,0 +1,18 @@ +locals { + tags = var.base_tags ? merge( + var.global_settings.tags, + try(var.settings.tags, null) + ) : try(var.settings.tags, null) +} + +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + azapi = { + source = "azure/azapi" + version = "~> 1.6.0" + } + } +} diff --git a/modules/billing/invoice_sections/module.tf b/modules/billing/invoice_sections/module.tf new file mode 100644 index 0000000000..0a49d498df --- /dev/null +++ b/modules/billing/invoice_sections/module.tf @@ -0,0 +1,29 @@ +resource "azapi_resource" "invoice_section" { + type = "Microsoft.Billing/billingAccounts/billingProfiles/invoiceSections@2020-05-01" + name = var.settings.name + parent_id = format("/providers/Microsoft.Billing/billingAccounts/%s/billingProfiles/%s", var.settings.billing_account_id, var.settings.billing_profile_id) + response_export_values = ["properties.displayName"] + body = jsonencode({ + properties = { + displayName = var.settings.name + labels = try(var.settings.labels, null) + tags = local.tags + } + }) +} + +output "id" { + value = azapi_resource.invoice_section.id +} +output "name" { + value = var.settings.name +} +output "display_name" { + value = jsondecode(azapi_resource.invoice_section.output).properties.displayName +} +output "billing_account_id" { + value = var.settings.billing_account_id +} +output "billing_profile_id" { + value = var.settings.billing_profile_id +} diff --git a/modules/billing/invoice_sections/variables.tf b/modules/billing/invoice_sections/variables.tf new file mode 100644 index 0000000000..e3f1e1db50 --- /dev/null +++ b/modules/billing/invoice_sections/variables.tf @@ -0,0 +1,13 @@ +variable "global_settings" { + description = "Global settings object (see module README.md)" +} +variable "client_config" { + description = "Client configuration object (see module README.md)." +} + +variable "settings" {} + +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} \ No newline at end of file diff --git a/modules/cognitive_services/cognitive_services_account/cognitive_service_account.tf b/modules/cognitive_services/cognitive_services_account/cognitive_service_account.tf index c61ddf1707..2f3a24ff40 100644 --- a/modules/cognitive_services/cognitive_services_account/cognitive_service_account.tf +++ b/modules/cognitive_services/cognitive_services_account/cognitive_service_account.tf @@ -9,13 +9,23 @@ resource "azurecaf_name" "service" { } resource "azurerm_cognitive_account" "service" { - name = azurecaf_name.service.result - location = var.location - resource_group_name = var.resource_group_name - kind = var.settings.kind - sku_name = var.settings.sku_name - - qna_runtime_endpoint = var.settings.kind == "QnAMaker" ? var.settings.qna_runtime_endpoint : try(var.settings.qna_runtime_endpoint, null) + name = azurecaf_name.service.result + location = var.location + resource_group_name = var.resource_group_name + kind = var.settings.kind + sku_name = var.settings.sku_name + public_network_access_enabled = try(var.settings.public_network_access_enabled, true) + custom_subdomain_name = try(var.settings.custom_subdomain_name, null) + tags = merge(local.tags, try(var.settings.tags, null)) + qna_runtime_endpoint = var.settings.kind == "QnAMaker" ? var.settings.qna_runtime_endpoint : try(var.settings.qna_runtime_endpoint, null) + + dynamic "identity" { + for_each = lookup(var.settings, "identity", {}) != {} ? [1] : [] + content { + type = lookup(var.settings.identity, "type", null) + identity_ids = can(var.settings.identity.ids) ? var.settings.identity.ids : can(var.settings.identity.key) ? [var.managed_identities[try(var.settings.identity.lz_key, var.client_config.landingzone_key)][var.settings.identity.key].id] : null + } + } dynamic "network_acls" { for_each = can(var.settings.network_acls) ? [var.settings.network_acls] : [] @@ -42,8 +52,4 @@ resource "azurerm_cognitive_account" "service" { } } } - - custom_subdomain_name = try(var.settings.custom_subdomain_name, null) - - tags = try(var.settings.tags, {}) } \ No newline at end of file diff --git a/modules/cognitive_services/cognitive_services_account/diagnostics.tf b/modules/cognitive_services/cognitive_services_account/diagnostics.tf new file mode 100644 index 0000000000..3d7118951f --- /dev/null +++ b/modules/cognitive_services/cognitive_services_account/diagnostics.tf @@ -0,0 +1,9 @@ +module "diagnostics" { + source = "../../diagnostics" + count = var.diagnostic_profiles == null ? 0 : 1 + + resource_id = azurerm_cognitive_account.service.id + resource_location = local.location + diagnostics = var.diagnostics + profiles = var.diagnostic_profiles +} diff --git a/modules/cognitive_services/cognitive_services_account/main.tf b/modules/cognitive_services/cognitive_services_account/main.tf index b34ed51903..e2fd2ccc7f 100644 --- a/modules/cognitive_services/cognitive_services_account/main.tf +++ b/modules/cognitive_services/cognitive_services_account/main.tf @@ -4,4 +4,13 @@ terraform { source = "aztfmod/azurecaf" } } -} \ No newline at end of file +} + +locals { + location = coalesce(var.location, var.resource_group.location) + tags = var.base_tags ? merge( + var.global_settings.tags, + try(var.resource_group.tags, null), + try(var.settings.tags, null) + ) : try(var.settings.tags, null) +} diff --git a/modules/cognitive_services/cognitive_services_account/output.tf b/modules/cognitive_services/cognitive_services_account/output.tf index fd2a6239a4..c548874b0b 100644 --- a/modules/cognitive_services/cognitive_services_account/output.tf +++ b/modules/cognitive_services/cognitive_services_account/output.tf @@ -6,4 +6,23 @@ output "id" { output "endpoint" { description = "The endpoint used to connect to the Cognitive Service Account." value = azurerm_cognitive_account.service.endpoint -} \ No newline at end of file +} + +output "primary_access_key" { + description = "The primary_access_key used to connect to the Cognitive Service Account." + value = azurerm_cognitive_account.service.primary_access_key +} + +output "secondary_access_key" { + description = "The secondary_access_key used to connect to the Cognitive Service Account." + value = azurerm_cognitive_account.service.secondary_access_key +} + +output "rbac_id" { + description = "The Principal ID of the Cognetive Services for Role Mapping" + value = try(azurerm_cognitive_account.service.identity[0].principal_id, null) +} + +output "identity" { + value = try(azurerm_cognitive_account.service.identity, null) +} diff --git a/modules/cognitive_services/cognitive_services_account/private_endpoints.tf b/modules/cognitive_services/cognitive_services_account/private_endpoints.tf new file mode 100644 index 0000000000..9c34adb305 --- /dev/null +++ b/modules/cognitive_services/cognitive_services_account/private_endpoints.tf @@ -0,0 +1,20 @@ +# +# Private endpoint +# + +module "private_endpoint" { + source = "../../networking/private_endpoint" + for_each = var.private_endpoints + + resource_id = azurerm_cognitive_account.service.id + name = each.value.name + location = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location + resource_group_name = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + settings = each.value + global_settings = var.global_settings + base_tags = var.base_tags + tags = local.tags + private_dns = var.private_dns + client_config = var.client_config +} diff --git a/modules/cognitive_services/cognitive_services_account/variables.tf b/modules/cognitive_services/cognitive_services_account/variables.tf index 6a1d64e03b..87b5679e0d 100644 --- a/modules/cognitive_services/cognitive_services_account/variables.tf +++ b/modules/cognitive_services/cognitive_services_account/variables.tf @@ -9,10 +9,39 @@ variable "location" { type = string } +variable "resource_group" { + description = "Resource group object to deploy the resource" +} + variable "resource_group_name" { - description = "Name of the existing resource group to deploy the virtual machine" + description = "Name of the existing resource group to deploy the resource" type = string } +variable "diagnostic_profiles" { + default = {} +} +variable "diagnostics" { + default = {} +} + variable "settings" {} +variable "managed_identities" { + default = {} +} + +variable "vnets" {} + +variable "resource_groups" {} + +variable "private_endpoints" {} + +variable "private_dns" { + default = {} +} + +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} diff --git a/modules/compute/aks/aks.tf b/modules/compute/aks/aks.tf index 7e9b487e4a..1ec9d71196 100644 --- a/modules/compute/aks/aks.tf +++ b/modules/compute/aks/aks.tf @@ -63,13 +63,13 @@ resource "azurerm_kubernetes_cluster" "aks" { os_disk_type = try(var.settings.default_node_pool.os_disk_type, null) os_sku = try(var.settings.default_node_pool.os_sku, null) tags = merge(try(var.settings.default_node_pool.tags, {}), local.tags) + temporary_name_for_rotation = try(var.settings.default_node_pool.temporary_name_for_rotation, null) type = try(var.settings.default_node_pool.type, "VirtualMachineScaleSets") ultra_ssd_enabled = try(var.settings.default_node_pool.ultra_ssd_enabled, false) vm_size = var.settings.default_node_pool.vm_size capacity_reservation_group_id = try(var.settings.capacity_reservation_group_id, null) custom_ca_trust_enabled = try(var.settings.custom_ca_trust_enabled, null) host_group_id = try(var.settings.host_group_id, null) - temporary_name_for_rotation = try(var.settings.default_node_pool.temporary_name_for_rotation, null) pod_subnet_id = can(var.settings.default_node_pool.pod_subnet_key) == false || can(var.settings.default_node_pool.pod_subnet.key) == false || can(var.settings.default_node_pool.pod_subnet_id) || can(var.settings.default_node_pool.pod_subnet.resource_id) ? try(var.settings.default_node_pool.pod_subnet_id, var.settings.default_node_pool.pod_subnet.resource_id, null) : var.vnets[try(var.settings.lz_key, var.client_config.landingzone_key)][var.settings.vnet_key].subnets[try(var.settings.default_node_pool.pod_subnet_key, var.settings.default_node_pool.pod_subnet.key)].id vnet_subnet_id = can(var.settings.default_node_pool.vnet_subnet_id) || can(var.settings.default_node_pool.subnet.resource_id) ? try(var.settings.default_node_pool.vnet_subnet_id, var.settings.default_node_pool.subnet.resource_id) : var.vnets[try(var.settings.vnet.lz_key, var.settings.lz_key, var.client_config.landingzone_key)][try(var.settings.vnet.key, var.settings.vnet_key)].subnets[try(var.settings.default_node_pool.subnet_key, var.settings.default_node_pool.subnet.key)].id @@ -161,7 +161,7 @@ resource "azurerm_kubernetes_cluster" "aks" { subnet_name = aci_connector_linux.value.subnet_name } } - + cost_analysis_enabled = try(var.settings.cost_analysis_enabled, null) azure_policy_enabled = can(var.settings.addon_profile.azure_policy) || can(var.settings.azure_policy_enabled) == false ? try(var.settings.addon_profile.azure_policy.0.enabled, null) : var.settings.azure_policy_enabled http_application_routing_enabled = can(var.settings.addon_profile.http_application_routing) || can(var.settings.http_application_routing_enabled) == false ? try(var.settings.addon_profile.http_application_routing.0.enabled, null) : var.settings.http_application_routing_enabled @@ -169,7 +169,7 @@ resource "azurerm_kubernetes_cluster" "aks" { for_each = try(var.settings.addon_profile.oms_agent[*], var.settings.oms_agent[*], {}) content { - log_analytics_workspace_id = can(oms_agent.value.log_analytics_workspace_id) ? oms_agent.value.log_analytics_workspace_id : var.diagnostics.log_analytics[oms_agent.value.log_analytics_key].id + log_analytics_workspace_id = can(oms_agent.value.log_analytics_workspace_id) ? oms_agent.value.log_analytics_workspace_id : var.diagnostics.log_analytics[oms_agent.value.log_analytics_key].id msi_auth_for_monitoring_enabled = try(oms_agent.value.msi_auth_for_monitoring_enabled, null) } } @@ -350,8 +350,18 @@ resource "azurerm_kubernetes_cluster" "aks" { } } + dynamic "service_mesh_profile" { + for_each = try(var.settings.service_mesh_profile[*], {}) + content { + mode = try(service_mesh_profile.value.mode, null) + internal_ingress_gateway_enabled = try(service_mesh_profile.value.internal_ingress_gateway_enabled, null) + external_ingress_gateway_enabled = try(service_mesh_profile.value.external_ingress_gateway_enabled, null) + } + } + node_resource_group = azurecaf_name.rg_node.result oidc_issuer_enabled = try(var.settings.oidc_issuer_enabled, null) + open_service_mesh_enabled = try(var.settings.open_service_mesh_enabled, null) private_cluster_enabled = try(var.settings.private_cluster_enabled, null) private_dns_zone_id = try(var.private_dns_zone_id, null) private_cluster_public_fqdn_enabled = try(var.settings.private_cluster_public_fqdn_enabled, null) diff --git a/modules/compute/container_app/container_app.tf b/modules/compute/container_app/container_app.tf new file mode 100644 index 0000000000..f94b29fc68 --- /dev/null +++ b/modules/compute/container_app/container_app.tf @@ -0,0 +1,280 @@ +resource "azurecaf_name" "ca" { + name = var.settings.name + prefixes = var.global_settings.prefixes + resource_type = "azurerm_container_app" + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} + +resource "azurerm_container_app" "ca" { + name = azurecaf_name.ca.result + resource_group_name = local.resource_group_name + container_app_environment_id = var.container_app_environment_id + revision_mode = var.settings.revision_mode + tags = merge(local.tags, try(var.settings.tags, null)) + + template { + dynamic "container" { + for_each = var.settings.template.container + + content { + name = container.value.name + image = container.value.image + args = try(container.value.args, null) + command = try(container.value.command, null) + cpu = container.value.cpu + memory = container.value.memory + + dynamic "env" { + for_each = try(container.value.env, {}) + + content { + name = env.value.name + secret_name = try(env.value.secret_name, null) + value = try(env.value.value, null) + } + } + + dynamic "liveness_probe" { + for_each = can(container.value.liveness_probe) ? [container.value.liveness_probe] : [] + + content { + failure_count_threshold = try(liveness_probe.value.failure_count_threshold, null) + host = try(liveness_probe.value.host, null) + initial_delay = try(liveness_probe.value.initial_delay, null) + interval_seconds = try(liveness_probe.value.interval_seconds, null) + path = try(liveness_probe.value.path, null) + port = liveness_probe.value.port + termination_grace_period_seconds = try(liveness_probe.value.termination_grace_period_seconds, null) + timeout = try(liveness_probe.value.timeout, null) + transport = liveness_probe.value.transport + + dynamic "header" { + for_each = can(liveness_probe.value.header) ? [liveness_probe.value.header] : [] + + content { + name = header.value.name + value = header.value.value + } + } + } + } + + dynamic "readiness_probe" { + for_each = can(container.value.readiness_probe) ? [container.value.readiness_probe] : [] + + content { + failure_count_threshold = try(readiness_probe.value.failure_count_threshold, null) + host = try(readiness_probe.value.host, null) + interval_seconds = try(readiness_probe.value.interval_seconds, null) + path = try(readiness_probe.value.path, null) + port = readiness_probe.value.port + success_count_threshold = try(readiness_probe.value.success_count_threshold, null) + timeout = try(readiness_probe.value.timeout, null) + transport = readiness_probe.value.transport + + dynamic "header" { + for_each = can(readiness_probe.value.header) ? [readiness_probe.value.header] : [] + + content { + name = header.value.name + value = header.value.value + } + } + } + } + + dynamic "startup_probe" { + for_each = can(container.value.startup_probe) ? [container.value.startup_probe] : [] + + content { + failure_count_threshold = try(startup_probe.value.failure_count_threshold, null) + host = try(startup_probe.value.host, null) + interval_seconds = try(startup_probe.value.interval_seconds, null) + path = try(startup_probe.value.path, null) + port = startup_probe.value.port + termination_grace_period_seconds = try(startup_probe.value.termination_grace_period_seconds, null) + timeout = try(startup_probe.value.timeout, null) + transport = startup_probe.value.transport + + dynamic "header" { + for_each = can(startup_probe.value.header) ? [startup_probe.value.header] : [] + + content { + name = header.value.name + value = header.value.value + } + } + } + } + + dynamic "volume_mounts" { + for_each = try(container.value.volume_mounts, {}) + + content { + name = volume_mounts.value.name + path = volume_mounts.value.path + } + } + } + } + + dynamic "azure_queue_scale_rule" { + for_each = try(var.settings.template.azure_queue_scale_rule, {}) + content { + name = azure_queue_scale_rule.value.name + queue_name = azure_queue_scale_rule.value.queue_name + queue_length = azure_queue_scale_rule.value.queue_length + + dynamic "authentication" { + for_each = azure_queue_scale_rule.value.authentication + + content { + secret_name = authentication.value.secret_name + trigger_parameter = authentication.value.trigger_parameter + } + } + } + } + + dynamic "custom_scale_rule" { + for_each = try(var.settings.template.custom_scale_rule, {}) + content { + name = custom_scale_rule.value.name + custom_rule_type = custom_scale_rule.value.custom_rule_type + metadata = custom_scale_rule.value.metadata + + dynamic "authentication" { + for_each = try(custom_scale_rule.value.authentication, {}) + + content { + secret_name = authentication.value.secret_name + trigger_parameter = authentication.value.trigger_parameter + } + } + } + } + + dynamic "http_scale_rule" { + for_each = try(var.settings.template.http_scale_rule, {}) + content { + name = http_scale_rule.value.name + concurrent_requests = http_scale_rule.value.concurrent_requests + + dynamic "authentication" { + for_each = try(http_scale_rule.value.authentication, {}) + + content { + secret_name = authentication.value.secret_name + trigger_parameter = authentication.value.trigger_parameter + } + } + } + } + + dynamic "tcp_scale_rule" { + for_each = try(var.settings.template.tcp_scale_rule, {}) + content { + name = tcp_scale_rule.value.name + concurrent_requests = tcp_scale_rule.value.concurrent_requests + + dynamic "authentication" { + for_each = try(tcp_scale_rule.value.authentication, {}) + + content { + secret_name = authentication.value.secret_name + trigger_parameter = authentication.value.trigger_parameter + } + } + } + } + + min_replicas = try(var.settings.template.min_replicas, null) + max_replicas = try(var.settings.template.max_replicas, null) + revision_suffix = try(var.settings.template.revision_suffix, null) + + dynamic "volume" { + for_each = try(var.settings.template.volume, {}) + + content { + name = volume.value.name + storage_name = try(volume.value.storage_name, null) + storage_type = try(volume.value.storage_type, null) + } + } + } + + dynamic "ingress" { + for_each = can(var.settings.ingress) ? [var.settings.ingress] : [] + + content { + allow_insecure_connections = try(ingress.value.allow_insecure_connections, null) + external_enabled = try(ingress.value.external_enabled, null) + fqdn = try(ingress.value.fqdn, null) + target_port = ingress.value.target_port + transport = ingress.value.transport + + dynamic "custom_domain" { + for_each = try(ingress.value.custom_domain, {}) + + content { + certificate_binding_type = try(custom_domain.value.certificate_binding_type, null) + certificate_id = can(custom_domain.value.certificate_id) ? custom_domain.value.certificate_id : var.combined_resources.container_app_environment_certificates[try(custom_domain.value.lz_key, var.client_config.landingzone_key)][custom_domain.value.certificate_key].id + name = custom_domain.value.name + } + } + + dynamic "traffic_weight" { + for_each = try(ingress.value.traffic_weight, {}) + + content { + label = traffic_weight.value.label + latest_revision = traffic_weight.value.latest_revision + revision_suffix = traffic_weight.value.revision_suffix + percentage = traffic_weight.value.percentage + } + } + } + } + + dynamic "dapr" { + for_each = can(var.settings.dapr) ? [var.settings.dapr] : [] + + content { + app_id = dapr.value.app_id + app_port = try(dapr.value.app_port, null) + app_protocol = try(dapr.value.app_protocol, null) + } + } + + dynamic "secret" { + for_each = try(var.settings.secret, {}) + + content { + name = secret.value.name + value = secret.value.value + } + } + + dynamic "identity" { + for_each = can(var.settings.identity) ? [var.settings.identity] : [] + + content { + type = var.settings.identity.type + identity_ids = local.managed_identities + } + } + + dynamic "registry" { + for_each = can(var.settings.registry) ? [var.settings.registry] : [] + + content { + server = registry.value.server + identity = can(registry.value.identity.key) ? var.combined_resources.managed_identities[try(registry.value.identity.lz_key, var.client_config.landingzone_key)][registry.value.identity.key].id : try(registry.value.identity.id, null) + username = try(registry.value.username, null) + password_secret_name = try(registry.value.password_secret_name, null) + } + } +} diff --git a/modules/compute/container_app/locals.tf b/modules/compute/container_app/locals.tf new file mode 100644 index 0000000000..4daa5a1ebd --- /dev/null +++ b/modules/compute/container_app/locals.tf @@ -0,0 +1,17 @@ +locals { + managed_local_identities = flatten([ + for managed_identity_key in try(var.settings.identity.managed_identity_keys, []) : [ + var.combined_resources.managed_identities[var.client_config.landingzone_key][managed_identity_key].id + ] + ]) + + managed_remote_identities = flatten([ + for lz_key, value in try(var.settings.identity.remote, []) : [ + for managed_identity_key in value.managed_identity_keys : [ + var.combined_resources.managed_identities[lz_key][managed_identity_key].id + ] + ] + ]) + + managed_identities = concat(local.managed_local_identities, local.managed_remote_identities) +} diff --git a/modules/compute/container_app/main.tf b/modules/compute/container_app/main.tf new file mode 100644 index 0000000000..e886ec6c93 --- /dev/null +++ b/modules/compute/container_app/main.tf @@ -0,0 +1,26 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} + +locals { + module_tag = { + "module" = basename(abspath(path.module)) + } + tags = var.base_tags ? merge( + var.global_settings.tags, + try(var.resource_group.tags, null), + local.module_tag, + try(var.settings.tags, null) + ) : merge( + local.module_tag, + try(var.settings.tags, + null) + ) + + location = coalesce(var.location, var.resource_group.location) + resource_group_name = coalesce(var.resource_group_name, var.resource_group.name) +} diff --git a/modules/compute/container_app/output.tf b/modules/compute/container_app/output.tf new file mode 100644 index 0000000000..fcd3430f8b --- /dev/null +++ b/modules/compute/container_app/output.tf @@ -0,0 +1,15 @@ +output "id" { + value = azurerm_container_app.ca.id +} +output "custom_domain_verification_id" { + value = azurerm_container_app.ca.custom_domain_verification_id +} +output "latest_revision_fqdn" { + value = azurerm_container_app.ca.latest_revision_fqdn +} +output "latest_revision_name" { + value = azurerm_container_app.ca.latest_revision_name +} +output "outbound_ip_addresses" { + value = azurerm_container_app.ca.outbound_ip_addresses +} diff --git a/modules/compute/container_app/variables.tf b/modules/compute/container_app/variables.tf new file mode 100644 index 0000000000..11e4f28fa9 --- /dev/null +++ b/modules/compute/container_app/variables.tf @@ -0,0 +1,20 @@ +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} +variable "client_config" {} +variable "diagnostics" {} +variable "diagnostic_profiles" {} +variable "combined_diagnostics" {} +variable "combined_resources" { + description = "Provide a map of combined resources for environment_variables_from_resources" + default = {} +} +variable "global_settings" {} +variable "location" {} +variable "resource_group_name" {} +variable "resource_group" { + description = "Resource group object to deploy the virtual machine" +} +variable "settings" {} +variable "container_app_environment_id" {} diff --git a/modules/compute/container_app_dapr_component/container_app_dapr_component.tf b/modules/compute/container_app_dapr_component/container_app_dapr_component.tf new file mode 100644 index 0000000000..c3f47aef36 --- /dev/null +++ b/modules/compute/container_app_dapr_component/container_app_dapr_component.tf @@ -0,0 +1,28 @@ +resource "azurerm_container_app_environment_dapr_component" "cadc" { + name = var.settings.name + container_app_environment_id = var.container_app_environment_id + component_type = var.settings.component_type + version = var.settings.version + ignore_errors = try(var.settings.ignore_errors, false) + init_timeout = try(var.settings.init_timeout, null) + scopes = try(var.settings.scopes, null) + + dynamic "metadata" { + for_each = try(var.settings.metadata, {}) + + content { + name = metadata.value.name + secret_name = try(metadata.value.secret_name, null) + value = try(metadata.value.value, null) + } + } + + dynamic "secret" { + for_each = try(var.settings.secret, {}) + + content { + name = secret.value.name + value = secret.value.value + } + } +} diff --git a/modules/compute/container_app_dapr_component/main.tf b/modules/compute/container_app_dapr_component/main.tf new file mode 100644 index 0000000000..1fbfa06797 --- /dev/null +++ b/modules/compute/container_app_dapr_component/main.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} diff --git a/modules/compute/container_app_dapr_component/output.tf b/modules/compute/container_app_dapr_component/output.tf new file mode 100644 index 0000000000..3669022961 --- /dev/null +++ b/modules/compute/container_app_dapr_component/output.tf @@ -0,0 +1,3 @@ +output "id" { + value = azurerm_container_app_environment_dapr_component.cadc.id +} diff --git a/modules/compute/container_app_dapr_component/variables.tf b/modules/compute/container_app_dapr_component/variables.tf new file mode 100644 index 0000000000..a316af1bdc --- /dev/null +++ b/modules/compute/container_app_dapr_component/variables.tf @@ -0,0 +1,8 @@ +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} +variable "client_config" {} +variable "global_settings" {} +variable "settings" {} +variable "container_app_environment_id" {} diff --git a/modules/compute/container_app_environment/container_app_environment.tf b/modules/compute/container_app_environment/container_app_environment.tf new file mode 100644 index 0000000000..ab6517ba28 --- /dev/null +++ b/modules/compute/container_app_environment/container_app_environment.tf @@ -0,0 +1,21 @@ +resource "azurecaf_name" "cae" { + name = var.settings.name + resource_type = "azurerm_container_app_environment" + prefixes = var.global_settings.prefixes + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} + +resource "azurerm_container_app_environment" "cae" { + name = azurecaf_name.cae.result + location = local.location + resource_group_name = local.resource_group_name + log_analytics_workspace_id = can(var.settings.log_analytics_workspace_id) ? var.settings.log_analytics_workspace_id : var.diagnostics.log_analytics[var.settings.log_analytics_key].id + dapr_application_insights_connection_string = try(var.settings.dapr_application_insights_connection_string, null) + infrastructure_subnet_id = try(var.subnet_id, null) + internal_load_balancer_enabled = try(var.settings.internal_load_balancer_enabled, null) + zone_redundancy_enabled = try(var.settings.zone_redundancy_enabled, null) + tags = merge(local.tags, try(var.settings.tags, null)) +} diff --git a/modules/compute/container_app_environment/main.tf b/modules/compute/container_app_environment/main.tf new file mode 100644 index 0000000000..e886ec6c93 --- /dev/null +++ b/modules/compute/container_app_environment/main.tf @@ -0,0 +1,26 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} + +locals { + module_tag = { + "module" = basename(abspath(path.module)) + } + tags = var.base_tags ? merge( + var.global_settings.tags, + try(var.resource_group.tags, null), + local.module_tag, + try(var.settings.tags, null) + ) : merge( + local.module_tag, + try(var.settings.tags, + null) + ) + + location = coalesce(var.location, var.resource_group.location) + resource_group_name = coalesce(var.resource_group_name, var.resource_group.name) +} diff --git a/modules/compute/container_app_environment/output.tf b/modules/compute/container_app_environment/output.tf new file mode 100644 index 0000000000..c20e15e443 --- /dev/null +++ b/modules/compute/container_app_environment/output.tf @@ -0,0 +1,23 @@ +output "id" { + value = azurerm_container_app_environment.cae.id +} + +output "default_domain" { + value = azurerm_container_app_environment.cae.default_domain +} + +output "docker_bridge_cidr" { + value = try(var.settings.infrastructure_subnet_id, null) != null ? azurerm_container_app_environment.cae.docker_bridge_cidr : null +} + +output "platform_reserved_cidr" { + value = try(var.settings.infrastructure_subnet_id, null) != null ? azurerm_container_app_environment.cae.platform_reserved_cidr : null +} + +output "platform_reserved_dns_ip_address" { + value = try(var.settings.infrastructure_subnet_id, null) != null ? azurerm_container_app_environment.cae.platform_reserved_dns_ip_address : null +} + +output "static_ip_address" { + value = try(var.settings.internal_load_balancer_enabled, false) == true ? azurerm_container_app_environment.cae.static_ip_address : null +} diff --git a/modules/compute/container_app_environment/variables.tf b/modules/compute/container_app_environment/variables.tf new file mode 100644 index 0000000000..5ceb7e3873 --- /dev/null +++ b/modules/compute/container_app_environment/variables.tf @@ -0,0 +1,20 @@ +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} +variable "client_config" {} +variable "diagnostics" {} +variable "diagnostic_profiles" {} +variable "combined_diagnostics" {} +variable "combined_resources" { + description = "Provide a map of combined resources for environment_variables_from_resources" + default = {} +} +variable "global_settings" {} +variable "location" {} +variable "resource_group_name" {} +variable "resource_group" { + description = "Resource group object to deploy the virtual machine" +} +variable "settings" {} +variable "subnet_id" {} diff --git a/modules/compute/container_app_environment_certificate/container_app_environment_certificate.tf b/modules/compute/container_app_environment_certificate/container_app_environment_certificate.tf new file mode 100644 index 0000000000..10d5fe0777 --- /dev/null +++ b/modules/compute/container_app_environment_certificate/container_app_environment_certificate.tf @@ -0,0 +1,7 @@ +resource "azurerm_container_app_environment_certificate" "caec" { + name = var.settings.name + container_app_environment_id = var.container_app_environment_id + certificate_blob_base64 = var.settings.certificate_blob_base64 + certificate_password = var.settings.certificate_password + tags = merge(local.tags, try(var.settings.tags, null)) +} diff --git a/modules/compute/container_app_environment_certificate/main.tf b/modules/compute/container_app_environment_certificate/main.tf new file mode 100644 index 0000000000..40fc6fa25f --- /dev/null +++ b/modules/compute/container_app_environment_certificate/main.tf @@ -0,0 +1,22 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} + +locals { + module_tag = { + "module" = basename(abspath(path.module)) + } + tags = var.base_tags ? merge( + var.global_settings.tags, + local.module_tag, + try(var.settings.tags, null) + ) : merge( + local.module_tag, + try(var.settings.tags, + null) + ) +} diff --git a/modules/compute/container_app_environment_certificate/output.tf b/modules/compute/container_app_environment_certificate/output.tf new file mode 100644 index 0000000000..4820a27b2f --- /dev/null +++ b/modules/compute/container_app_environment_certificate/output.tf @@ -0,0 +1,15 @@ +output "id" { + value = azurerm_container_app_environment_certificate.caec.id +} +output "expiration_date" { + value = azurerm_container_app_environment_certificate.caec.expiration_date +} +output "issue_date" { + value = azurerm_container_app_environment_certificate.caec.issue_date +} +output "issuer" { + value = azurerm_container_app_environment_certificate.caec.issuer +} +output "subject_name" { + value = azurerm_container_app_environment_certificate.caec.subject_name +} diff --git a/modules/compute/container_app_environment_certificate/variables.tf b/modules/compute/container_app_environment_certificate/variables.tf new file mode 100644 index 0000000000..a316af1bdc --- /dev/null +++ b/modules/compute/container_app_environment_certificate/variables.tf @@ -0,0 +1,8 @@ +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} +variable "client_config" {} +variable "global_settings" {} +variable "settings" {} +variable "container_app_environment_id" {} diff --git a/modules/compute/container_app_environment_storage/container_app_environment_storage.tf b/modules/compute/container_app_environment_storage/container_app_environment_storage.tf new file mode 100644 index 0000000000..b7e0ee7fb6 --- /dev/null +++ b/modules/compute/container_app_environment_storage/container_app_environment_storage.tf @@ -0,0 +1,8 @@ +resource "azurerm_container_app_environment_storage" "caes" { + name = var.settings.name + container_app_environment_id = var.container_app_environment_id + account_name = can(var.settings.account_name) ? var.settings.account_name : var.combined_resources.storage_accounts[try(var.settings.storage_account.lz_key, var.client_config.landingzone_key)][var.settings.storage_account.account_key].name + share_name = var.settings.share_name + access_key = can(var.settings.access_key) ? var.settings.access_key : var.combined_resources.storage_accounts[try(var.settings.storage_account.lz_key, var.client_config.landingzone_key)][var.settings.storage_account.account_key].primary_access_key + access_mode = var.settings.access_mode +} diff --git a/modules/compute/container_app_environment_storage/main.tf b/modules/compute/container_app_environment_storage/main.tf new file mode 100644 index 0000000000..1fbfa06797 --- /dev/null +++ b/modules/compute/container_app_environment_storage/main.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} diff --git a/modules/compute/container_app_environment_storage/output.tf b/modules/compute/container_app_environment_storage/output.tf new file mode 100644 index 0000000000..874f0c1fad --- /dev/null +++ b/modules/compute/container_app_environment_storage/output.tf @@ -0,0 +1,3 @@ +output "id" { + value = azurerm_container_app_environment_storage.caes.id +} diff --git a/modules/compute/container_app_environment_storage/variables.tf b/modules/compute/container_app_environment_storage/variables.tf new file mode 100644 index 0000000000..05b84bd7b7 --- /dev/null +++ b/modules/compute/container_app_environment_storage/variables.tf @@ -0,0 +1,16 @@ +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} +variable "client_config" {} +variable "global_settings" {} +variable "combined_resources" { + description = "Provide a map of combined resources for environment_variables_from_resources" + default = {} +} +variable "remote_objects" { + description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created." + default = {} +} +variable "settings" {} +variable "container_app_environment_id" {} diff --git a/modules/compute/container_registry/variables.tf b/modules/compute/container_registry/variables.tf index 03831e82b3..d4ba0209c0 100644 --- a/modules/compute/container_registry/variables.tf +++ b/modules/compute/container_registry/variables.tf @@ -68,18 +68,14 @@ variable "base_tags" { type = bool description = "Base tags for the resource to be inherited from the resource group." } - variable "resource_group" { - description = "Resource group object to deploy the virtual machine" default = null - + description = "Resource group object to deploy the virtual machine" } variable "resource_group_name" { } - - variable "location" { default = null description = "location of the resource if different from the resource group." -} +} \ No newline at end of file diff --git a/modules/compute/virtual_machine/dynamic_custom_data.tf b/modules/compute/virtual_machine/dynamic_custom_data.tf index c47299c4ee..2b2623b53e 100644 --- a/modules/compute/virtual_machine/dynamic_custom_data.tf +++ b/modules/compute/virtual_machine/dynamic_custom_data.tf @@ -1,6 +1,6 @@ data "azurerm_key_vault_secret" "custom_data" { - for_each = local.os_type == "linux" ? try({for k,v in local.dynamic_custom_data_to_process["keyvaults"]: k => v }, {}) : {} + for_each = local.os_type == "linux" ? try({ for k, v in local.dynamic_custom_data_to_process["keyvaults"] : k => v }, {}) : {} key_vault_id = var.keyvaults[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.keyvault_key].id name = each.value.name @@ -8,7 +8,7 @@ data "azurerm_key_vault_secret" "custom_data" { } data "azurerm_key_vault_key" "custom_data" { - for_each = local.os_type == "linux" ? try({for k,v in local.dynamic_custom_data_to_process["keyvault_keys"]: k =>v }, {}) : {} + for_each = local.os_type == "linux" ? try({ for k, v in local.dynamic_custom_data_to_process["keyvault_keys"] : k => v }, {}) : {} key_vault_id = var.keyvaults[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.keyvault_key].id name = each.value.name @@ -17,7 +17,7 @@ data "azurerm_key_vault_key" "custom_data" { } data "azurerm_key_vault_certificate" "custom_data" { - for_each = local.os_type == "linux" ? try({for k,v in local.dynamic_custom_data_to_process["keyvault_certificates"]: k => v }, {}) : {} + for_each = local.os_type == "linux" ? try({ for k, v in local.dynamic_custom_data_to_process["keyvault_certificates"] : k => v }, {}) : {} key_vault_id = var.keyvaults[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.keyvault_key].id name = each.value.name @@ -25,7 +25,7 @@ data "azurerm_key_vault_certificate" "custom_data" { } locals { - + palo_alto_connection_string = { for item in var.settings.virtual_machine_settings : item.name => base64encode("storage-account=${var.storage_accounts[var.client_config.landingzone_key][item.palo_alto_connection_string.storage_account].name}, access-key=${var.storage_accounts[var.client_config.landingzone_key][item.palo_alto_connection_string.storage_account].primary_access_key}, file-share=${var.storage_accounts[var.client_config.landingzone_key][item.palo_alto_connection_string.storage_account].file_share[item.palo_alto_connection_string.file_share].name}, share-directory=${var.storage_accounts[var.client_config.landingzone_key][item.palo_alto_connection_string.storage_account].file_share[item.palo_alto_connection_string.file_share].file_share_directories[item.palo_alto_connection_string.file_share_directory].name}") @@ -33,14 +33,14 @@ locals { } combined_objects = { - storage_accounts = var.storage_accounts - keyvaults = var.keyvaults - keyvault_keys = try(data.azurerm_key_vault_key.custom_data,{}) - keyvault_secrets = try(data.azurerm_key_vault_secret.custom_data,{}) - keyvault_certificates = try(data.azurerm_key_vault_certificate.custom_data,{}) - vnets = var.vnets + storage_accounts = var.storage_accounts + keyvaults = var.keyvaults + keyvault_keys = try(data.azurerm_key_vault_key.custom_data, {}) + keyvault_secrets = try(data.azurerm_key_vault_secret.custom_data, {}) + keyvault_certificates = try(data.azurerm_key_vault_certificate.custom_data, {}) + vnets = var.vnets } - + dynamic_custom_data_to_process = { for setting in flatten([ @@ -55,10 +55,10 @@ locals { ]) : setting.key => setting.value } - dynamic_custom_data_combined_objects ={ - for key, value in local.dynamic_custom_data_to_process: key => + dynamic_custom_data_combined_objects = { + for key, value in local.dynamic_custom_data_to_process : key => { - for k,v in value: k => try(local.combined_objects[key][try(v.lz_key, var.client_config.landingzone_key)][k], local.combined_objects[key][k]) + for k, v in value : k => try(local.combined_objects[key][try(v.lz_key, var.client_config.landingzone_key)][k], local.combined_objects[key][k]) } } diff --git a/modules/compute/virtual_machine/network_interface.tf b/modules/compute/virtual_machine/network_interface.tf index c1e201519e..ba20ece0b6 100644 --- a/modules/compute/virtual_machine/network_interface.tf +++ b/modules/compute/virtual_machine/network_interface.tf @@ -55,8 +55,7 @@ resource "azurerm_network_interface" "nic" { ip_configuration { name = azurecaf_name.nic[each.key].result - subnet_id = can(each.value.subnet_id) || can(each.value.vnet_key) == false ? try(each.value.subnet_id, var.virtual_subnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.subnet_key].id) : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id - + subnet_id = can(each.value.subnet_id) || can(each.value.vnet_key) == false ? try(each.value.subnet_id, var.virtual_subnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.subnet_key].id) : try(var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id, var.virtual_subnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.subnet_key].id) private_ip_address_allocation = lookup(each.value, "private_ip_address_allocation", "Dynamic") private_ip_address_version = lookup(each.value, "private_ip_address_version", null) private_ip_address = lookup(each.value, "private_ip_address", null) diff --git a/modules/compute/virtual_machine/vm_disk.tf b/modules/compute/virtual_machine/vm_disk.tf index 2f1b9aea7c..506ad2e2a2 100644 --- a/modules/compute/virtual_machine/vm_disk.tf +++ b/modules/compute/virtual_machine/vm_disk.tf @@ -23,8 +23,7 @@ resource "azurerm_managed_disk" "disk" { disk_iops_read_write = try(each.value.disk_iops_read_write, null) disk_mbps_read_write = try(each.value.disk.disk_mbps_read_write, null) tags = merge(local.tags, try(each.value.tags, {})) - disk_encryption_set_id = try(each.value.disk_encryption_set_key, null) == null ? null : var.disk_encryption_sets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.disk_encryption_set_key].id - + disk_encryption_set_id = can(each.value.disk_encryption_set_id) ? each.value.disk_encryption_set_id : can(each.value.disk_encryption_set_key) ? var.disk_encryption_sets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.disk_encryption_set_key].id : null lifecycle { ignore_changes = [ name, #for ASR disk restores diff --git a/modules/compute/virtual_machine/vm_linux.tf b/modules/compute/virtual_machine/vm_linux.tf index 59814b9101..60b99d97ca 100644 --- a/modules/compute/virtual_machine/vm_linux.tf +++ b/modules/compute/virtual_machine/vm_linux.tf @@ -46,7 +46,7 @@ data "azurecaf_name" "os_disk_linux" { use_slug = var.global_settings.use_slug } resource "local_sensitive_file" "custom_data" { - for_each = local.os_type == "linux" ? try({for k,v in var.settings.virtual_machine_settings : k => v if can(v.custom_data.templatefile)} , {}) : {} + for_each = local.os_type == "linux" ? try({ for k, v in var.settings.virtual_machine_settings : k => v if can(v.custom_data.templatefile) }, {}) : {} content = templatefile(try(format("%s/%s", path.cwd, each.value.custom_data.templatefile), each.value.custom_data.templatefile), merge(each.value.custom_data, local.dynamic_custom_data)) filename = try(format("%s/%s.out", path.cwd, each.value.custom_data.templatefile), each.value.custom_data.templatefile) } @@ -54,35 +54,39 @@ resource "local_sensitive_file" "custom_data" { resource "azurerm_linux_virtual_machine" "vm" { for_each = local.os_type == "linux" ? var.settings.virtual_machine_settings : {} - admin_password = each.value.disable_password_authentication == false ? each.value.admin_password : null - admin_username = each.value.admin_username - allow_extension_operations = try(each.value.allow_extension_operations, null) - availability_set_id = can(each.value.availability_set_key) || can(each.value.availability_set.key) ? var.availability_sets[try(var.client_config.landingzone_key, each.value.availability_set.lz_key)][try(each.value.availability_set_key, each.value.availability_set.key)].id : try(each.value.availability_set.id, each.value.availability_set_id, null) - computer_name = data.azurecaf_name.linux_computer_name[each.key].result - disable_password_authentication = try(each.value.disable_password_authentication, true) - encryption_at_host_enabled = try(each.value.encryption_at_host_enabled, null) - eviction_policy = try(each.value.eviction_policy, null) - license_type = try(each.value.license_type, null) - location = local.location - max_bid_price = try(each.value.max_bid_price, null) - name = data.azurecaf_name.linux[each.key].result - network_interface_ids = local.nic_ids + admin_password = each.value.disable_password_authentication == false ? each.value.admin_password : null + admin_username = each.value.admin_username + allow_extension_operations = try(each.value.allow_extension_operations, null) + availability_set_id = can(each.value.availability_set_key) || can(each.value.availability_set.key) ? var.availability_sets[try(var.client_config.landingzone_key, each.value.availability_set.lz_key)][try(each.value.availability_set_key, each.value.availability_set.key)].id : try(each.value.availability_set.id, each.value.availability_set_id, null) + computer_name = data.azurecaf_name.linux_computer_name[each.key].result + disable_password_authentication = try(each.value.disable_password_authentication, true) + encryption_at_host_enabled = try(each.value.encryption_at_host_enabled, null) + eviction_policy = try(each.value.eviction_policy, null) + license_type = try(each.value.license_type, null) + location = local.location + max_bid_price = try(each.value.max_bid_price, null) + name = data.azurecaf_name.linux[each.key].result + network_interface_ids = local.nic_ids + bypass_platform_safety_checks_on_user_schedule_enabled = try(each.value.bypass_platform_safety_checks_on_user_schedule_enabled, null) # (Optional) Specifies the mode of in-guest patching to this Linux Virtual Machine. Possible values are AutomaticByPlatform and ImageDefault. Defaults to ImageDefault. For more information on patch modes please see the product documentation. - patch_mode = try(each.value.patch_mode, "ImageDefault") - priority = try(each.value.priority, null) - provision_vm_agent = try(each.value.provision_vm_agent, true) - proximity_placement_group_id = can(each.value.proximity_placement_group_key) || can(each.value.proximity_placement_group.key) ? var.proximity_placement_groups[try(var.client_config.landingzone_key, var.client_config.landingzone_key)][try(each.value.proximity_placement_group_key, each.value.proximity_placement_group.key)].id : try(each.value.proximity_placement_group_id, each.value.proximity_placement_group.id, null) - resource_group_name = local.resource_group_name - size = each.value.size - tags = merge(local.tags, try(each.value.tags, null)) - zone = try(each.value.zone, null) + patch_mode = try(each.value.patch_mode, "ImageDefault") + priority = try(each.value.priority, null) + provision_vm_agent = try(each.value.provision_vm_agent, true) + proximity_placement_group_id = can(each.value.proximity_placement_group_key) || can(each.value.proximity_placement_group.key) ? var.proximity_placement_groups[try(var.client_config.landingzone_key, var.client_config.landingzone_key)][try(each.value.proximity_placement_group_key, each.value.proximity_placement_group.key)].id : try(each.value.proximity_placement_group_id, each.value.proximity_placement_group.id, null) + resource_group_name = local.resource_group_name + size = each.value.size + tags = merge(local.tags, try(each.value.tags, null)) + zone = try(each.value.zone, null) + secure_boot_enabled = try(each.value.secure_boot_enabled, null) + vtpm_enabled = try(each.value.vtpm_enabled, null) + custom_data = try( try( try(local_sensitive_file.custom_data[each.key].content_base64, local.dynamic_custom_data[each.value.custom_data][each.value.name]), - try(filebase64(format("%s/%s", path.cwd, each.value.custom_data)), base64encode(each.value.custom_data))), + try(filebase64(format("%s/%s", path.cwd, each.value.custom_data)), base64encode(each.value.custom_data))), null) - + dedicated_host_id = can(each.value.dedicated_host.key) ? var.dedicated_hosts[try(each.value.dedicated_host.lz_key, var.client_config.landingzone_key)][each.value.dedicated_host.key].id : try(each.value.dedicated_host.id, null) @@ -154,8 +158,7 @@ resource "azurerm_linux_virtual_machine" "vm" { name = try(data.azurecaf_name.os_disk_linux[each.key].result, null) storage_account_type = try(each.value.os_disk.storage_account_type, null) write_accelerator_enabled = try(each.value.os_disk.write_accelerator_enabled, false) - disk_encryption_set_id = try(each.value.os_disk.disk_encryption_set_key, null) == null ? null : try(var.disk_encryption_sets[var.client_config.landingzone_key][each.value.os_disk.disk_encryption_set_key].id, var.disk_encryption_sets[each.value.os_disk.lz_key][each.value.os_disk.disk_encryption_set_key].id, null) - + disk_encryption_set_id = can(each.value.os_disk.disk_encryption_set_id) ? each.value.os_disk.disk_encryption_set_id : can(each.value.os_disk.disk_encryption_set_key) ? var.disk_encryption_sets[try(each.value.os_disk.lz_key, var.client_config.landingzone_key)][each.value.os_disk.disk_encryption_set_key].id : null dynamic "diff_disk_settings" { for_each = try(each.value.diff_disk_settings, false) == false ? [] : [1] diff --git a/modules/compute/virtual_machine/vm_windows.tf b/modules/compute/virtual_machine/vm_windows.tf index 979bb89ddc..cd15555e34 100644 --- a/modules/compute/virtual_machine/vm_windows.tf +++ b/modules/compute/virtual_machine/vm_windows.tf @@ -41,28 +41,31 @@ resource "azurerm_windows_virtual_machine" "vm" { depends_on = [azurerm_network_interface.nic, azurerm_network_interface_security_group_association.nic_nsg] for_each = local.os_type == "windows" ? var.settings.virtual_machine_settings : {} - admin_password = try(each.value.admin_password_key, null) == null ? random_password.admin[local.os_type].result : local.admin_password - admin_username = try(each.value.admin_username_key, null) == null ? each.value.admin_username : local.admin_username - allow_extension_operations = try(each.value.allow_extension_operations, null) - availability_set_id = can(each.value.availability_set_key) || can(each.value.availability_set.key) ? var.availability_sets[try(var.client_config.landingzone_key, each.value.availability_set.lz_key)][try(each.value.availability_set_key, each.value.availability_set.key)].id : try(each.value.availability_set.id, each.value.availability_set_id, null) - computer_name = data.azurecaf_name.windows_computer_name[each.key].result - enable_automatic_updates = try(each.value.enable_automatic_updates, null) - encryption_at_host_enabled = try(each.value.encryption_at_host_enabled, null) - eviction_policy = try(each.value.eviction_policy, null) - license_type = try(each.value.license_type, null) - location = local.location - max_bid_price = try(each.value.max_bid_price, null) - name = data.azurecaf_name.windows[each.key].result - network_interface_ids = local.nic_ids - priority = try(each.value.priority, null) - patch_mode = try(each.value.patch_mode, "AutomaticByOS") - provision_vm_agent = try(each.value.provision_vm_agent, true) - proximity_placement_group_id = can(each.value.proximity_placement_group_key) || can(each.value.proximity_placement_group.key) ? var.proximity_placement_groups[try(var.client_config.landingzone_key, var.client_config.landingzone_key)][try(each.value.proximity_placement_group_key, each.value.proximity_placement_group.key)].id : try(each.value.proximity_placement_group_id, each.value.proximity_placement_group.id, null) - resource_group_name = local.resource_group_name - size = each.value.size - tags = merge(local.tags, try(each.value.tags, null)) - timezone = try(each.value.timezone, null) - zone = try(each.value.zone, null) + admin_password = try(each.value.admin_password_key, null) == null ? random_password.admin[local.os_type].result : local.admin_password + admin_username = try(each.value.admin_username_key, null) == null ? each.value.admin_username : local.admin_username + allow_extension_operations = try(each.value.allow_extension_operations, null) + availability_set_id = can(each.value.availability_set_key) || can(each.value.availability_set.key) ? var.availability_sets[try(var.client_config.landingzone_key, each.value.availability_set.lz_key)][try(each.value.availability_set_key, each.value.availability_set.key)].id : try(each.value.availability_set.id, each.value.availability_set_id, null) + bypass_platform_safety_checks_on_user_schedule_enabled = try(each.value.bypass_platform_safety_checks_on_user_schedule_enabled, null) + computer_name = data.azurecaf_name.windows_computer_name[each.key].result + enable_automatic_updates = try(each.value.enable_automatic_updates, null) + encryption_at_host_enabled = try(each.value.encryption_at_host_enabled, null) + eviction_policy = try(each.value.eviction_policy, null) + license_type = try(each.value.license_type, null) + location = local.location + max_bid_price = try(each.value.max_bid_price, null) + name = data.azurecaf_name.windows[each.key].result + network_interface_ids = local.nic_ids + priority = try(each.value.priority, null) + patch_mode = try(each.value.patch_mode, "AutomaticByOS") + provision_vm_agent = try(each.value.provision_vm_agent, true) + proximity_placement_group_id = can(each.value.proximity_placement_group_key) || can(each.value.proximity_placement_group.key) ? var.proximity_placement_groups[try(var.client_config.landingzone_key, var.client_config.landingzone_key)][try(each.value.proximity_placement_group_key, each.value.proximity_placement_group.key)].id : try(each.value.proximity_placement_group_id, each.value.proximity_placement_group.id, null) + resource_group_name = local.resource_group_name + size = each.value.size + tags = merge(local.tags, try(each.value.tags, null)) + timezone = try(each.value.timezone, null) + zone = try(each.value.zone, null) + secure_boot_enabled = try(each.value.secure_boot_enabled, null) + vtpm_enabled = try(each.value.vtpm_enabled, null) custom_data = try( try(filebase64(format("%s/%s", path.cwd, each.value.custom_data)), base64encode(each.value.custom_data)), @@ -78,8 +81,7 @@ resource "azurerm_windows_virtual_machine" "vm" { name = data.azurecaf_name.os_disk_windows[each.key].result storage_account_type = each.value.os_disk.storage_account_type write_accelerator_enabled = try(each.value.os_disk.write_accelerator_enabled, false) - disk_encryption_set_id = try(each.value.os_disk.disk_encryption_set_key, null) == null ? null : try(var.disk_encryption_sets[var.client_config.landingzone_key][each.value.os_disk.disk_encryption_set_key].id, var.disk_encryption_sets[each.value.os_disk.lz_key][each.value.os_disk.disk_encryption_set_key].id, null) - + disk_encryption_set_id = can(each.value.os_disk.disk_encryption_set_id) ? each.value.os_disk.disk_encryption_set_id : can(each.value.os_disk.disk_encryption_set_key) ? var.disk_encryption_sets[try(each.value.os_disk.lz_key, var.client_config.landingzone_key)][each.value.os_disk.disk_encryption_set_key].id : null dynamic "diff_disk_settings" { for_each = try(each.value.diff_disk_settings, false) == false ? [] : [1] diff --git a/modules/compute/virtual_machine_extensions/custom_script.tf b/modules/compute/virtual_machine_extensions/custom_script.tf index 7bd96425c2..e6afbca035 100644 --- a/modules/compute/virtual_machine_extensions/custom_script.tf +++ b/modules/compute/virtual_machine_extensions/custom_script.tf @@ -43,7 +43,7 @@ locals { # managed identity identity_type = try(var.extension.identity_type, "") #userassigned, systemassigned or null managed_local_identity = try(var.managed_identities[var.client_config.landingzone_key][var.extension.managed_identity_key].principal_id, "") - managed_remote_identity = try(var.managed_identities[var.extension.lz_key][var.extension.managed_identity_key].principal_id, "") + managed_remote_identity = try(var.managed_identities[var.extension.managed_identity_lz_key][var.extension.managed_identity_key].principal_id, var.managed_identities[var.extension.lz_key][var.extension.managed_identity_key].principal_id, "") provided_identity = try(var.extension.managed_identity_id, "") managed_identity = try(coalesce(local.managed_local_identity, local.managed_remote_identity, local.provided_identity), "") @@ -71,7 +71,7 @@ locals { # fileuris fileuri_sa_key = try(var.extension.fileuri_sa_key, "") fileuri_sa_path = try(var.extension.fileuri_sa_path, "") - fileuri_sa = local.fileuri_sa_key != "" ? try(var.storage_accounts[var.extension.lz_key][var.extension.fileuri_sa_key].primary_blob_endpoint, var.storage_accounts[var.client_config.landingzone_key][var.extension.fileuri_sa_key].primary_blob_endpoint) : "" + fileuri_sa = local.fileuri_sa_key != "" ? try(var.storage_accounts[var.extension.fileuri_sa_lz_key][var.extension.fileuri_sa_key].primary_blob_endpoint, var.storage_accounts[var.extension.lz_key][var.extension.fileuri_sa_key].primary_blob_endpoint, var.storage_accounts[var.client_config.landingzone_key][var.extension.fileuri_sa_key].primary_blob_endpoint) : "" fileuri_sa_full_path = "${local.fileuri_sa}${local.fileuri_sa_path}" fileuri_sa_defined = try(var.extension.fileuris, "") fileuris = local.fileuri_sa_defined == "" ? [local.fileuri_sa_full_path] : var.extension.fileuris diff --git a/modules/data_factory/data_factory/module.tf b/modules/data_factory/data_factory/module.tf index 4479a85741..9e6f7387c2 100644 --- a/modules/data_factory/data_factory/module.tf +++ b/modules/data_factory/data_factory/module.tf @@ -25,7 +25,7 @@ resource "azurerm_data_factory" "df" { } } dynamic "global_parameter" { - for_each = try(var.settings.global_parameter, null) != null ? [var.settings.global_parameter] : [] + for_each = try(var.settings.global_parameter, null) != null ? var.settings.global_parameter : {} content { name = global_parameter.value.name diff --git a/modules/databases/cosmos_dbs/output.tf b/modules/databases/cosmos_dbs/output.tf index 00995cc84d..379cff6d14 100644 --- a/modules/databases/cosmos_dbs/output.tf +++ b/modules/databases/cosmos_dbs/output.tf @@ -2,10 +2,6 @@ output "cosmos_account" { value = azurerm_cosmosdb_account.cosmos_account.id } -output "connection_string" { - value = azurerm_cosmosdb_account.cosmos_account.connection_strings[0] -} - output "primary_key" { value = azurerm_cosmosdb_account.cosmos_account.primary_key } diff --git a/modules/databases/data_explorer/kusto_clusters/module.tf b/modules/databases/data_explorer/kusto_clusters/module.tf index 82bea499fe..4a7ad9ffbf 100644 --- a/modules/databases/data_explorer/kusto_clusters/module.tf +++ b/modules/databases/data_explorer/kusto_clusters/module.tf @@ -52,9 +52,10 @@ resource "azurerm_kusto_cluster" "kusto" { maximum_instances = optimized_auto_scale.value.maximum_instances } } - trusted_external_tenants = try(var.settings.trusted_external_tenants, null) - zones = try(var.settings.zones, null) - engine = try(var.settings.engine, null) - auto_stop_enabled = try(var.settings.auto_stop_enabled, null) - tags = local.tags -} \ No newline at end of file + trusted_external_tenants = try(var.settings.trusted_external_tenants, null) + zones = try(var.settings.zones, null) + engine = try(var.settings.engine, null) + auto_stop_enabled = try(var.settings.auto_stop_enabled, null) + public_network_access_enabled = try(var.settings.public_network_access_enabled, null) + tags = local.tags +} diff --git a/modules/databases/data_explorer/kusto_clusters/private_endpoint.tf b/modules/databases/data_explorer/kusto_clusters/private_endpoint.tf new file mode 100644 index 0000000000..8c1d1b88c5 --- /dev/null +++ b/modules/databases/data_explorer/kusto_clusters/private_endpoint.tf @@ -0,0 +1,16 @@ +module "private_endpoint" { + source = "../../../networking/private_endpoint" + for_each = try(var.private_endpoints, {}) + + resource_id = azurerm_kusto_cluster.kusto.id + name = each.value.name + location = var.location + resource_group_name = var.resource_group_name + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.combined_resources.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + settings = each.value + global_settings = var.global_settings + base_tags = var.global_settings.inherit_tags + tags = local.tags + private_dns = var.combined_resources.private_dns + client_config = var.client_config +} diff --git a/modules/databases/data_explorer/kusto_clusters/variables.tf b/modules/databases/data_explorer/kusto_clusters/variables.tf index b0934606a9..a6b677d72a 100644 --- a/modules/databases/data_explorer/kusto_clusters/variables.tf +++ b/modules/databases/data_explorer/kusto_clusters/variables.tf @@ -25,8 +25,8 @@ variable "vnets" { variable "pips" { default = null } +variable "private_endpoints" {} variable "combined_resources" { description = "Provide a map of combined resources for environment_variables_from_resources" default = {} } - diff --git a/modules/databases/mssql_managed_instance/private_endpoints.tf b/modules/databases/mssql_managed_instance/private_endpoints.tf new file mode 100644 index 0000000000..81e3668e46 --- /dev/null +++ b/modules/databases/mssql_managed_instance/private_endpoints.tf @@ -0,0 +1,23 @@ + + +# +# Private endpoint +# + +module "private_endpoint" { + source = "../../networking/private_endpoint" + for_each = var.private_endpoints + + resource_id = local.output.id + name = each.value.name + location = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location + resource_group_name = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + + settings = each.value + global_settings = var.global_settings + base_tags = var.inherit_tags + tags = local.tags + private_dns = var.private_dns + client_config = var.client_config +} diff --git a/modules/databases/mssql_managed_instance/variables.tf b/modules/databases/mssql_managed_instance/variables.tf index 2aafbc3456..7b6ba43c80 100644 --- a/modules/databases/mssql_managed_instance/variables.tf +++ b/modules/databases/mssql_managed_instance/variables.tf @@ -7,6 +7,10 @@ variable "base_tags" { description = "Base tags for the resource to be inherited from the resource group." type = map(any) } +variable "inherit_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} variable "subnet_id" {} variable "resource_group_name" { description = "(Required) The name of the resource group where to create the resource." @@ -20,3 +24,9 @@ variable "primary_server_id" { default = "" } variable "keyvault" {} +variable "vnets" {} +variable "resource_groups" {} +variable "private_endpoints" {} +variable "private_dns" { + default = {} +} diff --git a/modules/databases/mssql_managed_instance_v1/private_endpoints.tf b/modules/databases/mssql_managed_instance_v1/private_endpoints.tf new file mode 100644 index 0000000000..7b1d83fe7b --- /dev/null +++ b/modules/databases/mssql_managed_instance_v1/private_endpoints.tf @@ -0,0 +1,23 @@ + + +# +# Private endpoint +# + +module "private_endpoint" { + source = "../../networking/private_endpoint" + for_each = var.private_endpoints + + resource_id = azurerm_mssql_managed_instance.mssqlmi.id + name = each.value.name + location = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location + resource_group_name = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + + settings = each.value + global_settings = var.global_settings + base_tags = var.inherit_tags + tags = local.tags + private_dns = var.private_dns + client_config = var.client_config +} diff --git a/modules/databases/mssql_managed_instance_v1/variables.tf b/modules/databases/mssql_managed_instance_v1/variables.tf index 8504b3733b..2ee8d621a8 100644 --- a/modules/databases/mssql_managed_instance_v1/variables.tf +++ b/modules/databases/mssql_managed_instance_v1/variables.tf @@ -30,7 +30,16 @@ variable "group_id" { } variable "keyvault" {} - +variable "resource_groups" {} +variable "vnets" {} +variable "private_endpoints" {} +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = map(any) +} +variable "private_dns" { + default = {} +} variable "primary_server_id" {} variable "settings" { @@ -54,6 +63,7 @@ variable "settings" { "minimal_tls_version", "name", "networking", + "private_endpoints", "primary_server", "proxy_override", "public_data_endpoint_enabled", diff --git a/modules/databases/mysql_flexible_server/main.tf b/modules/databases/mysql_flexible_server/main.tf index 2e1918847f..e8019f6ebf 100644 --- a/modules/databases/mysql_flexible_server/main.tf +++ b/modules/databases/mysql_flexible_server/main.tf @@ -12,4 +12,3 @@ locals { } tags = merge(var.base_tags, local.module_tag, try(var.settings.tags, null)) } - diff --git a/modules/databases/mysql_flexible_server/private_endpoints.tf b/modules/databases/mysql_flexible_server/private_endpoints.tf new file mode 100644 index 0000000000..c77476562c --- /dev/null +++ b/modules/databases/mysql_flexible_server/private_endpoints.tf @@ -0,0 +1,20 @@ +module "private_endpoint" { + source = "../../networking/private_endpoint" + for_each = var.private_endpoints + + resource_id = azurerm_mysql_flexible_server.mysql.id + name = each.value.name + # location = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location + # resource_group_name = var.resource_groups[try(each.value.resource_group.lz_key, var.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name + location = var.location + resource_group_name = var.resource_group_name + + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + + settings = each.value + global_settings = var.global_settings + base_tags = var.inherit_base_tags + tags = local.tags + private_dns = var.private_dns + client_config = var.client_config +} diff --git a/modules/databases/mysql_flexible_server/server.tf b/modules/databases/mysql_flexible_server/server.tf index d2b82d4ef9..50b1dc36fc 100644 --- a/modules/databases/mysql_flexible_server/server.tf +++ b/modules/databases/mysql_flexible_server/server.tf @@ -52,9 +52,10 @@ resource "azurerm_mysql_flexible_server" "mysql" { for_each = try(var.settings.storage, null) == null ? [] : [var.settings.storage] content { - auto_grow_enabled = try(var.settings.storage.auto_grow_enabled, "True") - iops = try(var.settings.storage.iops, "360") - size_gb = try(var.settings.storage.size_gb, "20") + auto_grow_enabled = try(var.settings.storage.auto_grow_enabled, "True") + io_scaling_enabled = try(var.settings.storage.io_scaling_enabled, "False") + iops = var.settings.storage.io_scaling_enabled ? null : try(var.settings.storage.iops, "360") + size_gb = var.settings.storage.io_scaling_enabled ? null : try(var.settings.storage.size_gb, "20") } } @@ -116,4 +117,4 @@ resource "azurerm_key_vault_secret" "mysql_fqdn" { name = format("%s-mysql-fqdn", azurecaf_name.mysql_flexible_server.result) value = azurerm_mysql_flexible_server.mysql.fqdn key_vault_id = var.remote_objects.keyvault_id -} \ No newline at end of file +} diff --git a/modules/databases/mysql_flexible_server/variables.tf b/modules/databases/mysql_flexible_server/variables.tf index 790831d1d0..c5717d2735 100644 --- a/modules/databases/mysql_flexible_server/variables.tf +++ b/modules/databases/mysql_flexible_server/variables.tf @@ -31,4 +31,21 @@ variable "settings" { variable "location" { description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created." type = string +} + +variable "private_dns" { + default = {} +} + +variable "private_endpoints" {} + +variable "resource_groups" {} + +variable "resource_group" {} + +variable "vnets" {} + +variable "inherit_base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool } \ No newline at end of file diff --git a/modules/databases/postgresql_flexible_server/private_endpoint.tf b/modules/databases/postgresql_flexible_server/private_endpoint.tf new file mode 100644 index 0000000000..ae7aeda65f --- /dev/null +++ b/modules/databases/postgresql_flexible_server/private_endpoint.tf @@ -0,0 +1,16 @@ +module "private_endpoint" { + source = "../../networking/private_endpoint" + for_each = try(var.private_endpoints, {}) + + resource_id = azurerm_postgresql_flexible_server.postgresql.id + name = each.value.name + location = local.location + resource_group_name = local.resource_group_name + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + settings = each.value + global_settings = var.global_settings + base_tags = var.base_tags + tags = local.tags + private_dns = var.private_dns + client_config = var.client_config +} diff --git a/modules/databases/postgresql_flexible_server/server.tf b/modules/databases/postgresql_flexible_server/server.tf index 88ffcfed4b..d588827ccf 100644 --- a/modules/databases/postgresql_flexible_server/server.tf +++ b/modules/databases/postgresql_flexible_server/server.tf @@ -17,6 +17,8 @@ resource "azurerm_postgresql_flexible_server" "postgresql" { zone = try(var.settings.zone, null) storage_mb = try(var.settings.storage_mb, null) auto_grow_enabled = try(var.settings.auto_grow_enabled, null) + + public_network_access_enabled = try(var.settings.public_network_access_enabled, false) delegated_subnet_id = var.remote_objects.subnet_id private_dns_zone_id = var.remote_objects.private_dns_zone_id @@ -25,8 +27,8 @@ resource "azurerm_postgresql_flexible_server" "postgresql" { point_in_time_restore_time_in_utc = try(var.settings.create_mode, "PointInTimeRestore") == "PointInTimeRestore" ? try(var.settings.point_in_time_restore_time_in_utc, null) : null source_server_id = try(var.settings.create_mode, "PointInTimeRestore") == "PointInTimeRestore" ? try(var.settings.source_server_id, null) : null - administrator_login = try(var.settings.create_mode, "Default") == "Default" ? try(var.settings.administrator_username, "pgadmin") : null - administrator_password = try(var.settings.create_mode, "Default") == "Default" ? try(var.settings.administrator_password, azurerm_key_vault_secret.postgresql_administrator_password.0.value) : null + administrator_login = try(var.settings.create_mode, "Default") == "Default" && try(var.settings.authentication.password_auth_enabled, true) ? try(var.settings.administrator_username, "pgadmin") : null + administrator_password = try(var.settings.create_mode, "Default") == "Default" && try(var.settings.authentication.password_auth_enabled, true) ? try(var.settings.administrator_password, azurerm_key_vault_secret.postgresql_administrator_password.0.value) : null dynamic "authentication" { for_each = try(var.settings.authentication, null) == null ? [] : [var.settings.authentication] @@ -125,4 +127,19 @@ resource "azurerm_key_vault_secret" "postgresql_fqdn" { name = format("%s-fqdn", azurecaf_name.postgresql_flexible_server.result) value = azurerm_postgresql_flexible_server.postgresql.fqdn key_vault_id = var.remote_objects.keyvault_id -} \ No newline at end of file +} + +resource "azurerm_postgresql_flexible_server_active_directory_administrator" "administrator" { + for_each = try(var.settings.authentication.active_directory_administrators, {}) + server_name = azurerm_postgresql_flexible_server.postgresql.name + resource_group_name = local.resource_group_name + tenant_id = try(var.settings.authentication.tenant_id, var.client_config.tenant_id) + object_id = can(each.value.object_id) ? each.value.object_id : ( + each.value.principal_type == "ServicePrincipal" ? var.remote_objects.service_principals[try(each.value.object_lz_key, var.client_config.landingzone_key)][each.value.object_key].object_id : + each.value.principal_type == "Group" ? var.remote_objects.azuread_groups[try(each.value.object_lz_key, var.client_config.landingzone_key)][each.value.object_key].object_id : + each.value.principal_type == "User" ? var.remote_objects.azuread_users[try(each.value.object_lz_key, var.client_config.landingzone_key)][each.value.object_key].object_id : + each.value.principal_type == "ManagedIdentity" ? var.remote_objects.managed_identities[try(each.value.object_lz_key, var.client_config.landingzone_key)][each.value.object_key].principal_id : null + ) + principal_name = each.value.principal_name + principal_type = each.value.principal_type == "ManagedIdentity" ? "ServicePrincipal" : each.value.principal_type +} diff --git a/modules/databases/postgresql_flexible_server/variables.tf b/modules/databases/postgresql_flexible_server/variables.tf index 50b5db9df1..1c25a4f06d 100755 --- a/modules/databases/postgresql_flexible_server/variables.tf +++ b/modules/databases/postgresql_flexible_server/variables.tf @@ -25,4 +25,12 @@ variable "resource_group" { variable "base_tags" { description = "Base tags for the resource to be inherited from the resource group." type = bool -} \ No newline at end of file +} + +variable "vnets" {} + +variable "private_endpoints" {} + +variable "private_dns" { + default = {} +} diff --git a/modules/identity/active_directory_domain_service/module.tf b/modules/identity/active_directory_domain_service/module.tf index eb96be8310..d3af67beb6 100644 --- a/modules/identity/active_directory_domain_service/module.tf +++ b/modules/identity/active_directory_domain_service/module.tf @@ -19,13 +19,14 @@ resource "azurecaf_name" "aadds" { # use_slug = var.global_settings.use_slug # } resource "azurerm_active_directory_domain_service" "aadds" { - name = azurecaf_name.aadds.result - resource_group_name = local.resource_group_name - location = local.location - domain_name = var.settings.domain_name - filtered_sync_enabled = try(var.settings.filtered_sync_enabled, null) - sku = var.settings.sku - tags = merge(local.tags, try(var.settings.tags, {})) + name = azurecaf_name.aadds.result + resource_group_name = local.resource_group_name + location = local.location + domain_name = var.settings.domain_name + filtered_sync_enabled = try(var.settings.filtered_sync_enabled, null) + domain_configuration_type = try(var.settings.domain_configuration_type, null) + sku = var.settings.sku + tags = merge(local.tags, try(var.settings.tags, {})) dynamic "secure_ldap" { for_each = can(var.settings.secure_ldap) ? [var.settings.secure_ldap] : [] diff --git a/modules/load_test/load_test.tf b/modules/load_test/load_test.tf new file mode 100644 index 0000000000..1191116aa2 --- /dev/null +++ b/modules/load_test/load_test.tf @@ -0,0 +1,28 @@ +# Terraform azurerm resource: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/load_test + +data "azurecaf_name" "this" { + name = var.settings.name + resource_type = "azurerm_load_test" + prefixes = var.global_settings.prefixes + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} + +resource "azurerm_load_test" "this" { + name = data.azurecaf_name.this.result + resource_group_name = local.resource_group_name + location = local.location + description = try(var.settings.description, null) + + dynamic "identity" { + for_each = lookup(var.settings, "identity", {}) == {} ? [] : [1] + content { + type = var.settings.identity.type + identity_ids = local.managed_identities + } + } + + tags = merge(local.tags, lookup(var.settings, "tags", {})) +} diff --git a/modules/load_test/main.tf b/modules/load_test/main.tf new file mode 100644 index 0000000000..3a3afd4ff8 --- /dev/null +++ b/modules/load_test/main.tf @@ -0,0 +1,25 @@ +locals { + module_tag = { + "module" = basename(abspath(path.module)) + } + tags = var.base_tags ? merge( + var.global_settings.tags, + try(var.resource_group.tags, null), + local.module_tag, + try(var.settings.tags, null) + ) : merge( + local.module_tag, + try(var.settings.tags, + null) + ) + location = coalesce(var.location, var.resource_group.location) + resource_group_name = coalesce(var.resource_group_name, var.resource_group.name) +} + +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} diff --git a/modules/load_test/managed_identities.tf b/modules/load_test/managed_identities.tf new file mode 100644 index 0000000000..a425758162 --- /dev/null +++ b/modules/load_test/managed_identities.tf @@ -0,0 +1,23 @@ +# +# Managed identities from remote state +# + +locals { + managed_local_identities = flatten([ + for managed_identity_key in try(var.settings.identity.managed_identity_keys, []) : [ + var.remote_objects.managed_identities[var.client_config.landingzone_key][managed_identity_key].id + ] + ]) + + managed_remote_identities = flatten([ + for lz_key, value in try(var.settings.identity.remote, []) : [ + for managed_identity_key in value.managed_identity_keys : [ + var.remote_objects.managed_identities[lz_key][managed_identity_key].id + ] + ] + ]) + + provided_identities = try(var.settings.identity.managed_identity_ids, []) + + managed_identities = concat(local.provided_identities, local.managed_local_identities, local.managed_remote_identities) +} diff --git a/modules/load_test/output.tf b/modules/load_test/output.tf new file mode 100644 index 0000000000..41618c004d --- /dev/null +++ b/modules/load_test/output.tf @@ -0,0 +1,11 @@ +output "id" { + value = azurerm_load_test.this.id +} + +output "data_plane_uri" { + value = azurerm_load_test.this.data_plane_uri +} + +output "identity" { + value = try(azurerm_load_test.this.identity, null) +} diff --git a/modules/load_test/variables.tf b/modules/load_test/variables.tf new file mode 100644 index 0000000000..b31af17fcf --- /dev/null +++ b/modules/load_test/variables.tf @@ -0,0 +1,31 @@ +variable "settings" {} + +variable "global_settings" { + description = "Global settings object (see module README.md)" +} + +variable "client_config" { + description = "Client configuration object (see module README.md)." +} + +variable "resource_group_name" { + description = "(Required) Resource group of the IoT Hub" +} + +variable "resource_group" { + description = "Resource group object to deploy the IoT Hub" +} + +variable "location" { + description = "(Required) Region in which the resource will be deployed" +} + +variable "remote_objects" { + description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created." + default = {} +} + +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} diff --git a/modules/logic_app/standard/managed_identities.tf b/modules/logic_app/standard/managed_identities.tf deleted file mode 100644 index cb18c82023..0000000000 --- a/modules/logic_app/standard/managed_identities.tf +++ /dev/null @@ -1,17 +0,0 @@ -locals { - managed_local_identities = flatten([ - for managed_identity_key in try(var.identity.managed_identity_keys, []) : [ - var.combined_objects.managed_identities[var.client_config.landingzone_key][managed_identity_key].id - ] - ]) - - managed_remote_identities = flatten([ - for keyvault_key, value in try(var.identity.remote, []) : [ - for managed_identity_key in value.managed_identity_keys : [ - var.combined_objects.managed_identities[keyvault_key][managed_identity_key].id - ] - ] - ]) - - managed_identities = concat(local.managed_local_identities, local.managed_remote_identities) -} \ No newline at end of file diff --git a/modules/logic_app/standard/module.tf b/modules/logic_app/standard/module.tf index a2606ec3b4..ed5249fb9c 100644 --- a/modules/logic_app/standard/module.tf +++ b/modules/logic_app/standard/module.tf @@ -15,9 +15,11 @@ resource "azurerm_logic_app_standard" "logic_app_standard" { app_service_plan_id = local.app_service_plan.id storage_account_name = local.storage_account.name storage_account_access_key = local.storage_account.primary_access_key - - app_settings = local.app_settings - + https_only = lookup(var.settings, "https_only", null) + app_settings = local.app_settings + version = lookup(var.settings, "version", null) + virtual_network_subnet_id = lookup(var.settings, "vnet_integration", null) != null ? can(var.settings.vnet_integration.subnet_id) ? var.settings.vnet_integration.subnet_id : try(var.vnets[try(var.settings.vnet_integration.lz_key, var.client_config.landingzone_key)][var.settings.vnet_integration.vnet_key].subnets[var.settings.vnet_integration.subnet_key].id, + try(var.virtual_subnets[var.client_config.landingzone_key][var.settings.vnet_integration.subnet_key].id, var.virtual_subnets[var.settings.vnet_integration.lz_key][var.settings.vnet_integration.subnet_key].id)) : null dynamic "site_config" { for_each = lookup(var.settings, "site_config", {}) != {} ? [1] : [] @@ -42,14 +44,22 @@ resource "azurerm_logic_app_standard" "logic_app_standard" { } } } -} - -resource "azurerm_app_service_virtual_network_swift_connection" "vnet_config" { - depends_on = [azurerm_logic_app_standard.logic_app_standard] - count = lookup(var.settings, "vnet_integration", {}) != {} ? 1 : 0 + dynamic "identity" { + for_each = lookup(var.settings, "identity", {}) != {} ? [1] : [] + content { + type = lookup(var.settings.identity, "type", null) + identity_ids = can(var.settings.identity.ids) ? var.settings.identity.ids : can(var.settings.identity.key) ? [var.managed_identities[try(var.settings.identity.lz_key, var.client_config.landingzone_key)][var.settings.identity.key].id] : null + } + } - app_service_id = azurerm_logic_app_standard.logic_app_standard.id - subnet_id = can(var.vnet_integration.subnet_id) ? var.vnet_integration.subnet_id : try(var.vnets[try(var.vnet_integration.lz_key, var.client_config.landingzone_key)][var.vnet_integration.vnet_key].subnets[var.vnet_integration.subnet_key].id, - try(var.virtual_subnets[var.client_config.landingzone_key][var.vnet_integration.subnet_key].id, var.virtual_subnets[var.vnet_integration.lz_key][var.vnet_integration.subnet_key].id)) +} -} \ No newline at end of file +#resource "azurerm_app_service_virtual_network_swift_connection" "vnet_config" { +# depends_on = [azurerm_logic_app_standard.logic_app_standard] +# count = lookup(var.settings, "vnet_integration", {}) != {} ? 1 : 0 +# +# app_service_id = azurerm_logic_app_standard.logic_app_standard.id +# subnet_id = can(var.vnet_integration.subnet_id) ? var.vnet_integration.subnet_id : try(var.vnets[try(var.vnet_integration.lz_key, var.client_config.landingzone_key)][var.vnet_integration.vnet_key].subnets[var.vnet_integration.subnet_key].id, +# try(var.virtual_subnets[var.client_config.landingzone_key][var.vnet_integration.subnet_key].id, var.virtual_subnets[var.vnet_integration.lz_key][var.vnet_integration.subnet_key].id)) +# +#} diff --git a/modules/logic_app/standard/variables.tf b/modules/logic_app/standard/variables.tf index 8cce8a818e..7521d7fb84 100644 --- a/modules/logic_app/standard/variables.tf +++ b/modules/logic_app/standard/variables.tf @@ -34,9 +34,6 @@ variable "vnets" { variable "base_tags" { default = {} } -variable "identity" { - default = null -} variable "combined_objects" { default = {} } @@ -45,4 +42,7 @@ variable "virtual_subnets" { } variable "vnet_integration" { default = {} -} \ No newline at end of file +} +variable "managed_identities" { + default = {} +} diff --git a/modules/maintenance/assignment_virtual_machine/main.tf b/modules/maintenance/assignment_virtual_machine/main.tf new file mode 100644 index 0000000000..7c28cbbdb3 --- /dev/null +++ b/modules/maintenance/assignment_virtual_machine/main.tf @@ -0,0 +1,15 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } + +} +locals { + module_tag = { + "module" = basename(abspath(path.module)) + } + tags = merge(var.base_tags, local.module_tag, try(var.tags, null)) + location = var.location +} \ No newline at end of file diff --git a/modules/maintenance/assignment_virtual_machine/module.tf b/modules/maintenance/assignment_virtual_machine/module.tf new file mode 100644 index 0000000000..8db2502a19 --- /dev/null +++ b/modules/maintenance/assignment_virtual_machine/module.tf @@ -0,0 +1,7 @@ +resource "azurerm_maintenance_assignment_virtual_machine" "maintenance_assignment_virtual_machine" { + location = var.location + maintenance_configuration_id = var.maintenance_configuration_id + virtual_machine_id = var.virtual_machine_id +} + + diff --git a/modules/maintenance/assignment_virtual_machine/outputs.tf b/modules/maintenance/assignment_virtual_machine/outputs.tf new file mode 100644 index 0000000000..4e69bbf8ea --- /dev/null +++ b/modules/maintenance/assignment_virtual_machine/outputs.tf @@ -0,0 +1,4 @@ +output "id" { + description = "The ID of the Maintenance Assignment." + value = azurerm_maintenance_assignment_virtual_machine.maintenance_assignment_virtual_machine.id +} diff --git a/modules/maintenance/assignment_virtual_machine/variables.tf b/modules/maintenance/assignment_virtual_machine/variables.tf new file mode 100644 index 0000000000..cc4cc84f9a --- /dev/null +++ b/modules/maintenance/assignment_virtual_machine/variables.tf @@ -0,0 +1,34 @@ +variable "global_settings" { + description = "Global settings object (see module README.md)" +} + +variable "client_config" { + description = "Client configuration object (see module README.md)." +} + +variable "tags" { + description = "Tags to be used for this resource deployment." + type = map(any) + default = {} +} + +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = map(any) + default = {} +} + +variable "location" { + description = "(Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created." + type = string +} + +variable "maintenance_configuration_id" { + description = "(Required) Specifies the ID of the Maintenance Configuration Resource. Changing this forces a new resource to be created." + type = string +} + +variable "virtual_machine_id" { + description = "(Required) Specifies the Virtual Machine ID to which the Maintenance Configuration will be assigned. Changing this forces a new resource to be created." + type = string +} \ No newline at end of file diff --git a/modules/maintenance/configuration/main.tf b/modules/maintenance/configuration/main.tf new file mode 100644 index 0000000000..d720f3c838 --- /dev/null +++ b/modules/maintenance/configuration/main.tf @@ -0,0 +1,16 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } + +} +locals { + module_tag = { + "module" = basename(abspath(path.module)) + } + tags = merge(var.base_tags, local.module_tag, try(var.tags, null)) + location = var.location + resource_group_name = var.resource_group_name +} \ No newline at end of file diff --git a/modules/maintenance/configuration/module.tf b/modules/maintenance/configuration/module.tf new file mode 100644 index 0000000000..aa5e777aa1 --- /dev/null +++ b/modules/maintenance/configuration/module.tf @@ -0,0 +1,60 @@ +resource "azurecaf_name" "maintenance_configuration" { + name = var.name + resource_type = "azurerm_maintenance_configuration" + prefixes = var.global_settings.prefixes + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} + +resource "azurerm_maintenance_configuration" "maintenance_configuration" { + name = azurecaf_name.maintenance_configuration.result + resource_group_name = var.resource_group_name + location = var.location + scope = var.scope + visibility = try(var.visibility, null) + properties = try(var.properties, {}) + in_guest_user_patch_mode = var.settings.scope == "InGuestPatch" ? var.in_guest_user_patch_mode : try(var.in_guest_user_patch_mode, null) + + + dynamic "window" { + for_each = try(var.settings.window, null) != null ? [var.settings.window] : [] + content { + start_date_time = window.value.start_date_time + expiration_date_time = try(window.value.expiration_date_time, null) + duration = window.value.duration + time_zone = window.value.time_zone + recur_every = window.value.recur_every + } + } + + dynamic "install_patches" { + # install_patches is required if scope = "InGuestPatch" + for_each = var.settings.scope == "InGuestPatch" ? [1] : [] + content { + dynamic "linux" { + for_each = try(var.settings.install_patches.linux, null) != null ? [1] : [] + content { + classifications_to_include = try(var.settings.install_patches.linux.classifications_to_include, ["Critical", "Security"]) + package_names_mask_to_exclude = try(var.settings.install_patches.linux.package_names_mask_to_exclude, []) + package_names_mask_to_include = try(var.settings.install_patches.linux.package_names_mask_to_include, []) + } + } + + dynamic "windows" { + for_each = try(var.settings.install_patches.windows, null) != null ? [1] : [] + content { + classifications_to_include = try(var.settings.install_patches.windows.classifications_to_include, ["Critical", "Security"]) + kb_numbers_to_exclude = try(var.settings.install_patches.windows.kb_numbers_to_exclude, []) + kb_numbers_to_include = try(var.settings.install_patches.windows.kb_numbers_to_include, []) + + } + } + + reboot = try(var.settings.install_patches.reboot, "IfRequired") + } + } + + tags = var.tags +} \ No newline at end of file diff --git a/modules/maintenance/configuration/outputs.tf b/modules/maintenance/configuration/outputs.tf new file mode 100644 index 0000000000..3163ab4fa2 --- /dev/null +++ b/modules/maintenance/configuration/outputs.tf @@ -0,0 +1,14 @@ +output "id" { + description = "The ID of the Maintenance Configuration." + value = azurerm_maintenance_configuration.maintenance_configuration.id +} + +output "maintenance_configuration_name" { + description = "The name of the maintenance configuration." + value = azurerm_maintenance_configuration.maintenance_configuration.name +} + +output "maintenance_configuration_location" { + description = "The location where the resource exists" + value = azurerm_maintenance_configuration.maintenance_configuration.location +} \ No newline at end of file diff --git a/modules/maintenance/configuration/variables.tf b/modules/maintenance/configuration/variables.tf new file mode 100644 index 0000000000..15a1888329 --- /dev/null +++ b/modules/maintenance/configuration/variables.tf @@ -0,0 +1,67 @@ +variable "global_settings" { + description = "Global settings object (see module README.md)" +} + +variable "client_config" { + description = "Client configuration object (see module README.md)." +} + +variable "tags" { + description = "Tags to be used for this resource deployment." + type = map(any) + default = {} +} + +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = map(any) + default = {} +} + +variable "name" { + description = "(Required) The name of the PowerBI Embedded. Changing this forces a new resource to be created." + type = string +} + +variable "location" { + description = "(Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created." + type = string +} + +variable "scope" { + description = "(Required) The scope of the Maintenance Configuration. Possible values are Extension, Host, InGuestPatch, OSImage, SQLDB or SQLManagedInstance." + type = string + validation { + condition = contains(["Extension", "Host", "InGuestPatch", "OSImage", "SQLDB", "SQLManagedInstance"], var.scope) + error_message = "Invalid value for scope. Possible values are Extension, Host, InGuestPatch, OSImage, SQLDB or SQLManagedInstance." + } +} + +variable "visibility" { + description = "The visibility of the Maintenance Configuration." + type = string + default = null +} + +variable "properties" { + description = "A mapping of properties to assign to the resource." + type = map(string) + default = {} +} + +variable "resource_group_name" { + description = "Resource group object" +} + +variable "window" {} + +variable "install_patches" {} + +variable "settings" {} + +variable "in_guest_user_patch_mode" { + description = "The in guest user patch mode." + type = string + default = null +} + diff --git a/modules/messaging/eventgrid/eventgrid_system_event_subscription/main.tf b/modules/messaging/eventgrid/eventgrid_system_event_subscription/main.tf new file mode 100644 index 0000000000..1fbfa06797 --- /dev/null +++ b/modules/messaging/eventgrid/eventgrid_system_event_subscription/main.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} diff --git a/modules/messaging/eventgrid/eventgrid_system_event_subscription/module.tf b/modules/messaging/eventgrid/eventgrid_system_event_subscription/module.tf new file mode 100644 index 0000000000..7e41458075 --- /dev/null +++ b/modules/messaging/eventgrid/eventgrid_system_event_subscription/module.tf @@ -0,0 +1,235 @@ + +resource "azurecaf_name" "eges" { + name = var.settings.name + resource_type = "azurerm_eventgrid_event_subscription" + prefixes = var.global_settings.prefixes + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} +resource "azurerm_eventgrid_system_topic_event_subscription" "eges" { + name = azurecaf_name.eges.result + resource_group_name = can(var.settings.resource_group.name) ? var.settings.resource_group.name : var.remote_objects.resource_groups[try(var.settings.resource_group.lz_key, var.client_config.landingzone_key)][var.settings.resource_group.key].name + system_topic = var.remote_objects.eventgrid_system_topics[try(var.settings.eventgrid_system_topic.lz_key, var.client_config.landingzone_key)][var.settings.eventgrid_system_topic.key].name + eventhub_endpoint_id = can(var.settings.eventhub.id) ? var.settings.eventhub.id : can(var.remote_objects.eventhubs[try(var.settings.eventhub.lz_key, var.client_config.landingzone_key)][var.settings.eventhub.key].id) ? var.remote_objects.eventhubs[try(var.settings.eventhub.lz_key, var.client_config.landingzone_key)][var.settings.eventhub.key].id : null + hybrid_connection_endpoint_id = can(var.settings.hybrid_connection.id) ? var.settings.hybrid_connection.id : can(var.remote_objects.hybrid_connections[try(var.settings.hybrid_connection.lz_key, var.client_config.landingzone_key)][var.settings.hybrid_connection.key].id) ? var.remote_objects.hybrid_connections[try(var.settings.hybrid_connection.lz_key, var.client_config.landingzone_key)][var.settings.hybrid_connection.key].id : null + service_bus_queue_endpoint_id = can(var.settings.servicebus_queues.id) ? var.settings.servicebus_queues.id : can(var.remote_objects.servicebus_queues[try(var.settings.servicebus_queues.lz_key, var.client_config.landingzone_key)][var.settings.servicebus_queues.key].id) ? var.remote_objects.servicebus_queues[try(var.settings.servicebus_queues.lz_key, var.client_config.landingzone_key)][var.settings.servicebus_queues.key].id : null + service_bus_topic_endpoint_id = can(var.settings.servicebus_topic.id) ? var.settings.servicebus_topic.id : can(var.remote_objects.servicebus_topic[try(var.settings.servicebus_topic.lz_key, var.client_config.landingzone_key)][var.settings.servicebus_topic.key].id) ? var.remote_objects.servicebus_topic[try(var.settings.servicebus_topic.lz_key, var.client_config.landingzone_key)][var.settings.servicebus_topic.key].id : null + expiration_time_utc = try(var.settings.expiration_time_utc, null) + event_delivery_schema = try(var.settings.event_delivery_schema, null) + + dynamic "azure_function_endpoint" { + for_each = try(var.settings.azure_function_endpoint, null) != null ? [var.settings.azure_function_endpoint] : [] + content { + function_id = can(azure_function_endpoint.value.function_app.id) ? azure_function_endpoint.value.function_app.id : can(var.remote_objects.functions[try(azure_function_endpoint.value.function_app.lz_key, var.client_config.landingzone_key)][azure_function_endpoint.value.function_app.key].id) ? "${var.remote_objects.functions[try(azure_function_endpoint.value.function_app.lz_key, var.client_config.landingzone_key)][azure_function_endpoint.value.function_app.key].id}/functions/${azure_function_endpoint.value.function_name}" : null + max_events_per_batch = try(azure_function_endpoint.value.max_events_per_batch, null) + preferred_batch_size_in_kilobytes = try(azure_function_endpoint.value.preferred_batch_size_in_kilobytes, null) + } + } + dynamic "storage_queue_endpoint" { + for_each = try(var.settings.storage_queue_endpoint, null) != null ? [var.settings.storage_queue_endpoint] : [] + content { + storage_account_id = can(storage_queue_endpoint.value.queue_endpoint.storage_account.id) ? storage_queue_endpoint.value.queue_endpoint.storage_account.id : var.remote_objects.storage_accounts[try(storage_queue_endpoint.value.storage_account.lz_key, var.client_config.landingzone_key)][storage_queue_endpoint.value.storage_account.key].id + queue_name = can(storage_queue_endpoint.value.queue.name) ? storage_queue_endpoint.value.queue.name : var.remote_objects.storage_account_queues[try(storage_queue_endpoint.value.queue.lz_key, var.client_config.landingzone_key)][storage_queue_endpoint.value.queue.key].name + queue_message_time_to_live_in_seconds = try(storage_queue_endpoint.value.queue_message_time_to_live_in_seconds, null) + } + } + dynamic "webhook_endpoint" { + for_each = try(var.settings.webhook_endpoint, null) != null ? [var.settings.webhook_endpoint] : [] + content { + url = try(webhook_endpoint.value.url, null) + base_url = try(webhook_endpoint.value.base_url, null) + max_events_per_batch = try(webhook_endpoint.value.max_events_per_batch, null) + preferred_batch_size_in_kilobytes = try(webhook_endpoint.value.preferred_batch_size_in_kilobytes, null) + active_directory_tenant_id = try(webhook_endpoint.value.active_directory_tenant_id, null) + active_directory_app_id_or_uri = try(webhook_endpoint.value.active_directory_app_id_or_uri, null) + } + } + included_event_types = try(var.settings.included_event_types, null) + + dynamic "advanced_filter" { + for_each = try(var.settings.advanced_filter, null) != null ? [var.settings.advanced_filter] : [] + content { + dynamic "bool_equals" { + for_each = try(var.settings.bool_equals, null) != null ? [var.settings.bool_equals] : [] + content { + key = try(bool_equals.value.subject_begins_with, null) + value = try(bool_equals.value.subject_ends_with, null) + } + } + dynamic "number_greater_than" { + for_each = try(var.settings.number_greater_than, null) != null ? [var.settings.number_greater_than] : [] + content { + key = try(number_greater_than.value.subject_begins_with, null) + value = try(number_greater_than.value.subject_ends_with, null) + + } + } + dynamic "number_greater_than_or_equals" { + for_each = try(var.settings.number_greater_than_or_equals, null) != null ? [var.settings.number_greater_than_or_equals] : [] + content { + key = try(number_greater_than_or_equals.value.subject_begins_with, null) + value = try(number_greater_than_or_equals.value.subject_ends_with, null) + } + } + dynamic "number_less_than" { + for_each = try(var.settings.number_less_than, null) != null ? [var.settings.number_less_than] : [] + content { + key = try(number_less_than.value.subject_begins_with, null) + value = try(number_less_than.value.subject_ends_with, null) + } + } + dynamic "number_less_than_or_equals" { + for_each = try(var.settings.number_less_than_or_equals, null) != null ? [var.settings.number_less_than_or_equals] : [] + content { + key = try(number_less_than.value.number_less_than_or_equals, null) + value = try(number_less_than.value.number_less_than_or_equals, null) + } + } + dynamic "number_in" { + for_each = try(var.settings.number_in, null) != null ? [var.settings.number_in] : [] + content { + key = try(number_less_than.value.number_in, null) + values = try(number_less_than.value.number_in, null) + } + } + dynamic "number_not_in" { + for_each = try(var.settings.number_not_in, null) != null ? [var.settings.number_not_in] : [] + content { + key = try(number_less_than.value.number_not_in, null) + values = try(number_less_than.value.number_not_in, null) + } + } + dynamic "number_in_range" { + for_each = try(var.settings.number_in_range, null) != null ? [var.settings.number_in_range] : [] + content { + key = try(number_less_than.value.number_in_range, null) + values = try(number_less_than.value.number_in_range, null) + } + } + dynamic "number_not_in_range" { + for_each = try(var.settings.number_not_in_range, null) != null ? [var.settings.number_not_in_range] : [] + content { + key = try(number_less_than.value.number_not_in_range, null) + values = try(number_less_than.value.number_not_in_range, null) + } + } + dynamic "string_begins_with" { + for_each = try(var.settings.string_begins_with, null) != null ? [var.settings.string_begins_with] : [] + content { + key = try(number_less_than.value.string_begins_with, null) + values = try(number_less_than.value.string_begins_with, null) + } + } + dynamic "string_not_begins_with" { + for_each = try(var.settings.string_not_begins_with, null) != null ? [var.settings.string_not_begins_with] : [] + content { + key = try(number_less_than.value.string_not_begins_with, null) + values = try(number_less_than.value.string_not_begins_with, null) + } + } + dynamic "string_ends_with" { + for_each = try(var.settings.string_ends_with, null) != null ? [var.settings.string_ends_with] : [] + content { + key = try(number_less_than.value.string_ends_with, null) + values = try(number_less_than.value.string_ends_with, null) + } + } + dynamic "string_not_ends_with" { + for_each = try(var.settings.string_not_ends_with, null) != null ? [var.settings.string_not_ends_with] : [] + content { + key = try(number_less_than.value.string_not_ends_with, null) + values = try(number_less_than.value.string_not_ends_with, null) + } + } + dynamic "string_contains" { + for_each = try(var.settings.string_contains, null) != null ? [var.settings.string_contains] : [] + content { + key = try(number_less_than.value.string_contains, null) + values = try(number_less_than.value.string_contains, null) + } + } + dynamic "string_not_contains" { + for_each = try(var.settings.string_not_contains, null) != null ? [var.settings.string_not_contains] : [] + content { + key = try(number_less_than.value.string_not_contains, null) + values = try(number_less_than.value.string_not_contains, null) + } + } + dynamic "string_in" { + for_each = try(var.settings.string_in, null) != null ? [var.settings.string_in] : [] + content { + key = try(number_less_than.value.string_in, null) + values = try(number_less_than.value.string_in, null) + } + } + dynamic "string_not_in" { + for_each = try(var.settings.string_not_in, null) != null ? [var.settings.string_not_in] : [] + content { + key = try(number_less_than.value.string_not_in, null) + values = try(number_less_than.value.string_not_in, null) + } + } + dynamic "is_not_null" { + for_each = try(var.settings.is_not_null, null) != null ? [var.settings.is_not_null] : [] + content { + key = try(number_less_than.value.is_not_null, null) + } + } + dynamic "is_null_or_undefined" { + for_each = try(var.settings.is_null_or_undefined, null) != null ? [var.settings.is_null_or_undefined] : [] + content { + key = try(number_less_than.value.is_null_or_undefined, null) + } + } + } + } + dynamic "delivery_identity" { + for_each = try(var.settings.delivery_identity, null) != null ? [var.settings.delivery_identity] : [] + content { + type = try(delivery_identity.value.type, null) + user_assigned_identity = try(delivery_identity.value.user_assigned_identity, null) + } + } + dynamic "delivery_property" { + for_each = try(var.settings.delivery_property, null) != null ? [var.settings.delivery_property] : [] + content { + header_name = try(delivery_property.value.header_name, null) + type = try(delivery_property.value.type, null) + value = try(delivery_property.value.value, null) + source_field = try(delivery_property.value.source_field, null) + secret = try(delivery_property.value.secret, null) + } + } + dynamic "dead_letter_identity" { + for_each = try(var.settings.dead_letter_identity, null) != null ? [var.settings.dead_letter_identity] : [] + content { + type = try(dead_letter_identity.value.type, null) + user_assigned_identity = try(dead_letter_identity.value.user_assigned_identity, null) + } + } + dynamic "storage_blob_dead_letter_destination" { + for_each = try(var.settings.storage_blob_dead_letter_destination, null) != null ? [var.settings.storage_blob_dead_letter_destination] : [] + content { + storage_account_id = try(storage_blob_dead_letter_destination.value.storage_account_id, null) + storage_blob_container_name = try(storage_blob_dead_letter_destination.value.storage_blob_container_name, null) + } + } + dynamic "storage_blob_dead_letter_destination" { + for_each = try(var.settings.storage_blob_dead_letter_destination, null) != null ? [var.settings.storage_blob_dead_letter_destination] : [] + content { + storage_account_id = try(storage_blob_dead_letter_destination.value.storage_account_id, null) + storage_blob_container_name = try(storage_blob_dead_letter_destination.value.storage_blob_container_name, null) + } + } + dynamic "retry_policy" { + for_each = try(var.settings.retry_policy, null) != null ? [var.settings.retry_policy] : [] + content { + max_delivery_attempts = try(retry_policy.value.max_delivery_attempts, null) + event_time_to_live = try(retry_policy.value.event_time_to_live, null) + } + } + labels = try(var.settings.labels, null) + advanced_filtering_on_arrays_enabled = try(var.settings.advanced_filtering_on_arrays_enabled, null) +} diff --git a/modules/messaging/eventgrid/eventgrid_system_event_subscription/output.tf b/modules/messaging/eventgrid/eventgrid_system_event_subscription/output.tf new file mode 100644 index 0000000000..979f441b76 --- /dev/null +++ b/modules/messaging/eventgrid/eventgrid_system_event_subscription/output.tf @@ -0,0 +1,4 @@ +output "id" { + value = azurerm_eventgrid_system_topic_event_subscription.eges.id + description = "The ID of the EventGrid System Event Subscription." +} diff --git a/modules/messaging/eventgrid/eventgrid_system_event_subscription/variables.tf b/modules/messaging/eventgrid/eventgrid_system_event_subscription/variables.tf new file mode 100644 index 0000000000..b9514b9172 --- /dev/null +++ b/modules/messaging/eventgrid/eventgrid_system_event_subscription/variables.tf @@ -0,0 +1,18 @@ +variable "global_settings" { + description = "Global settings object" +} +variable "client_config" { + description = "Client configuration object." +} +variable "settings" { + description = "(Required) Used to handle passthrough paramenters." +} +variable "remote_objects" { + description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created." + default = {} +} +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = map(any) + default = {} +} diff --git a/modules/messaging/eventgrid/eventgrid_system_topic_event_subscription/output.tf b/modules/messaging/eventgrid/eventgrid_system_topic_event_subscription/output.tf index a269931f46..65b6b9b2c8 100644 --- a/modules/messaging/eventgrid/eventgrid_system_topic_event_subscription/output.tf +++ b/modules/messaging/eventgrid/eventgrid_system_topic_event_subscription/output.tf @@ -1,4 +1,4 @@ output "id" { value = azurerm_eventgrid_system_topic_event_subscription.egstes.id description = "The ID of the EventGrid Event Subscription." -} +} \ No newline at end of file diff --git a/modules/messaging/servicebus/namespace/main.tf b/modules/messaging/servicebus/namespace/main.tf index 2ae16770c0..048a981951 100644 --- a/modules/messaging/servicebus/namespace/main.tf +++ b/modules/messaging/servicebus/namespace/main.tf @@ -10,5 +10,5 @@ terraform { locals { location = can(var.settings.location) ? var.settings.location : var.remote_objects.resource_groups[try(var.settings.resource_group.lz_key, var.client_config.landingzone_key)][var.settings.resource_group.key].location resource_group_name = can(var.settings.resource_group_name) || can(var.settings.resource_group.name) ? try(var.settings.resource_group_name, var.settings.resource_group.name) : var.remote_objects.resource_groups[try(var.settings.resource_group.lz_key, var.client_config.landingzone_key)][var.settings.resource_group.key].name - base_tags = try(var.global_settings.inherit_tags, false) ? var.remote_objects.resource_groups[try(var.settings.resource_group.lz_key, var.client_config.landingzone_key)][var.settings.resource_group.key].tags : {} + tags = var.base_tags ? merge(var.global_settings.tags, try(var.resource_groups.tags, null), try(var.settings.tags, null)) : try(var.settings.tags, null) } \ No newline at end of file diff --git a/modules/messaging/servicebus/namespace/namespace.tf b/modules/messaging/servicebus/namespace/namespace.tf index 7a6094806e..18d1a7541f 100644 --- a/modules/messaging/servicebus/namespace/namespace.tf +++ b/modules/messaging/servicebus/namespace/namespace.tf @@ -1,5 +1,10 @@ -# azure_caf +locals { + # Need to update the tags if the environment tag is updated with the rover command line + caf_tags = can(var.settings.tags.caf_environment) || can(var.settings.tags.environment) ? merge(lookup(var.settings, "tags", {}), { "caf_environment" : var.global_settings.environment }) : {} +} + +# naming convention azure_caf resource "azurecaf_name" "namespace" { name = var.settings.name resource_type = "azurerm_servicebus_namespace" @@ -11,11 +16,12 @@ resource "azurecaf_name" "namespace" { } resource "azurerm_servicebus_namespace" "namespace" { - name = azurecaf_name.namespace.result - sku = var.settings.sku - capacity = try(var.settings.capacity, null) - zone_redundant = try(var.settings.zone_redundant, null) - tags = merge(local.base_tags, try(var.settings.tags, {})) - location = local.location - resource_group_name = local.resource_group_name + name = azurecaf_name.namespace.result + sku = var.settings.sku + capacity = try(var.settings.capacity, null) + zone_redundant = try(var.settings.zone_redundant, null) + tags = merge(try(var.settings.tags, null), local.caf_tags) + premium_messaging_partitions = try(var.settings.premium_messaging_partitions, null) + location = local.location + resource_group_name = local.resource_group_name } diff --git a/modules/messaging/servicebus/namespace/private_endpoints.tf b/modules/messaging/servicebus/namespace/private_endpoints.tf index 1d3d4b1c8b..9cbab5ee22 100644 --- a/modules/messaging/servicebus/namespace/private_endpoints.tf +++ b/modules/messaging/servicebus/namespace/private_endpoints.tf @@ -1,15 +1,17 @@ module "private_endpoint" { - source = "../../../networking/private_endpoint" - for_each = try(var.settings.private_endpoints, {}) + source = "../../../networking/private_endpoint" + #for_each = try(var.settings.private_endpoints, {}) + for_each = lookup(var.settings, "private_endpoints", {}) - base_tags = local.base_tags - client_config = var.client_config - global_settings = var.global_settings - location = local.location - name = each.value.name - private_dns = can(each.value.private_dns) ? var.remote_objects.private_dns : {} - resource_groups = var.resource_groups - resource_id = azurerm_servicebus_namespace.namespace.id - settings = each.value - subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.remote_objects.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + base_tags = var.base_tags + tags = local.tags + client_config = var.client_config + global_settings = var.global_settings + location = local.location + name = each.value.name + private_dns = can(each.value.private_dns) ? var.remote_objects.private_dns : {} + resource_group_name = local.resource_group_name + resource_id = azurerm_servicebus_namespace.namespace.id + settings = each.value + subnet_id = can(each.value.subnet_id) ? each.value.subnet_id : var.remote_objects.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id } diff --git a/modules/messaging/servicebus/namespace/variables.tf b/modules/messaging/servicebus/namespace/variables.tf index b2e6c4bc4f..bb45a8b066 100644 --- a/modules/messaging/servicebus/namespace/variables.tf +++ b/modules/messaging/servicebus/namespace/variables.tf @@ -15,3 +15,7 @@ variable "resource_groups" { description = "Combined resource groups object." default = {} } +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} \ No newline at end of file diff --git a/modules/messaging/signalr_service/output.tf b/modules/messaging/signalr_service/output.tf index 336e66e8d7..55f7108a04 100644 --- a/modules/messaging/signalr_service/output.tf +++ b/modules/messaging/signalr_service/output.tf @@ -8,6 +8,16 @@ output "name" { value = azurerm_signalr_service.signalr_service.name } +output "primary_connection_string" { + description = "The primary connection string of the SignalR Service" + value = azurerm_signalr_service.signalr_service.primary_connection_string +} + +output "secondary_connection_string" { + description = "The secondary connection string of the SignalR Service" + value = azurerm_signalr_service.signalr_service.secondary_connection_string +} + output "resource_group_name" { description = "The resource group name of the SignalR Service" value = local.resource_group_name diff --git a/modules/messaging/web_pubsub/private_endpoint.tf b/modules/messaging/web_pubsub/private_endpoint.tf index ae1d455277..9d95616fa1 100644 --- a/modules/messaging/web_pubsub/private_endpoint.tf +++ b/modules/messaging/web_pubsub/private_endpoint.tf @@ -8,7 +8,7 @@ module "private_endpoint" { global_settings = var.global_settings location = local.location name = each.value.name - private_dns = can(each.value.private_dns) ? var.remote_objects.private_dns : {} + private_dns = var.remote_objects.private_dns resource_groups = var.remote_objects.resource_groups resource_id = azurerm_web_pubsub.wps.id settings = each.value diff --git a/modules/monitoring/monitor_activity_log_alert/module.tf b/modules/monitoring/monitor_activity_log_alert/module.tf index a2b2ec515a..c5b5b8344d 100644 --- a/modules/monitoring/monitor_activity_log_alert/module.tf +++ b/modules/monitoring/monitor_activity_log_alert/module.tf @@ -35,7 +35,9 @@ resource "azurerm_monitor_activity_log_alert" "mala" { ) caller = try(criteria.value.caller, null) level = try(criteria.value.level, null) + levels = try(criteria.value.levels, null) status = try(criteria.value.status, null) + statuses = try(criteria.value.statuses, null) sub_status = try(criteria.value.sub_status, null) recommendation_type = try(criteria.value.recommendation_type, null) recommendation_category = try(criteria.value.recommendation_category, null) diff --git a/modules/networking/application_gateway/application_gateway.tf b/modules/networking/application_gateway/application_gateway.tf index a0cbfb6feb..100b2c6c52 100644 --- a/modules/networking/application_gateway/application_gateway.tf +++ b/modules/networking/application_gateway/application_gateway.tf @@ -193,6 +193,7 @@ resource "azurerm_application_gateway" "agw" { affinity_cookie_name = try(backend_http_settings.value.affinity_cookie_name, null) port = backend_http_settings.value.port protocol = backend_http_settings.value.protocol + path = try(backend_http_settings.value.path, null) request_timeout = try(backend_http_settings.value.request_timeout, 30) pick_host_name_from_backend_address = try(backend_http_settings.value.pick_host_name_from_backend_address, false) trusted_root_certificate_names = try(backend_http_settings.value.trusted_root_certificate_names, null) diff --git a/modules/networking/application_gateway/locals.networking.tf b/modules/networking/application_gateway/locals.networking.tf index 049ee1529b..687080544b 100644 --- a/modules/networking/application_gateway/locals.networking.tf +++ b/modules/networking/application_gateway/locals.networking.tf @@ -21,10 +21,6 @@ locals { try(var.vnets[var.settings.subnet.lz_key][var.settings.subnet.vnet_key], null) ), null) - gateway_virtual_subnets_remote = try(coalesce( - try(var.virtual_subnets[var.settings.subnet.lz_key][var.settings.subnet.subnet_key], null) - ), null) - private_vnet_remote = try(var.vnets[var.settings.front_end_ip_configurations.private.lz_key][var.settings.front_end_ip_configurations.private.vnet_key], null) public_vnet_remote = try(var.vnets[var.settings.front_end_ip_configurations.public.lz_key][var.settings.front_end_ip_configurations.public.vnet_key], null) @@ -32,7 +28,6 @@ locals { private_subnets_remote = try(var.virtual_subnets[var.settings.front_end_ip_configurations.private.lz_key], null) public_subnets_remote = try(var.virtual_subnets[var.settings.front_end_ip_configurations.public.lz_key], null) - gateway_vnet = merge(local.gateway_vnet_local, local.gateway_vnet_remote) private_vnet = merge(local.private_vnet_local, local.private_vnet_remote) public_vnet = merge(local.public_vnet_local, local.public_vnet_remote) @@ -45,12 +40,10 @@ locals { subnet_id = coalesce( try(local.gateway_vnet.subnets[var.settings.subnet_key].id, null), try(var.virtual_subnets[var.client_config.landingzone_key][var.settings.subnet_key].id, null), - try(var.virtual_subnets[var.client_config.landingzone_key][var.settings.subnet_key].id, null), try(var.settings.subnet_id, null) ) } - private = { subnet_id = try(coalesce( try(local.private_vnet.subnets[var.settings.front_end_ip_configurations.private.subnet_key].id, null), @@ -66,8 +59,6 @@ locals { ), null) - - } public = { subnet_id = try( diff --git a/modules/networking/application_gateway_application/scripts/set_resource.sh b/modules/networking/application_gateway_application/scripts/set_resource.sh index 06d2b425b1..a817762cd7 100755 --- a/modules/networking/application_gateway_application/scripts/set_resource.sh +++ b/modules/networking/application_gateway_application/scripts/set_resource.sh @@ -160,15 +160,35 @@ case "${RESOURCE}" in --name ${NAME} ${certfile}${keyvaultsecretid} ;; PATHMAP) - addresspool=$([ -z "${ADDRESS_POOL}" ] && echo "" || echo "--address-pool ${ADDRESS_POOL} --default-address-pool ${ADDRESS_POOL} ") - httpsettings=$([ -z "${HTTP_SETTINGS}" ] && echo "" || echo "--http-settings ${HTTP_SETTINGS} --default-http-settings ${HTTP_SETTINGS} ") + defaultaddresspool=$([ -z "${DEFAULT_ADDRESS_POOL}" ] && echo "" || echo "--default-address-pool ${DEFAULT_ADDRESS_POOL} ") + addresspool=$([ -z "${ADDRESS_POOL}" ] && echo "" || echo "--address-pool ${ADDRESS_POOL} ") + defaulthttpsettings=$([ -z "${DEFAULT_HTTP_SETTINGS}" ] && echo "" || echo "--default-http-settings ${DEFAULT_HTTP_SETTINGS} ") + httpsettings=$([ -z "${HTTP_SETTINGS}" ] && echo "" || echo "--http-settings ${HTTP_SETTINGS} ") + defaultredirectconfig=$([ -z "${DEFAULT_REDIRECT_CONFIG}" ] && echo "" || echo "--default-redirect-config ${DEFAULT_REDIRECT_CONFIG} ") redirectconfig=$([ -z "${REDIRECT_CONFIG}" ] && echo "" || echo "--redirect-config ${REDIRECT_CONFIG} ") + defaultrewriteruleset=$([ -z "${DEFAULT_REWRITE_RULE_SET}" ] && echo "" || echo "--default-rewrite-rule-set ${DEFAULT_REWRITE_RULE_SET} ") rewriteruleset=$([ -z "${REWRITE_RULE_SET}" ] && echo "" || echo "--rewrite-rule-set ${REWRITE_RULE_SET} ") rulename=$([ -z "${RULE_NAME}" ] && echo "" || echo "--rule-name ${RULE_NAME} ") wafpolicy=$([ -z "${WAF_POLICY}" ] && echo "" || echo "--waf-policy ${WAF_POLICY} ") - execute_with_backoff az network application-gateway url-path-map create -g ${RG_NAME} --gateway-name ${APPLICATION_GATEWAY_NAME} \ - -n ${NAME} --paths ${PATHS} ${addresspool}${httpsettings}${redirectconfig}${rewriteruleset}${rulename}${wafpolicy} + # Check if pathmap already created + output=$(az network application-gateway url-path-map show -g ${RG_NAME} --gateway-name ${APPLICATION_GATEWAY_NAME} -n ${NAME} 2> error.txt) + + # Check if the error file contains the ResourceNotFoundError message + if grep -q "ResourceNotFoundError" error.txt; then + execute_with_backoff az network application-gateway url-path-map create -g ${RG_NAME} --gateway-name ${APPLICATION_GATEWAY_NAME} \ + -n ${NAME} --paths ${PATHS} ${defaultaddresspool}${addresspool}${defaulthttpsettings}${httpsettings} \ + ${defaultredirectconfig}${redirectconfig}${defaultrewriteruleset}${rewriteruleset}${rulename}${wafpolicy} + else + execute_with_backoff az network application-gateway url-path-map update -g ${RG_NAME} --gateway-name ${APPLICATION_GATEWAY_NAME} \ + -n ${NAME} ${defaultaddresspool}${defaulthttpsettings}${defaultredirectconfig}${defaultrewriteruleset} + execute_with_backoff az network application-gateway url-path-map rule create -g ${RG_NAME} --gateway-name ${APPLICATION_GATEWAY_NAME} \ + -n ${RULE_NAME} --path-map-name ${NAME} --paths ${PATHS} ${addresspool}${httpsettings}${redirectconfig}${rewriteruleset}${wafpolicy} + fi + + # Remove the error file + rm error.txt + ;; PATHRULE) addresspool=$([ -z "${ADDRESS_POOL}" ] && echo "" || echo "--address-pool ${ADDRESS_POOL} ") @@ -215,9 +235,9 @@ case "${RESOURCE}" in ignorecase=$([ -z "${IGNORE_CASE}" ] && echo "" || echo "--ignore-case ${IGNORE_CASE} ") negate=$([ -z "${NEGATE}" ] && echo "" || echo "--negate ${NEGATE} ") pattern=$([ -z "${PATTERN}" ] && echo "" || echo "--pattern ${PATTERN} ") - + execute_with_backoff az network application-gateway rewrite-rule condition create -g ${RG_NAME} \ --gateway-name ${APPLICATION_GATEWAY_NAME} --variable ${VARIABLE} --rule-set-name ${RULE_SET_NAME} --rule-name ${RULE_NAME}\ ${ignorecase} ${negate} ${pattern} ;; -esac \ No newline at end of file +esac diff --git a/modules/networking/application_gateway_application/url_path_map.tf b/modules/networking/application_gateway_application/url_path_map.tf index 6a10a51b2d..c3b0a94626 100644 --- a/modules/networking/application_gateway_application/url_path_map.tf +++ b/modules/networking/application_gateway_application/url_path_map.tf @@ -20,9 +20,13 @@ resource "null_resource" "set_url_path_map" { APPLICATION_GATEWAY_ID = var.application_gateway.id NAME = each.value.name PATHS = each.value.paths + DEFAULT_ADDRESS_POOL = try(var.settings.backend_pools[each.value.default_backend_pool_key].name, var.settings.backend_pools[each.value.backend_pool_key].name) ADDRESS_POOL = var.settings.backend_pools[each.value.backend_pool_key].name + DEFAULT_HTTP_SETTINGS = try(var.settings.http_settings[each.value.default_http_settings_key].name, var.settings.http_settings[each.value.http_settings_key].name) HTTP_SETTINGS = var.settings.http_settings[each.value.http_settings_key].name + DEFAULT_REDIRECT_CONFIG = try(each.value.default_redirect_config, each.value.redirect_config, null) REDIRECT_CONFIG = try(each.value.redirect_config, null) + DEFAULT_REWRITE_RULE_SET = try(var.settings.rewrite_rule_sets[each.value.default_rewrite_rule_set_key].name, var.settings.rewrite_rule_sets[each.value.rewrite_rule_set_key].name, null) REWRITE_RULE_SET = try(var.settings.rewrite_rule_sets[each.value.rewrite_rule_set_key].name, null) RULE_NAME = try(each.value.rule_name, null) WAF_POLICY = try(each.value.waf_policy, null) diff --git a/modules/networking/application_gateway_waf_policies/waf_policy.tf b/modules/networking/application_gateway_waf_policies/waf_policy.tf index ab0da3fa8a..ffad0c8823 100644 --- a/modules/networking/application_gateway_waf_policies/waf_policy.tf +++ b/modules/networking/application_gateway_waf_policies/waf_policy.tf @@ -83,7 +83,16 @@ resource "azurerm_web_application_firewall_policy" "wafpolicy" { for_each = try(managed_rule_set.value.rule_group_override, {}) content { rule_group_name = rule_group_override.value.rule_group_name - disabled_rules = try(rule_group_override.value.disabled_rules, null) + dynamic "rule" { + for_each = { + for key, value in try(rule_group_override.value.rules, {}) : key => value + } + content { + id = rule.value.id + enabled = try(rule.value.enabled, null) + action = try(rule.value.action, null) + } + } } } } diff --git a/modules/networking/network_connection_monitor/module.tf b/modules/networking/network_connection_monitor/module.tf index ad7ad397fd..f627b2e89f 100644 --- a/modules/networking/network_connection_monitor/module.tf +++ b/modules/networking/network_connection_monitor/module.tf @@ -126,11 +126,15 @@ locals { key => var.combined_objects_log_analytics[try(value.lz_key, var.client_config.landingzone_key)][value.key].id if try(value.key, null) != null } + workspace_id_from_diagnostics = {for key, value in var.diagnostics.log_analytics : + key => value.id + if try(value.diagnostic_log_destination_key, null) != null + } workspace_from_ids = { for key, value in var.settings.output_workspaces : key => value.id if try(value.id, null) != null } - workspace_ids = concat(values(local.workspace_ids_from_keys), values(local.workspace_from_ids)) + workspace_ids = concat(values(local.workspace_ids_from_keys), values(local.workspace_from_ids), values(local.workspace_id_from_diagnostics)) name = var.network_watcher_name != null ? var.network_watcher_name : format("NetworkWatcher_%s", var.location) resource_group_name = var.network_watcher_resource_group_name != null ? var.network_watcher_resource_group_name : "NetworkWatcherRG" diff --git a/modules/networking/network_connection_monitor/variables.tf b/modules/networking/network_connection_monitor/variables.tf index 872b685bac..c072e2c9e7 100644 --- a/modules/networking/network_connection_monitor/variables.tf +++ b/modules/networking/network_connection_monitor/variables.tf @@ -32,7 +32,9 @@ variable "network_watcher_id" { default = null } variable "combined_objects_log_analytics" {} - +variable "diagnostics" { + default = {} +} variable "endpoint_objects" { description = "map of possible endpoint objects from caf" diff --git a/modules/networking/private-dns/output.tf b/modules/networking/private-dns/output.tf index f77ac5d4b3..46bcce2667 100644 --- a/modules/networking/private-dns/output.tf +++ b/modules/networking/private-dns/output.tf @@ -1,18 +1,43 @@ output "id" { value = azurerm_private_dns_zone.private_dns.id - } output "name" { value = azurerm_private_dns_zone.private_dns.name - } output "resource_group_name" { value = local.resource_group_name - } output "base_tags" { value = local.tags +} + +output "a" { + value = azurerm_private_dns_a_record.a_records +} + +output "aaaa" { + value = azurerm_private_dns_aaaa_record.aaaa_records +} + +output "cname" { + value = azurerm_private_dns_cname_record.cname_records +} + +output "mx" { + value = azurerm_private_dns_mx_record.mx_records +} + +output "ptr" { + value = azurerm_private_dns_ptr_record.ptr_records +} + +output "srv" { + value = azurerm_private_dns_srv_record.srv_records +} + +output "txt" { + value = azurerm_private_dns_txt_record.txt_records } \ No newline at end of file diff --git a/modules/networking/private_endpoint/main.tf b/modules/networking/private_endpoint/main.tf index c9a409e81e..b8af5addcc 100644 --- a/modules/networking/private_endpoint/main.tf +++ b/modules/networking/private_endpoint/main.tf @@ -16,6 +16,6 @@ locals { location = can(var.location) || can(var.settings.region) ? try(var.location, var.global_settings.regions[var.settings.region]) : var.resource_groups[try(var.settings.resource_group.lz_key, var.settings.lz_key, var.client_config.landingzone_key)][try(var.settings.resource_group.key, var.settings.resource_group_key)].location - resource_group_name = can(var.resource_group_name) ? var.resource_group_name : var.resource_groups[try(var.settings.resource_group.lz_key, var.settings.lz_key, var.client_config.landingzone_key)][try(var.settings.resource_group.key, var.settings.resource_group_key)].name + resource_group_name = can(var.resource_group_name) && var.resource_group_name != null ? var.resource_group_name : var.resource_groups[try(var.settings.resource_group.lz_key, var.settings.lz_key, var.client_config.landingzone_key)][try(var.settings.resource_group.key, var.settings.resource_group_key)].name } diff --git a/modules/networking/private_endpoint/private_endpoint.tf b/modules/networking/private_endpoint/private_endpoint.tf index 199478464b..d74f19c6bd 100644 --- a/modules/networking/private_endpoint/private_endpoint.tf +++ b/modules/networking/private_endpoint/private_endpoint.tf @@ -54,3 +54,12 @@ resource "azurerm_private_endpoint" "pep" { } } + +resource "time_sleep" "delay" { + count = can(lookup(var.settings, var.settings.delay_time_after_creation, false)) ? 1 : 0 + depends_on = [azurerm_private_endpoint.pep] + create_duration = var.settings.delay_time_after_creation + lifecycle { + replace_triggered_by = [azurerm_private_endpoint.pep] + } +} \ No newline at end of file diff --git a/modules/networking/private_links/endpoints/subnet/cognitive_services_account.tf b/modules/networking/private_links/endpoints/subnet/cognitive_services_account.tf new file mode 100644 index 0000000000..517c4a80b2 --- /dev/null +++ b/modules/networking/private_links/endpoints/subnet/cognitive_services_account.tf @@ -0,0 +1,36 @@ +module "cognitive_services_account" { + source = "../private_endpoint" + for_each = { + for key, value in try(var.private_endpoints.cognitive_services_account, {}) : key => value + if can(value.lz_key) == false + } + global_settings = var.global_settings + client_config = var.client_config + settings = each.value + resource_id = can(each.value.resource_id) ? each.value.resource_id : var.remote_objects.cognitive_services_accounts[var.client_config.landingzone_key][try(each.value.key, each.key)].id + subresource_names = toset(try(each.value.private_service_connection.subresource_names, ["account"])) + subnet_id = var.subnet_id + private_dns = var.private_dns + name = try(each.value.name, each.key) + resource_group_name = can(each.value.resource_group_key) ? var.resource_groups[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.resource_group_key].name : var.vnet_resource_group_name + location = var.vnet_location # The private endpoint must be deployed in the same region as the virtual network. + base_tags = var.base_tags +} +module "cognitive_services_account_remote" { + source = "../private_endpoint" + for_each = { + for key, value in try(var.private_endpoints.cognitive_services_account, {}) : key => value + if can(value.lz_key) + } + global_settings = var.global_settings + client_config = var.client_config + settings = each.value + resource_id = can(each.value.key) ? var.remote_objects.cognitive_services_accounts[each.value.lz_key][each.value.key].id : var.remote_objects.cognitive_services_accounts[each.value.lz_key][each.key].id + subresource_names = toset(try(each.value.private_service_connection.subresource_names, ["account"])) + subnet_id = var.subnet_id + private_dns = var.private_dns + name = try(each.value.name, each.key) + resource_group_name = can(each.value.resource_group_key) ? var.resource_groups[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.resource_group_key].name : var.vnet_resource_group_name + location = var.vnet_location # The private endpoint must be deployed in the same region as the virtual network. + base_tags = var.base_tags +} \ No newline at end of file diff --git a/modules/networking/public_ip_addresses/variables.tf b/modules/networking/public_ip_addresses/variables.tf index 260f56de25..24a16437a2 100644 --- a/modules/networking/public_ip_addresses/variables.tf +++ b/modules/networking/public_ip_addresses/variables.tf @@ -70,7 +70,7 @@ variable "generate_domain_name_label" { variable "reverse_fqdn" { description = "(Optional) A fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN." - type = bool + type = string default = null } diff --git a/modules/networking/virtual_wan/variables.tf b/modules/networking/virtual_wan/variables.tf index 8248462fec..425fb35aff 100644 --- a/modules/networking/virtual_wan/variables.tf +++ b/modules/networking/virtual_wan/variables.tf @@ -23,6 +23,9 @@ variable "virtual_networks" { variable "public_ip_addresses" { description = "Combined object for public ip addresses" } +variable "keyvaults" { + description = "Combined object for keyvaults" +} variable "client_config" { -} \ No newline at end of file +} diff --git a/modules/networking/virtual_wan/virtual_hub/output.tf b/modules/networking/virtual_wan/virtual_hub/output.tf index e80d4cfd39..df4496377a 100644 --- a/modules/networking/virtual_wan/virtual_hub/output.tf +++ b/modules/networking/virtual_wan/virtual_hub/output.tf @@ -37,4 +37,9 @@ output "p2s_gateway" { output "resource_group_name" { description = "Name of the resource group where the resources are deployed." value = var.resource_group_name -} \ No newline at end of file +} + +output "default_route_table_id" { + description = "Resource ID of the Virtual Hub Default Route Table" + value = azurerm_virtual_hub.vwan_hub.default_route_table_id +} diff --git a/modules/networking/virtual_wan/virtual_hub/point_to_site_gateway.tf b/modules/networking/virtual_wan/virtual_hub/point_to_site_gateway.tf index bdf1bafb6d..01ecfdae01 100644 --- a/modules/networking/virtual_wan/virtual_hub/point_to_site_gateway.tf +++ b/modules/networking/virtual_wan/virtual_hub/point_to_site_gateway.tf @@ -64,7 +64,7 @@ resource "azurerm_vpn_server_configuration" "p2s_configuration" { for_each = contains(var.virtual_hub_config.p2s_config.server_config.vpn_authentication_types, "Certificate") ? [1] : [] content { name = var.virtual_hub_config.p2s_config.server_config.client_root_certificate.name - public_cert_data = var.virtual_hub_config.p2s_config.server_config.client_root_certificate.public_cert_data + public_cert_data = can(var.virtual_hub_config.p2s_config.server_config.client_root_certificate.keyvault_secret) ? replace(replace(data.azurerm_key_vault_secret.vpn_client_configuration_root_certificate[0].value, "-----BEGIN CERTIFICATE-----", ""), "-----END CERTIFICATE-----", "") : var.virtual_hub_config.p2s_config.server_config.client_root_certificate.public_cert_data } } @@ -72,9 +72,17 @@ resource "azurerm_vpn_server_configuration" "p2s_configuration" { for_each = can(var.virtual_hub_config.p2s_config.server_config.azure_active_directory_authentication) ? [1] : [] content { audience = var.virtual_hub_config.p2s_config.server_config.azure_active_directory_authentication.audience - tenant = var.virtual_hub_config.p2s_config.server_config.azure_active_directory_authentication.tenant - issuer = var.virtual_hub_config.p2s_config.server_config.azure_active_directory_authentication.issuer - } + tenant = var.virtual_hub_config.p2s_config.server_config.azure_active_directory_authentication.tenant + issuer = var.virtual_hub_config.p2s_config.server_config.azure_active_directory_authentication.issuer + } } } +data "azurerm_key_vault_secret" "vpn_client_configuration_root_certificate" { + count = try(var.virtual_hub_config.p2s_config.server_config.client_root_certificate.keyvault_secret, null) != null ? 1 : 0 + name = var.virtual_hub_config.p2s_config.server_config.client_root_certificate.keyvault_secret.secret_name + key_vault_id = try( + var.virtual_hub_config.p2s_config.server_config.client_root_certificate.keyvault_secret.key_vault_id, + var.keyvaults[try(var.virtual_hub_config.p2s_config.server_config.client_root_certificate.keyvault_secret.lz_key, var.client_config.landingzone_key)][var.virtual_hub_config.p2s_config.server_config.client_root_certificate.keyvault_secret.keyvault_key].id + ) +} diff --git a/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf b/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf index 0014169dea..f4d6655594 100644 --- a/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf +++ b/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf @@ -22,8 +22,9 @@ resource "azurerm_vpn_gateway" "s2s_gateway" { tags = local.tags virtual_hub_id = azurerm_virtual_hub.vwan_hub.id - scale_unit = var.virtual_hub_config.s2s_config.scale_unit - routing_preference = try(var.virtual_hub_config.s2s_config.routing_preference, "Microsoft Network") + scale_unit = var.virtual_hub_config.s2s_config.scale_unit + routing_preference = try(var.virtual_hub_config.s2s_config.routing_preference, "Microsoft Network") + bgp_route_translation_for_nat_enabled = try(var.virtual_hub_config.s2s_config.bgp_route_translation_for_nat_enabled, false) dynamic "bgp_settings" { for_each = try(var.virtual_hub_config.s2s_config.bgp_settings, null) == null ? [] : [1] @@ -55,4 +56,4 @@ resource "azurerm_vpn_gateway" "s2s_gateway" { create = "120m" delete = "120m" } -} \ No newline at end of file +} diff --git a/modules/networking/virtual_wan/virtual_hub/variables.tf b/modules/networking/virtual_wan/virtual_hub/variables.tf index 10fc694b91..f5d9fae1a8 100644 --- a/modules/networking/virtual_wan/virtual_hub/variables.tf +++ b/modules/networking/virtual_wan/virtual_hub/variables.tf @@ -45,6 +45,9 @@ variable "virtual_networks" { variable "public_ip_addresses" { description = "Combined object for public ip addresses" } +variable "keyvaults" { + description = "Combined object for keyvaults" +} variable "client_config" { -} \ No newline at end of file +} diff --git a/modules/networking/virtual_wan/virtual_hub/virtual_hub.tf b/modules/networking/virtual_wan/virtual_hub/virtual_hub.tf index 81ddefb39e..bb9d7eeb9b 100644 --- a/modules/networking/virtual_wan/virtual_hub/virtual_hub.tf +++ b/modules/networking/virtual_wan/virtual_hub/virtual_hub.tf @@ -11,14 +11,15 @@ resource "azurecaf_name" "vwan_hub" { ## creates a virtual hub in the region resource "azurerm_virtual_hub" "vwan_hub" { - name = azurecaf_name.vwan_hub.result - resource_group_name = var.resource_group_name - location = var.location - virtual_wan_id = var.vwan_id - sku = try(var.virtual_hub_config.sku, null) - address_prefix = try(var.virtual_hub_config.hub_address_prefix, null) - hub_routing_preference = try(var.virtual_hub_config.hub_routing_preference, null) - tags = local.tags + name = azurecaf_name.vwan_hub.result + resource_group_name = var.resource_group_name + location = var.location + virtual_wan_id = var.vwan_id + sku = try(var.virtual_hub_config.sku, null) + address_prefix = try(var.virtual_hub_config.hub_address_prefix, null) + hub_routing_preference = try(var.virtual_hub_config.hub_routing_preference, null) + virtual_router_auto_scale_min_capacity = try(var.virtual_hub_config.virtual_router_auto_scale_min_capacity, null) + tags = local.tags dynamic "route" { for_each = try(var.virtual_hub_config.routes, {}) diff --git a/modules/networking/virtual_wan/virtual_wan.tf b/modules/networking/virtual_wan/virtual_wan.tf index f8d625ee83..11cb9a2bbd 100644 --- a/modules/networking/virtual_wan/virtual_wan.tf +++ b/modules/networking/virtual_wan/virtual_wan.tf @@ -34,5 +34,6 @@ module "hubs" { tags = merge(try(each.value.tags, null), local.tags) virtual_hub_config = each.value virtual_networks = var.virtual_networks + keyvaults = var.keyvaults vwan_id = azurerm_virtual_wan.vwan.id } diff --git a/modules/networking/vpn_gateway_connection/module.tf b/modules/networking/vpn_gateway_connection/module.tf index 09a70a0a6e..93396a2354 100644 --- a/modules/networking/vpn_gateway_connection/module.tf +++ b/modules/networking/vpn_gateway_connection/module.tf @@ -30,6 +30,18 @@ resource "azurerm_vpn_gateway_connection" "vpn_gateway_connection" { shared_key = try(vpn_link.value.shared_key, null) local_azure_ip_address_enabled = try(vpn_link.value.local_azure_ip_address_enabled, null) policy_based_traffic_selector_enabled = try(vpn_link.value.policy_based_traffic_selector_enabled, null) + egress_nat_rule_ids = try(compact( + [ + for key, value in vpn_link.value.egress_nat_rules : + can(value.id) ? value.id : var.nat_rules[try(value.lz_key, var.client_config.landingzone_key)][value.key].id + ] + ), []) + ingress_nat_rule_ids = try(compact( + [ + for key, value in vpn_link.value.ingress_nat_rules : + can(value.id) ? value.id : var.nat_rules[try(value.lz_key, var.client_config.landingzone_key)][value.key].id + ] + ), []) vpn_site_link_id = coalesce( try(var.vpn_sites[try(var.settings.vpn_site.lz_key, var.client_config.landingzone_key)][var.settings.vpn_site.key].vpn_site.link[vpn_link.value.link_index].id, null), @@ -55,19 +67,27 @@ resource "azurerm_vpn_gateway_connection" "vpn_gateway_connection" { dynamic "routing" { for_each = can(var.settings.routing) ? [var.settings.routing] : [] content { - associated_route_table = can(routing.value.associated_route_table.key) ? var.route_tables[try(routing.value.associated_route_table.lz_key, var.client_config.landingzone_key)][routing.value.associated_route_table.key].id : try(routing.value.associated_route_table.id, null) + associated_route_table = can(routing.value.associated_route_table.key) ? var.route_tables[try(routing.value.associated_route_table.lz_key, var.client_config.landingzone_key)][routing.value.associated_route_table.key].id : try(routing.value.associated_route_table.id, try(var.default_route_table_id, null)) dynamic "propagated_route_table" { # propagated_route_tables kept to smooth the migration to azurerm 3.0 - for_each = can(routing.value.propagated_route_table) ? routing.value.propagated_route_table : routing.value.propagated_route_tables - + for_each = can(routing.value.propagated_route_table) ? [routing.value.propagated_route_table] : [] content { - route_table_ids = can(propagated_route_table.value.id) ? propagated_route_table.value.id : var.route_tables[try(propagated_route_table.value.lz_key, var.client_config.landingzone_key)][propagated_route_table.value.key].id + route_table_ids = compact( + [ + for key, value in propagated_route_table.value.route_tables : + can(value.id) ? value.id : var.route_tables[try(value.lz_key, var.client_config.landingzone_key)][value.key].id + ] + ) - labels = try(propagated_route_table.value.labels, null) + labels = flatten( + [ + for key, value in propagated_route_table.value.route_tables : + can(value.labels) ? value.labels : [] + ] + ) } } - } } } diff --git a/modules/networking/vpn_gateway_connection/variables.tf b/modules/networking/vpn_gateway_connection/variables.tf index abb3037c16..a462584483 100644 --- a/modules/networking/vpn_gateway_connection/variables.tf +++ b/modules/networking/vpn_gateway_connection/variables.tf @@ -6,3 +6,5 @@ variable "vpn_gateway_id" {} variable "vpn_sites" {} variable "client_config" {} variable "route_tables" {} +variable "nat_rules" {} +variable "default_route_table_id" {} diff --git a/modules/networking/vpn_gateway_nat_rule/main.tf b/modules/networking/vpn_gateway_nat_rule/main.tf new file mode 100644 index 0000000000..1fbfa06797 --- /dev/null +++ b/modules/networking/vpn_gateway_nat_rule/main.tf @@ -0,0 +1,7 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } +} diff --git a/modules/networking/vpn_gateway_nat_rule/module.tf b/modules/networking/vpn_gateway_nat_rule/module.tf new file mode 100644 index 0000000000..cdd05f3523 --- /dev/null +++ b/modules/networking/vpn_gateway_nat_rule/module.tf @@ -0,0 +1,27 @@ +resource "azurerm_vpn_gateway_nat_rule" "vpn_gateway_nat_rule" { + name = var.settings.name + resource_group_name = var.resource_group_name + vpn_gateway_id = var.vpn_gateway_id + ip_configuration_id = try(var.settings.ip_configuration_id, null) + + mode = var.settings.mode + type = var.settings.type + + dynamic "external_mapping" { + for_each = try(var.settings.external_mapping, {}) + + content { + address_space = external_mapping.value.address_space + port_range = try(external_mapping.value.port_range, null) + } + } + + dynamic "internal_mapping" { + for_each = try(var.settings.internal_mapping, {}) + + content { + address_space = internal_mapping.value.address_space + port_range = try(internal_mapping.value.port_range, null) + } + } +} diff --git a/modules/networking/vpn_gateway_nat_rule/output.tf b/modules/networking/vpn_gateway_nat_rule/output.tf new file mode 100644 index 0000000000..ded382e112 --- /dev/null +++ b/modules/networking/vpn_gateway_nat_rule/output.tf @@ -0,0 +1,4 @@ +output "id" { + value = azurerm_vpn_gateway_nat_rule.vpn_gateway_nat_rule.id + description = "Resource ID of the VPN Gateway NAT rule" +} diff --git a/modules/networking/vpn_gateway_nat_rule/variables.tf b/modules/networking/vpn_gateway_nat_rule/variables.tf new file mode 100644 index 0000000000..0a5a9df7e3 --- /dev/null +++ b/modules/networking/vpn_gateway_nat_rule/variables.tf @@ -0,0 +1,10 @@ +variable "settings" {} +variable "global_settings" { + description = "Global settings object (see module README.md)" +} +variable "vpn_gateway_id" {} +variable "resource_group_name" { + description = "(Required) The name of the resource group where to create the resource." + type = string +} +variable "client_config" {} diff --git a/modules/recovery_vault/backup_policies_vm.tf b/modules/recovery_vault/backup_policies_vm.tf index b8260ca75a..da18ae313a 100644 --- a/modules/recovery_vault/backup_policies_vm.tf +++ b/modules/recovery_vault/backup_policies_vm.tf @@ -9,14 +9,17 @@ resource "azurerm_backup_policy_vm" "vm" { recovery_vault_name = azurerm_recovery_services_vault.asr.name instant_restore_retention_days = try(each.value.instant_restore_retention_days, null) timezone = try(each.value.timezone, null) + policy_type = try(each.value.policy_type, null) dynamic "backup" { for_each = lookup(each.value, "backup", null) == null ? [] : [1] content { - frequency = lookup(each.value.backup, "frequency", null) - time = each.value.backup.time - weekdays = lookup(each.value.backup, "weekdays", null) + frequency = lookup(each.value.backup, "frequency", null) + hour_interval = lookup(each.value.backup, "hour_interval", null) + hour_duration = lookup(each.value.backup, "hour_duration", null) + time = each.value.backup.time + weekdays = lookup(each.value.backup, "weekdays", null) } } diff --git a/modules/recovery_vault/backup_policies_vm_workload.tf b/modules/recovery_vault/backup_policies_vm_workload.tf new file mode 100644 index 0000000000..83520e77c0 --- /dev/null +++ b/modules/recovery_vault/backup_policies_vm_workload.tf @@ -0,0 +1,78 @@ +resource "azurerm_backup_policy_vm_workload" "vm_workload" { + for_each = try(var.settings.backup_policies.vm_workloads, {}) + + name = each.value.name + resource_group_name = local.resource_group_name + recovery_vault_name = azurerm_recovery_services_vault.asr.name + workload_type = each.value.workload_type + + settings { + time_zone = each.value.timezone + compression_enabled = each.value.compression_enabled + } + + dynamic "protection_policy" { + for_each = each.value.protection_policies + + content { + policy_type = protection_policy.value.policy_type + + backup { + frequency = try(protection_policy.value.backup.frequency, null) + frequency_in_minutes = try(protection_policy.value.backup.frequency_in_minutes, null) + time = try(protection_policy.value.backup.time, null) + weekdays = try(protection_policy.value.backup.weekdays, null) + } + + dynamic "retention_daily" { + for_each = lookup(protection_policy.value, "retention_daily", null) == null ? [] : [1] + + content { + count = protection_policy.value.retention_daily.count + } + } + + dynamic "retention_weekly" { + for_each = lookup(protection_policy.value, "retention_weekly", null) == null ? [] : [1] + + content { + count = protection_policy.value.retention_weekly.count + weekdays = protection_policy.value.retention_weekly.weekdays + } + } + + dynamic "retention_monthly" { + for_each = lookup(protection_policy.value, "retention_monthly", null) == null ? [] : [1] + + content { + count = protection_policy.value.retention_monthly.count + format_type = protection_policy.value.retention_monthly.format_type + monthdays = try(protection_policy.value.retention_monthly.monthdays, null) + weekdays = try(protection_policy.value.retention_monthly.weekdays, null) + weeks = try(protection_policy.value.retention_monthly.weeks, null) + } + } + + dynamic "retention_yearly" { + for_each = lookup(protection_policy.value, "retention_yearly", null) == null ? [] : [1] + + content { + count = protection_policy.value.retention_yearly.count + format_type = protection_policy.value.retention_yearly.format_type + months = protection_policy.value.retention_yearly.months + monthdays = try(protection_policy.value.retention_yearly.monthdays, null) + weekdays = try(protection_policy.value.retention_yearly.weekdays, null) + weeks = try(protection_policy.value.retention_yearly.weeks, null) + } + } + + dynamic "simple_retention" { + for_each = lookup(protection_policy.value, "simple_retention", null) == null ? [] : [1] + + content { + count = protection_policy.value.simple_retention.count + } + } + } + } +} diff --git a/modules/recovery_vault/diagnostics.tf b/modules/recovery_vault/diagnostics.tf index 0caaba4e20..50f56b34e9 100644 --- a/modules/recovery_vault/diagnostics.tf +++ b/modules/recovery_vault/diagnostics.tf @@ -1,6 +1,7 @@ module "diagnostics" { source = "../diagnostics" + count = var.diagnostic_profiles == null ? 0 : 1 resource_id = azurerm_recovery_services_vault.asr.id resource_location = local.location diff --git a/modules/recovery_vault/outputs.tf b/modules/recovery_vault/outputs.tf index 936572ebe9..4213ffee07 100644 --- a/modules/recovery_vault/outputs.tf +++ b/modules/recovery_vault/outputs.tf @@ -16,6 +16,7 @@ output "backup_policies" { value = { virtual_machines = azurerm_backup_policy_vm.vm file_shares = azurerm_backup_policy_file_share.fs + vm_workloads = azurerm_backup_policy_vm_workload.vm_workload } } diff --git a/modules/recovery_vault/recovery_vault.tf b/modules/recovery_vault/recovery_vault.tf index 4d73f65dba..eecd16a3ac 100644 --- a/modules/recovery_vault/recovery_vault.tf +++ b/modules/recovery_vault/recovery_vault.tf @@ -12,13 +12,15 @@ resource "azurecaf_name" "asr_rg_vault" { } resource "azurerm_recovery_services_vault" "asr" { - name = azurecaf_name.asr_rg_vault.result - location = local.location - resource_group_name = local.resource_group_name - sku = "Standard" - tags = merge(local.tags, try(var.settings.tags, null)) - soft_delete_enabled = try(var.settings.soft_delete_enabled, true) - storage_mode_type = try(var.settings.storage_mode_type, "GeoRedundant") + name = azurecaf_name.asr_rg_vault.result + location = local.location + resource_group_name = local.resource_group_name + sku = "Standard" + tags = merge(local.tags, try(var.settings.tags, null)) + soft_delete_enabled = try(var.settings.soft_delete_enabled, true) + storage_mode_type = try(var.settings.storage_mode_type, "GeoRedundant") + public_network_access_enabled = try(var.settings.public_network_access_enabled, null) + immutability = try(var.settings.immutability, null) identity { type = "SystemAssigned" diff --git a/modules/recovery_vault/variables.tf b/modules/recovery_vault/variables.tf index 5f4359b7e4..aeae2a877a 100644 --- a/modules/recovery_vault/variables.tf +++ b/modules/recovery_vault/variables.tf @@ -4,7 +4,14 @@ variable "global_settings" { description = "Global settings object (see module README.md)" } -variable "diagnostics" {} +variable "diagnostic_profiles" { + default = {} +} + +variable "diagnostics" { + default = null +} + variable "private_endpoints" {} variable "vnets" {} variable "client_config" { diff --git a/modules/roles/custom_roles/module.tf b/modules/roles/custom_roles/module.tf index afcc8b8aa9..94a0a1747f 100644 --- a/modules/roles/custom_roles/module.tf +++ b/modules/roles/custom_roles/module.tf @@ -1,13 +1,17 @@ +locals { + global_settings = merge(var.global_settings, try(var.custom_role.global_settings, {})) +} + resource "azurecaf_name" "custom_role" { name = var.custom_role.name resource_type = "azurerm_resource_group" #TODO: need to be changed to appropriate resource (no caf reference for now) - prefixes = var.global_settings.prefixes - random_length = var.global_settings.random_length + prefixes = local.global_settings.prefixes + random_length = local.global_settings.random_length clean_input = true - passthrough = var.global_settings.passthrough - use_slug = var.global_settings.use_slug + passthrough = local.global_settings.passthrough + use_slug = local.global_settings.use_slug } resource "azurerm_role_definition" "custom_role" { diff --git a/modules/search_service/main.tf b/modules/search_service/main.tf new file mode 100644 index 0000000000..50f65e1e7d --- /dev/null +++ b/modules/search_service/main.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + azurecaf = { + source = "aztfmod/azurecaf" + } + } + +} + +locals { + tags = var.base_tags ? merge( + var.global_settings.tags, + try(var.resource_group.tags, null), + try(var.settings.tags, null) + ) : try(var.settings.tags, null) + + location = coalesce(var.location, var.resource_group.location) + resource_group_name = coalesce(var.resource_group_name, var.resource_group.name) +} \ No newline at end of file diff --git a/modules/search_service/output.tf b/modules/search_service/output.tf new file mode 100644 index 0000000000..9b89f354c0 --- /dev/null +++ b/modules/search_service/output.tf @@ -0,0 +1,16 @@ +output "name" { + value = azurerm_search_service.search_service.name +} + +output "location" { + value = azurerm_search_service.search_service.location +} + +output "tags" { + value = azurerm_search_service.search_service.tags + +} + +output "id" { + value = azurerm_search_service.search_service.id +} \ No newline at end of file diff --git a/modules/search_service/private_endpoint.tf b/modules/search_service/private_endpoint.tf new file mode 100644 index 0000000000..66838a9993 --- /dev/null +++ b/modules/search_service/private_endpoint.tf @@ -0,0 +1,18 @@ +module "private_endpoint" { + source = "../networking/private_endpoint" + for_each = var.private_endpoints + + resource_id = azurerm_search_service.search_service.id + name = each.value.name + location = local.location + resource_group_name = local.resource_group_name + subnet_id = can(each.value.subnet_id) || can(each.value.virtual_subnet_key) ? try(each.value.subnet_id, var.virtual_subnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.virtual_subnet_key].id) : var.vnets[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.vnet_key].subnets[each.value.subnet_key].id + settings = each.value + global_settings = var.global_settings + tags = local.tags + base_tags = var.base_tags + private_dns = var.private_dns + client_config = var.client_config +} + + diff --git a/modules/search_service/searchservice.tf b/modules/search_service/searchservice.tf new file mode 100644 index 0000000000..0a9efbb00a --- /dev/null +++ b/modules/search_service/searchservice.tf @@ -0,0 +1,32 @@ + +resource "azurecaf_name" "service" { + name = var.settings.name + prefixes = var.global_settings.prefixes + resource_type = "azurerm_search_service" + random_length = var.global_settings.random_length + clean_input = true + passthrough = var.global_settings.passthrough + use_slug = var.global_settings.use_slug +} + +resource "azurerm_search_service" "search_service" { + name = azurecaf_name.service.result + location = local.location + resource_group_name = local.resource_group_name + sku = lower(var.settings.sku) + local_authentication_enabled = try(var.settings.local_authentication_enabled, null) + authentication_failure_mode = try(var.settings.authentication_failure_mode, null) + public_network_access_enabled = try(var.settings.public_network_access_enabled, false) + allowed_ips = try(var.settings.public_network_access_enabled, false) ? try(var.settings.allowed_ips, []) : [] + customer_managed_key_enforcement_enabled = try(var.settings.customer_managed_key_enforcement_enabled, null) + hosting_mode = (lower(var.settings.sku) == "standard3") ? try(var.settings.hosting_mode, "default") : null + dynamic "identity" { + for_each = try(var.identity, null) == null ? [] : [1] + + content { + type = var.identity.type + } + } + partition_count = ((lower(var.settings.sku) != "free") && (lower(var.settings.sku) != "basic")) ? try(var.settings.partition_count, null) : null + replica_count = (lower(var.settings.sku) != "free") ? try(var.settings.replica_count, null) : null +} \ No newline at end of file diff --git a/modules/search_service/variables.tf b/modules/search_service/variables.tf new file mode 100644 index 0000000000..f430c40d38 --- /dev/null +++ b/modules/search_service/variables.tf @@ -0,0 +1,44 @@ +variable "global_settings" { + description = "Global settings object (see module README.md)" +} +variable "client_config" { + description = "Client configuration object (see module README.md)." +} +variable "location" { + description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created." + type = string +} + +variable "resource_group_name" { + description = "Name of the existing resource group to deploy the virtual machine" + type = string +} +variable "resource_group" { + description = "Resource group object to deploy the virtual machine" +} +variable "identity" { + default = null +} + +variable "settings" {} + +variable "private_endpoints" { + default = {} +} + +variable "private_dns" { + default = {} +} + +variable "base_tags" { + description = "Base tags for the resource to be inherited from the resource group." + type = bool +} +variable "vnets" { + default = {} +} +variable "virtual_subnets" { + description = "Map of virtual_subnets objects" + default = {} + nullable = false +} \ No newline at end of file diff --git a/modules/security/keyvault_certificate_request/global_sign.tf b/modules/security/keyvault_certificate_request/global_sign.tf index 4d37d173f1..ab89721e1e 100644 --- a/modules/security/keyvault_certificate_request/global_sign.tf +++ b/modules/security/keyvault_certificate_request/global_sign.tf @@ -5,7 +5,7 @@ data "external" "password" { "bash", "-c", format( "az keyvault secret show --id '%s'secrets/'%s' --query '{value: value}' -o json", - var.keyvault_id, + var.keyvault_uri, var.cert_secret_name ) ] diff --git a/modules/security/keyvault_certificate_request/output.tf b/modules/security/keyvault_certificate_request/output.tf index be939cec82..306e00551f 100644 --- a/modules/security/keyvault_certificate_request/output.tf +++ b/modules/security/keyvault_certificate_request/output.tf @@ -4,6 +4,9 @@ output "id" { output "keyvault_id" { value = var.keyvault_id } +output "keyvault_uri" { + value = var.keyvault_uri +} output "secret_id" { value = azurerm_key_vault_certificate.csr.secret_id } diff --git a/modules/security/keyvault_certificate_request/variables.tf b/modules/security/keyvault_certificate_request/variables.tf index 5f3a19f4c3..df115d8202 100644 --- a/modules/security/keyvault_certificate_request/variables.tf +++ b/modules/security/keyvault_certificate_request/variables.tf @@ -2,6 +2,7 @@ variable "certificate_issuers" { default = {} } variable "keyvault_id" {} +variable "keyvault_uri" {} variable "settings" {} variable "domain_name_registrations" { default = {} diff --git a/modules/storage_account/storage_account.tf b/modules/storage_account/storage_account.tf index c8e73baa30..5b660a1e78 100644 --- a/modules/storage_account/storage_account.tf +++ b/modules/storage_account/storage_account.tf @@ -22,9 +22,10 @@ resource "azurerm_storage_account" "stg" { account_tier = try(var.storage_account.account_tier, "Standard") account_replication_type = try(var.storage_account.account_replication_type, "LRS") account_kind = try(var.storage_account.account_kind, "StorageV2") - access_tier = try(var.storage_account.access_tier, "Hot") + access_tier = contains(["BlobStorage", "FileStorage", "StorageV2"], try(var.storage_account.account_kind, "StorageV2")) ? try(var.storage_account.access_tier, "Hot") : null allow_nested_items_to_be_public = try(var.storage_account.allow_nested_items_to_be_public, var.storage_account.allow_blob_public_access, false) - cross_tenant_replication_enabled = try(var.storage_account.cross_tenant_replication_enabled, null) + # Falsely defaults to true in this version 3.114.0 https://github.com/hashicorp/terraform-provider-azurerm/pull/26962 + cross_tenant_replication_enabled = try(var.storage_account.cross_tenant_replication_enabled, false) edge_zone = try(var.storage_account.edge_zone, null) enable_https_traffic_only = try(var.storage_account.enable_https_traffic_only, true) infrastructure_encryption_enabled = try(var.storage_account.infrastructure_encryption_enabled, null) diff --git a/modules/storage_account/storage_defender.tf b/modules/storage_account/storage_defender.tf new file mode 100644 index 0000000000..8857e914e1 --- /dev/null +++ b/modules/storage_account/storage_defender.tf @@ -0,0 +1,9 @@ +resource "azurerm_security_center_storage_defender" "defender" { + count = can(var.storage_account.defender) ? 1 : 0 + + storage_account_id = azurerm_storage_account.stg.id + override_subscription_settings_enabled = try(var.storage_account.defender.override_subscription_settings, null) + malware_scanning_on_upload_enabled = try(var.storage_account.defender.malware_scanning_on_upload, null) + malware_scanning_on_upload_cap_gb_per_month = try(var.storage_account.defender.malware_scanning_on_upload_cap_gb_per_month, null) + sensitive_data_discovery_enabled = try(var.storage_account.defender.sensitive_data_discovery_enabled, null) +} diff --git a/modules/subscriptions/subscriptions.tf b/modules/subscriptions/subscriptions.tf index 433fc473e8..7c4d6b1592 100644 --- a/modules/subscriptions/subscriptions.tf +++ b/modules/subscriptions/subscriptions.tf @@ -6,7 +6,7 @@ data "azurerm_billing_enrollment_account_scope" "sub" { } data "azurerm_billing_mca_account_scope" "sub" { - count = try(var.settings.subscription_id, null) == null && var.subscription_key != "logged_in_subscription" && try(var.settings.billing_profile_name, null) != null ? 1 : 0 + count = !can(var.settings.subscription_id) && var.subscription_key != "logged_in_subscription" && can(var.settings.billing_profile_name) && !can(var.settings.invoice_section_key) ? 1 : 0 billing_account_name = var.settings.billing_account_name billing_profile_name = var.settings.billing_profile_name @@ -19,9 +19,10 @@ resource "azurerm_subscription" "sub" { alias = try(var.settings.alias, null) == null ? var.subscription_key : var.settings.alias subscription_name = var.settings.name subscription_id = try(var.settings.subscription_id, null) != null ? var.settings.subscription_id : null - billing_scope_id = try(var.settings.billing_scope_id, null) == null ? try(data.azurerm_billing_enrollment_account_scope.sub.0.id, data.azurerm_billing_mca_account_scope.sub.0.id, null) : var.settings.billing_scope_id - workload = try(var.settings.workload, null) - tags = try(var.tags, null) + billing_scope_id = can(local.billing_scope_id) ? local.billing_scope_id : try(data.azurerm_billing_enrollment_account_scope.sub.0.id, data.azurerm_billing_mca_account_scope.sub.0.id, null) + + workload = try(var.settings.workload, null) + tags = try(var.tags, null) lifecycle { ignore_changes = [ @@ -29,6 +30,11 @@ resource "azurerm_subscription" "sub" { ] } } +locals { + billing_scope_by_name = try(data.azurerm_billing_enrollment_account_scope.sub.0.id, data.azurerm_billing_mca_account_scope.sub.0.id, null) + billing_scope_by_key = try((can(var.billing_scope_id) ? var.billing_scope_id : null), (can(var.settings.billing_scope_id) ? var.settings.billing_scope_id : null), null) + billing_scope_id = try(coalesce(local.billing_scope_by_name, local.billing_scope_by_key), null) +} resource "null_resource" "refresh_access_token" { diff --git a/modules/subscriptions/variables.tf b/modules/subscriptions/variables.tf index c8b3fb97fe..1cfadf5e64 100644 --- a/modules/subscriptions/variables.tf +++ b/modules/subscriptions/variables.tf @@ -10,7 +10,9 @@ variable "client_config" {} variable "global_settings" { description = "Global settings object (see module README.md)" } - +variable "billing_scope_id" { + default = {} +} # For diagnostics settings variable "diagnostics" { default = {} diff --git a/modules/webapps/appservice/main.tf b/modules/webapps/appservice/main.tf index cdd9aaa111..682442ae8c 100644 --- a/modules/webapps/appservice/main.tf +++ b/modules/webapps/appservice/main.tf @@ -27,12 +27,14 @@ locals { arm_filename = "${path.module}/arm_site_config.json" - app_settings = merge(try(var.app_settings, {}), try(local.dynamic_settings_to_process, {}), var.application_insight == null ? {} : - { + app_settings = merge( + var.application_insight == null ? {} : { "APPINSIGHTS_INSTRUMENTATIONKEY" = var.application_insight.instrumentation_key, "APPLICATIONINSIGHTS_CONNECTION_STRING" = var.application_insight.connection_string, "ApplicationInsightsAgent_EXTENSION_VERSION" = "~2" - } + }, + try(var.app_settings, {}), + try(local.dynamic_settings_to_process, {}) ) backup_storage_account = can(var.settings.backup) ? var.storage_accounts[try(var.settings.backup.lz_key, var.client_config.landingzone_key)][var.settings.backup.storage_account_key] : null diff --git a/modules/webapps/appservice/module.tf b/modules/webapps/appservice/module.tf index 105d5d56f5..7ad8c896ec 100644 --- a/modules/webapps/appservice/module.tf +++ b/modules/webapps/appservice/module.tf @@ -84,6 +84,28 @@ resource "azurerm_app_service" "app_service" { dynamic "headers" { for_each = try(ip_restriction.headers, {}) + content { + x_azure_fdid = lookup(headers.value, "x_azure_fdid", null) + x_fd_health_probe = lookup(headers.value, "x_fd_health_probe", null) + x_forwarded_for = lookup(headers.value, "x_forwarded_for", null) + x_forwarded_host = lookup(headers.value, "x_forwarded_host", null) + } + } + } + } + dynamic "scm_ip_restriction" { + for_each = try(var.settings.site_config.scm_ip_restriction, {}) + + content { + ip_address = lookup(scm_ip_restriction.value, "ip_address", null) + service_tag = lookup(scm_ip_restriction.value, "service_tag", null) + virtual_network_subnet_id = can(scm_ip_restriction.value.virtual_network_subnet_id) ? scm_ip_restriction.value.virtual_network_subnet_id : can(scm_ip_restriction.value.virtual_network_subnet.id) ? scm_ip_restriction.value.virtual_network_subnet.id : can(scm_ip_restriction.value.virtual_network_subnet.subnet_key) ? var.combined_objects.networking[try(scm_ip_restriction.value.virtual_network_subnet.lz_key, var.client_config.landingzone_key)][scm_ip_restriction.value.virtual_network_subnet.vnet_key].subnets[scm_ip_restriction.value.virtual_network_subnet.subnet_key].id : null + name = lookup(scm_ip_restriction.value, "name", null) + priority = lookup(scm_ip_restriction.value, "priority", null) + action = lookup(scm_ip_restriction.value, "action", null) + dynamic "headers" { + for_each = try(scm_ip_restriction.headers, {}) + content { x_azure_fdid = lookup(headers.value, "x_azure_fdid", null) x_fd_health_probe = lookup(headers.value, "x_fd_health_probe", null) diff --git a/modules/webapps/appservice/slot.tf b/modules/webapps/appservice/slot.tf index aa4926c28b..c737549e3b 100644 --- a/modules/webapps/appservice/slot.tf +++ b/modules/webapps/appservice/slot.tf @@ -68,6 +68,28 @@ resource "azurerm_app_service_slot" "slots" { virtual_network_subnet_id = lookup(var.settings.site_config.ip_restriction, "virtual_network_subnet_id", null) } } + dynamic "scm_ip_restriction" { + for_each = try(var.settings.site_config.scm_ip_restriction, {}) + + content { + ip_address = lookup(scm_ip_restriction.value, "ip_address", null) + service_tag = lookup(scm_ip_restriction.value, "service_tag", null) + virtual_network_subnet_id = can(scm_ip_restriction.value.virtual_network_subnet_id) ? scm_ip_restriction.value.virtual_network_subnet_id : can(scm_ip_restriction.value.virtual_network_subnet.id) ? scm_ip_restriction.value.virtual_network_subnet.id : can(scm_ip_restriction.value.virtual_network_subnet.subnet_key) ? var.combined_objects.networking[try(scm_ip_restriction.value.virtual_network_subnet.lz_key, var.client_config.landingzone_key)][scm_ip_restriction.value.virtual_network_subnet.vnet_key].subnets[scm_ip_restriction.value.virtual_network_subnet.subnet_key].id : null + name = lookup(scm_ip_restriction.value, "name", null) + priority = lookup(scm_ip_restriction.value, "priority", null) + action = lookup(scm_ip_restriction.value, "action", null) + dynamic "headers" { + for_each = try(scm_ip_restriction.headers, {}) + + content { + x_azure_fdid = lookup(headers.value, "x_azure_fdid", null) + x_fd_health_probe = lookup(headers.value, "x_fd_health_probe", null) + x_forwarded_for = lookup(headers.value, "x_forwarded_for", null) + x_forwarded_host = lookup(headers.value, "x_forwarded_host", null) + } + } + } + } } } diff --git a/modules/webapps/function_app/diagnostic.tf b/modules/webapps/function_app/diagnostic.tf new file mode 100644 index 0000000000..981bd0dd3a --- /dev/null +++ b/modules/webapps/function_app/diagnostic.tf @@ -0,0 +1,9 @@ +module "diagnostics" { + source = "../../diagnostics" + count = var.diagnostic_profiles == null ? 0 : 1 + + resource_id = azurerm_function_app.function_app.id + resource_location = local.location + diagnostics = var.diagnostics + profiles = var.diagnostic_profiles +} diff --git a/modules/webapps/function_app/main.tf b/modules/webapps/function_app/main.tf index 1cc33b7edc..a401486a5e 100644 --- a/modules/webapps/function_app/main.tf +++ b/modules/webapps/function_app/main.tf @@ -27,12 +27,14 @@ locals { arm_filename = "${path.module}/arm_site_config.json" - app_settings = merge(try(var.app_settings, {}), try(local.dynamic_settings_to_process, {}), var.application_insight == null ? {} : - { + app_settings = merge( + var.application_insight == null ? {} : { "APPINSIGHTS_INSTRUMENTATIONKEY" = var.application_insight.instrumentation_key, "APPLICATIONINSIGHTS_CONNECTION_STRING" = var.application_insight.connection_string, "ApplicationInsightsAgent_EXTENSION_VERSION" = "~2" - } + }, + try(var.app_settings, {}), + try(local.dynamic_settings_to_process, {}) ) -} \ No newline at end of file +} diff --git a/modules/webapps/function_app/variables.tf b/modules/webapps/function_app/variables.tf index 713ad444b1..b3fb6425cc 100644 --- a/modules/webapps/function_app/variables.tf +++ b/modules/webapps/function_app/variables.tf @@ -86,4 +86,10 @@ variable "virtual_subnets" { } variable "vnets" { default = {} -} \ No newline at end of file +} +variable "diagnostic_profiles" { + default = {} +} +variable "diagnostics" { + default = null +} diff --git a/msssql_managed_instances.tf b/msssql_managed_instances.tf index 5bf6b33d61..373d445ec9 100644 --- a/msssql_managed_instances.tf +++ b/msssql_managed_instances.tf @@ -16,8 +16,12 @@ module "mssql_managed_instances" { location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} + inherit_tags = try(local.global_settings.inherit_tags, false) keyvault = can(each.value.administrator_login_password) ? null : local.combined_objects_keyvaults[try(each.value.keyvault.lz_key, local.client_config.landingzone_key)][try(each.value.keyvault.key, each.value.keyvault_key)] - + vnets = local.combined_objects_networking + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + resource_groups = local.combined_objects_resource_groups } module "mssql_managed_instances_secondary" { @@ -34,9 +38,14 @@ module "mssql_managed_instances_secondary" { location = can(local.global_settings.regions[each.value.region]) ? local.global_settings.regions[each.value.region] : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} + inherit_tags = try(local.global_settings.inherit_tags, false) subnet_id = can(each.value.networking.subnet_id) ? each.value.networking.subnet_id : local.combined_objects_networking[try(each.value.networking.lz_key, local.client_config.landingzone_key)][each.value.networking.vnet_key].subnets[each.value.networking.subnet_key].id primary_server_id = local.combined_objects_mssql_managed_instances[try(each.value.primary_server.lz_key, local.client_config.landingzone_key)][each.value.primary_server.mi_server_key].id keyvault = can(each.value.administrator_login_password) ? null : local.combined_objects_keyvaults[try(each.value.keyvault.lz_key, local.client_config.landingzone_key)][try(each.value.keyvault.key, each.value.keyvault_key)] + vnets = local.combined_objects_networking + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + resource_groups = local.combined_objects_resource_groups } module "mssql_mi_failover_groups" { diff --git a/msssql_managed_instances_v1.tf b/msssql_managed_instances_v1.tf index f1ac78b3f0..93c0235fb4 100644 --- a/msssql_managed_instances_v1.tf +++ b/msssql_managed_instances_v1.tf @@ -34,7 +34,12 @@ module "mssql_managed_instances_v1" { keyvault = can(each.value.administrator_login_password) ? null : local.combined_objects_keyvaults[try(each.value.keyvault.lz_key, local.client_config.landingzone_key)][try(each.value.keyvault.key, each.value.keyvault_key)] primary_server_id = null group_id = can(each.value.administrators.azuread_group_id) || can(each.value.administrators.azuread_group_key) ? try(each.value.administrators.azuread_group_id, local.combined_objects_azuread_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.administrators.azuread_group_key].id) : null + vnets = local.combined_objects_networking + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + resource_groups = local.combined_objects_resource_groups + base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} inherit_tags = try(local.global_settings.inherit_tags, false) resource_group = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? null : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : null @@ -57,7 +62,12 @@ module "mssql_managed_instances_secondary_v1" { primary_server_id = local.combined_objects_mssql_managed_instances[try(each.value.primary_server.lz_key, local.client_config.landingzone_key)][each.value.primary_server.mi_server_key].id keyvault = can(each.value.administrator_login_password) ? null : local.combined_objects_keyvaults[try(each.value.keyvault.lz_key, local.client_config.landingzone_key)][try(each.value.keyvault.key, each.value.keyvault_key)] group_id = can(each.value.administrators.azuread_group_id) || can(each.value.administrators.azuread_group_key) ? try(each.value.administrators.azuread_group_id, local.combined_objects_azuread_groups[try(each.value.administrators.lz_key, local.client_config.landingzone_key)][each.value.administrators.azuread_group_key].id) : null + vnets = local.combined_objects_networking + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + resource_groups = local.combined_objects_resource_groups + base_tags = try(local.global_settings.inherit_tags, false) ? try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags, {}) : {} inherit_tags = try(local.global_settings.inherit_tags, false) resource_group = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? null : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : null diff --git a/mysql_flexible_servers.tf b/mysql_flexible_servers.tf index 3e396f8e63..afdcc69bee 100644 --- a/mysql_flexible_servers.tf +++ b/mysql_flexible_servers.tf @@ -15,7 +15,11 @@ module "mysql_flexible_server" { resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name location = can(local.global_settings.regions[each.value.region]) || can(each.value.region) ? try(local.global_settings.regions[each.value.region], each.value.region) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location - + private_endpoints = try(each.value.private_endpoints, {}) + resource_groups = try(each.value.private_endpoints, {}) == {} ? null : local.resource_groups + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] + vnets = local.combined_objects_networking + inherit_base_tags = local.global_settings.inherit_tags remote_objects = { subnet_id = can(each.value.vnet.subnet_key) ? local.combined_objects_networking[try(each.value.vnet.lz_key, local.client_config.landingzone_key)][each.value.vnet.key].subnets[each.value.vnet.subnet_key].id : null private_dns_zone_id = can(each.value.private_dns_zone.key) ? local.combined_objects_private_dns[try(each.value.private_dns_zone.lz_key, local.client_config.landingzone_key)][each.value.private_dns_zone.key].id : null diff --git a/networking.tf b/networking.tf index f906002385..a3cd729c74 100644 --- a/networking.tf +++ b/networking.tf @@ -259,7 +259,7 @@ resource "azurecaf_name" "route_tables" { prefixes = local.global_settings.prefixes random_length = local.global_settings.random_length clean_input = true - passthrough = local.global_settings.passthrough + passthrough = can( each.value.passthrough ) ? true : local.global_settings.passthrough use_slug = local.global_settings.use_slug } diff --git a/networking_connection_monitor.tf b/networking_connection_monitor.tf index 1104635bb9..8c4b908caa 100644 --- a/networking_connection_monitor.tf +++ b/networking_connection_monitor.tf @@ -15,6 +15,7 @@ module "network_connection_monitors" { network_watcher_name = try(each.value.network_watcher_name, null) combined_objects_log_analytics = local.combined_objects_log_analytics + diagnostics = local.combined_diagnostics endpoint_objects = { virtual_subnets = local.combined_objects_virtual_subnets diff --git a/networking_private_links.tf b/networking_private_links.tf index db8ea88cb2..2971f91eb5 100644 --- a/networking_private_links.tf +++ b/networking_private_links.tf @@ -15,24 +15,25 @@ module "private_endpoints" { diagnostic_storage_accounts = local.combined_diagnostics.storage_accounts diagnostic_event_hub_namespaces = local.combined_diagnostics.event_hub_namespaces - aks_clusters = local.combined_objects_aks_clusters - app_config = local.combined_objects_app_config - batch_accounts = local.combined_objects_batch_accounts - azure_container_registries = local.combined_objects_azure_container_registries - cosmos_dbs = local.combined_objects_cosmos_dbs - data_factory = local.combined_objects_data_factory - event_hub_namespaces = local.combined_objects_event_hub_namespaces - keyvaults = local.combined_objects_keyvaults - machine_learning = local.combined_objects_machine_learning - mssql_servers = local.combined_objects_mssql_servers - mysql_servers = local.combined_objects_mysql_servers - networking = local.combined_objects_networking - postgresql_servers = local.combined_objects_postgresql_servers - recovery_vaults = local.combined_objects_recovery_vaults - redis_caches = local.combined_objects_redis_caches - storage_accounts = local.combined_objects_storage_accounts - synapse_workspaces = local.combined_objects_synapse_workspaces - signalr_services = local.combined_objects_signalr_services + aks_clusters = local.combined_objects_aks_clusters + app_config = local.combined_objects_app_config + batch_accounts = local.combined_objects_batch_accounts + azure_container_registries = local.combined_objects_azure_container_registries + cognitive_services_accounts = local.combined_objects_cognitive_services_accounts + cosmos_dbs = local.combined_objects_cosmos_dbs + data_factory = local.combined_objects_data_factory + event_hub_namespaces = local.combined_objects_event_hub_namespaces + keyvaults = local.combined_objects_keyvaults + machine_learning = local.combined_objects_machine_learning + mssql_servers = local.combined_objects_mssql_servers + mysql_servers = local.combined_objects_mysql_servers + networking = local.combined_objects_networking + postgresql_servers = local.combined_objects_postgresql_servers + recovery_vaults = local.combined_objects_recovery_vaults + redis_caches = local.combined_objects_redis_caches + storage_accounts = local.combined_objects_storage_accounts + synapse_workspaces = local.combined_objects_synapse_workspaces + signalr_services = local.combined_objects_signalr_services } } diff --git a/networking_virtual_hubs.tf b/networking_virtual_hubs.tf index 0b9d0066ea..5798210db1 100644 --- a/networking_virtual_hubs.tf +++ b/networking_virtual_hubs.tf @@ -23,6 +23,7 @@ module "virtual_hubs" { tags = try(local.global_settings.inherit_tags, false) ? merge(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][each.value.resource_group.key].tags, try(each.value.tags, null)) : {} virtual_hub_config = each.value virtual_networks = local.combined_objects_networking + keyvaults = local.combined_objects_keyvaults vwan_id = can(each.value.virtual_wan) ? local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, local.client_config.landingzone_key)][each.value.virtual_wan.key].virtual_wan.id : null } diff --git a/networking_virtual_wan.tf b/networking_virtual_wan.tf index c1bdd4f119..9363cfde01 100644 --- a/networking_virtual_wan.tf +++ b/networking_virtual_wan.tf @@ -25,5 +25,6 @@ module "virtual_wans" { global_settings = local.global_settings virtual_networks = local.combined_objects_networking public_ip_addresses = local.combined_objects_public_ip_addresses + keyvaults = local.combined_objects_keyvaults } diff --git a/networking_vpn_gateway_connection.tf b/networking_vpn_gateway_connection.tf index 49bee6d68d..aa19169ef6 100644 --- a/networking_vpn_gateway_connection.tf +++ b/networking_vpn_gateway_connection.tf @@ -19,6 +19,8 @@ module "vpn_gateway_connections" { client_config = local.client_config vpn_sites = local.combined_objects_vpn_sites route_tables = local.combined_objects_virtual_hub_route_tables + nat_rules = local.combined_objects_vpn_gateway_nat_rules - vpn_gateway_id = can(each.value.virtual_hub_gateway_id) || can(each.value.virtual_wan) ? try(each.value.virtual_hub_gateway_id, local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, each.value.lz_key, local.client_config.landingzone_key)][try(each.value.virtual_wan.key, each.value.virtual_wan_key)].virtual_hubs[try(each.value.virtual_hub.key, each.value.virtual_hub_key)].s2s_gateway.id) : local.combined_objects_virtual_hubs[try(each.value.virtual_hub.lz_key, local.client_config.landingzone_key)][each.value.virtual_hub.key].s2s_gateway.id + default_route_table_id = can(each.value.virtual_wan) ? local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, each.value.lz_key, local.client_config.landingzone_key)][try(each.value.virtual_wan.key, each.value.virtual_wan_key)].virtual_hubs[try(each.value.virtual_hub.key, each.value.virtual_hub_key)].default_route_table_id : local.combined_objects_virtual_hubs[try(each.value.virtual_hub.lz_key, local.client_config.landingzone_key)][each.value.virtual_hub.key].default_route_table_id + vpn_gateway_id = can(each.value.virtual_hub_gateway_id) || can(each.value.virtual_wan) ? try(each.value.virtual_hub_gateway_id, local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, each.value.lz_key, local.client_config.landingzone_key)][try(each.value.virtual_wan.key, each.value.virtual_wan_key)].virtual_hubs[try(each.value.virtual_hub.key, each.value.virtual_hub_key)].s2s_gateway.id) : local.combined_objects_virtual_hubs[try(each.value.virtual_hub.lz_key, local.client_config.landingzone_key)][each.value.virtual_hub.key].s2s_gateway.id } diff --git a/networking_vpn_gateway_nat_rule.tf b/networking_vpn_gateway_nat_rule.tf new file mode 100644 index 0000000000..6bab061a19 --- /dev/null +++ b/networking_vpn_gateway_nat_rule.tf @@ -0,0 +1,23 @@ + +# +# +# VPN Gateway NAT Rule used for VPN Gatway Connection +# +# + +output "vpn_gateway_nat_rules" { + value = module.vpn_gateway_nat_rules +} + +module "vpn_gateway_nat_rules" { + depends_on = [module.virtual_wans, module.vpn_sites, module.virtual_hubs] + source = "./modules/networking/vpn_gateway_nat_rule" + for_each = local.networking.vpn_gateway_nat_rules + + settings = each.value + global_settings = local.global_settings + client_config = local.client_config + + resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)].name + vpn_gateway_id = can(each.value.virtual_hub_gateway_id) || can(each.value.virtual_wan) ? try(each.value.virtual_hub_gateway_id, local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, each.value.lz_key, local.client_config.landingzone_key)][try(each.value.virtual_wan.key, each.value.virtual_wan_key)].virtual_hubs[try(each.value.virtual_hub.key, each.value.virtual_hub_key)].s2s_gateway.id) : local.combined_objects_virtual_hubs[try(each.value.virtual_hub.lz_key, local.client_config.landingzone_key)][each.value.virtual_hub.key].s2s_gateway.id +} diff --git a/postgresql_flexible_servers.tf b/postgresql_flexible_servers.tf index a6e5ea3f42..68dbd2865f 100755 --- a/postgresql_flexible_servers.tf +++ b/postgresql_flexible_servers.tf @@ -7,20 +7,23 @@ module "postgresql_flexible_servers" { depends_on = [module.keyvaults, module.networking] for_each = local.database.postgresql_flexible_servers - global_settings = local.global_settings - client_config = local.client_config - settings = each.value - resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)] - base_tags = local.global_settings.inherit_tags + global_settings = local.global_settings + client_config = local.client_config + settings = each.value + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)] + base_tags = local.global_settings.inherit_tags + vnets = local.combined_objects_networking + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns remote_objects = { subnet_id = can(each.value.vnet.subnet_key) ? local.combined_objects_networking[try(each.value.vnet.lz_key, local.client_config.landingzone_key)][each.value.vnet.key].subnets[each.value.vnet.subnet_key].id : null private_dns_zone_id = can(each.value.private_dns_zone.key) ? local.combined_objects_private_dns[try(each.value.private_dns_zone.lz_key, local.client_config.landingzone_key)][each.value.private_dns_zone.key].id : null keyvault_id = can(each.value.keyvault.key) ? local.combined_objects_keyvaults[try(each.value.keyvault.lz_key, local.client_config.landingzone_key)][each.value.keyvault.key].id : null diagnostics = local.combined_diagnostics - managed_identities = local.combined_objects_managed_identities azuread_groups = local.combined_objects_azuread_groups azuread_users = local.combined_objects_azuread_users service_principals = local.combined_objects_azuread_service_principals + managed_identities = local.combined_objects_managed_identities } -} \ No newline at end of file +} diff --git a/recovery_vaults.tf b/recovery_vaults.tf index 2449c3d201..88dc152315 100644 --- a/recovery_vaults.tf +++ b/recovery_vaults.tf @@ -3,16 +3,17 @@ module "recovery_vaults" { source = "./modules/recovery_vault" for_each = local.shared_services.recovery_vaults - global_settings = local.global_settings - client_config = local.client_config - settings = each.value - diagnostics = local.combined_diagnostics - identity = try(each.value.identity, null) - vnets = try(local.combined_objects_networking, {}) - private_endpoints = try(each.value.private_endpoints, {}) - private_dns = local.combined_objects_private_dns - resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)] - base_tags = local.global_settings.inherit_tags + global_settings = local.global_settings + client_config = local.client_config + settings = each.value + diagnostic_profiles = try(each.value.diagnostic_profiles, {}) + diagnostics = local.combined_diagnostics + identity = try(each.value.identity, null) + vnets = try(local.combined_objects_networking, {}) + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)] + base_tags = local.global_settings.inherit_tags } output "recovery_vaults" { diff --git a/roles.tf b/roles.tf index 5874167bd5..150b45a175 100644 --- a/roles.tf +++ b/roles.tf @@ -106,6 +106,7 @@ locals { storage_containers = local.combined_objects_storage_containers azuread_groups = local.combined_objects_azuread_groups azuread_service_principals = local.combined_objects_azuread_service_principals + storage_account_file_shares = local.combined_objects_storage_account_file_shares } @@ -130,8 +131,10 @@ locals { azurerm_firewalls = local.combined_objects_azurerm_firewalls backup_vaults = local.combined_objects_backup_vaults batch_accounts = local.combined_objects_batch_accounts + cognitive_services_account = local.combined_objects_cognitive_services_accounts data_factory = local.combined_objects_data_factory databricks_workspaces = local.combined_objects_databricks_workspaces + diagnostic_storage_accounts = local.current_objects_diagnostic_storage_accounts dns_zones = local.combined_objects_dns_zones event_hub_namespaces = local.combined_objects_event_hub_namespaces function_apps = local.combined_objects_function_apps @@ -145,11 +148,13 @@ locals { machine_learning_workspaces = local.combined_objects_machine_learning managed_identities = local.combined_objects_managed_identities management_group = local.management_groups + monitor_action_groups = local.combined_objects_monitor_action_groups mssql_databases = local.combined_objects_mssql_databases mssql_elastic_pools = local.combined_objects_mssql_elastic_pools mssql_managed_databases = local.combined_objects_mssql_managed_databases mssql_managed_instances = local.combined_objects_mssql_managed_instances mssql_servers = local.combined_objects_mssql_servers + maintenance_configuration = local.combined_objects_maintenance_configuration mysql_servers = local.combined_objects_mysql_servers network_watchers = local.combined_objects_network_watchers networking = local.combined_objects_networking @@ -160,6 +165,8 @@ locals { purview_accounts = local.combined_objects_purview_accounts recovery_vaults = local.combined_objects_recovery_vaults resource_groups = local.combined_objects_resource_groups + shared_image_galleries = local.combined_objects_shared_image_galleries + route_tables = local.combined_objects_route_tables servicebus_namespaces = local.combined_objects_servicebus_namespaces servicebus_queues = local.combined_objects_servicebus_queues servicebus_topics = local.combined_objects_servicebus_topics @@ -170,12 +177,10 @@ locals { virtual_subnets = local.combined_objects_virtual_subnets virtual_machine_scale_sets = local.combined_objects_virtual_machine_scale_sets log_analytics = local.current_objects_log_analytics - route_tables = local.combined_objects_route_tables wvd_application_groups = local.combined_objects_wvd_application_groups wvd_applications = local.combined_objects_wvd_applications wvd_host_pools = local.combined_objects_wvd_host_pools wvd_workspaces = local.combined_objects_wvd_workspaces - } current_objects_log_analytics = tomap( @@ -183,6 +188,11 @@ locals { (var.current_landingzone_key) = merge(local.combined_objects_log_analytics, local.combined_diagnostics.log_analytics) } ) + current_objects_diagnostic_storage_accounts = tomap( + { + (var.current_landingzone_key) = merge(local.combined_objects_diagnostic_storage_accounts, local.combined_diagnostics.storage_accounts) + } + ) logged_in = tomap( { diff --git a/rover_on_ssh_host.yml b/rover_on_ssh_host.yml index 74132a91f2..3ca008f2df 100644 --- a/rover_on_ssh_host.yml +++ b/rover_on_ssh_host.yml @@ -11,7 +11,7 @@ version: '3.7' services: rover: - image: aztfmod/rover:1.5.7-2310.0211 +R image: aztfmod/rover:1.8.0-2405.0203 user: vscode diff --git a/search_service.tf b/search_service.tf new file mode 100644 index 0000000000..da079ee11b --- /dev/null +++ b/search_service.tf @@ -0,0 +1,21 @@ +module "search_service" { + source = "./modules/search_service" + for_each = local.search_services.search_services + + client_config = local.client_config + global_settings = local.global_settings + resource_group = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group_key, each.value.resource_group.key)] + resource_group_name = can(each.value.resource_group.name) || can(each.value.resource_group_name) ? try(each.value.resource_group.name, each.value.resource_group_name) : null + location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region] + settings = each.value + base_tags = local.global_settings.inherit_tags + identity = try(each.value.identity, null) + private_endpoints = try(each.value.private_endpoints, {}) + private_dns = local.combined_objects_private_dns + vnets = local.combined_objects_networking + virtual_subnets = local.combined_objects_virtual_subnets +} + +output "search_service" { + value = module.search_service +} diff --git a/shared_image_gallery.tf b/shared_image_gallery.tf index ae8b09f642..ba92588c18 100644 --- a/shared_image_gallery.tf +++ b/shared_image_gallery.tf @@ -44,7 +44,7 @@ module "packer_service_principal" { tenant_id = data.azurerm_client_config.current.tenant_id gallery_name = module.shared_image_galleries[each.value.shared_image_gallery_destination.gallery_key].name image_name = module.image_definitions[each.value.shared_image_gallery_destination.image_key].name - key_vault_id = lookup(each.value, "keyvault_key") == null ? null : module.keyvaults[each.value.keyvault_key].id + key_vault_id = lookup(each.value, "keyvault_key", null) == null ? null : module.keyvaults[each.value.keyvault_key].id settings = each.value depends_on = [ @@ -67,7 +67,7 @@ module "packer_build" { tenant_id = data.azurerm_client_config.current.tenant_id gallery_name = module.shared_image_galleries[each.value.shared_image_gallery_destination.gallery_key].name image_name = module.image_definitions[each.value.shared_image_gallery_destination.image_key].name - key_vault_id = lookup(each.value, "keyvault_key") == null ? null : module.keyvaults[each.value.keyvault_key].id + key_vault_id = each.value.keyvault_key == null ? null : module.keyvaults[each.value.keyvault_key].id managed_identities = local.combined_objects_managed_identities vnet_name = try(try(local.combined_objects_networking[each.value.lz_key][each.value.vnet_key].name, local.combined_objects_networking[local.client_config.landingzone_key][each.value.vnet_key].name), "") subnet_name = try(lookup(each.value, "lz_key", null) == null ? local.combined_objects_networking[local.client_config.landingzone_key][each.value.vnet_key].subnets[each.value.subnet_key].name : local.combined_objects_networking[each.value.lz_key][each.value.vnet_key].subnets[each.value.subnet_key].name, "") diff --git a/storage_account_blobs.tf b/storage_account_blobs.tf index 0b6efb52f1..763417a63c 100644 --- a/storage_account_blobs.tf +++ b/storage_account_blobs.tf @@ -3,7 +3,7 @@ # resource "time_sleep" "delay" { - #depends_on = [azurerm_role_assignment.for] # NOTE: Deactivated this direct dependency due to Cycle error + #depends_on = [azurerm_role_assignment.for_deferred] # NOTE: Deactivated this direct dependency due to Cycle error for_each = local.storage.storage_account_blobs create_duration = try(each.value.dealy.create_duration, "300s") diff --git a/storage_container.tf b/storage_container.tf index 0664970160..f7f3ae692e 100644 --- a/storage_container.tf +++ b/storage_container.tf @@ -1,6 +1,7 @@ module "storage_containers" { source = "./modules/storage_account/container/" - depends_on = [time_sleep.azurerm_role_assignment_for] + # triggers cyclic dependency + #depends_on = [time_sleep.azurerm_role_assignment_for] for_each = local.storage.storage_containers settings = each.value diff --git a/subscriptions.tf b/subscriptions.tf index fd8bc0abbc..4d9dda29bf 100644 --- a/subscriptions.tf +++ b/subscriptions.tf @@ -7,11 +7,14 @@ module "subscriptions" { global_settings = local.global_settings subscription_key = each.key settings = each.value + # billing_scope_id can also be set by tfvars (var.settings). This is only the way to inject billing_scope_id by key + billing_scope_id = can(each.value.invoice_section_key) ? local.combined_objects_invoice_sections[try(each.value.invoice_section_lz_key, local.client_config.landingzone_key)][each.value.invoice_section_key].id : null client_config = local.client_config diagnostics = local.combined_diagnostics tags = merge(var.tags, lookup(each.value, "tags", {})) } + module "subscription_billing_role_assignments" { source = "./modules/subscription_billing_role_assignment" for_each = var.subscription_billing_role_assignments @@ -31,3 +34,4 @@ module "subscription_billing_role_assignments" { output "subscriptions" { value = module.subscriptions } + diff --git a/variables.tf b/variables.tf index 8bc92383b8..5c271ce96e 100644 --- a/variables.tf +++ b/variables.tf @@ -438,6 +438,22 @@ variable "preview_features" { variable "powerbi_embedded" { default = {} } +variable "maintenance" { + default = {} +} +variable "search_services" { + description = "Configuration object - Search service Resource " + default = {} +} +variable "load_test" { + description = "Configuration object - Load Test resources" + default = {} +} + + variable "cost_anomaly_alert" { default = {} -} \ No newline at end of file +} +variable "invoice_sections" { + default = {} +}