October 2010 release (#97)
To use this new release you need to perform a full deployment. You cannot automatically upgrade from the previous launchpad. Moving forward this version adds the foundations to support future upgrade without destroying the launchpad.
|
@ -4,13 +4,13 @@
|
||||||
// Update the 'dockerComposeFile' list if you have more compose files or use different names.
|
// Update the 'dockerComposeFile' list if you have more compose files or use different names.
|
||||||
"dockerComposeFile": "docker-compose.yml",
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
|
|
||||||
|
// Container user to use in VSCode Online and GitHub Codespaces
|
||||||
|
"containerUser" : "vscode",
|
||||||
|
|
||||||
// The 'service' property is the name of the service for the container that VS Code should
|
// The 'service' property is the name of the service for the container that VS Code should
|
||||||
// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
|
// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
|
||||||
"service": "rover",
|
"service": "rover",
|
||||||
|
|
||||||
// Container user to use in VSCode Online and GitHub Codespaces
|
|
||||||
"containerUser" : "vscode",
|
|
||||||
|
|
||||||
// The optional 'workspaceFolder' property is the path VS Code should open by default when
|
// The optional 'workspaceFolder' property is the path VS Code should open by default when
|
||||||
// connected. This is typically a volume mount in .devcontainer/docker-compose.yml
|
// connected. This is typically a volume mount in .devcontainer/docker-compose.yml
|
||||||
"workspaceFolder": "/tf/caf",
|
"workspaceFolder": "/tf/caf",
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
// "shutdownAction": "none",
|
// "shutdownAction": "none",
|
||||||
|
|
||||||
// Uncomment the next line to run commands after the container is created.
|
// Uncomment the next line to run commands after the container is created.
|
||||||
"postCreateCommand": "cp -R /tmp/.ssh-localhost/* ~/.ssh && chmod 700 ~/.ssh && chmod 600 ~/.ssh/*",
|
"postCreateCommand": "cp -R /tmp/.ssh-localhost/* ~/.ssh && sudo chmod 600 ~/.ssh/* && sudo chown -R $(whoami) /tf/caf && git config --global core.editor vi && pre-commit install && pre-commit update",
|
||||||
|
|
||||||
// Add the IDs of extensions you want installed when the container is created in the array below.
|
// Add the IDs of extensions you want installed when the container is created in the array below.
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
version: '3.7'
|
version: '3.7'
|
||||||
services:
|
services:
|
||||||
rover:
|
rover:
|
||||||
image: aztfmod/rover:2009.0210
|
image: aztfmod/rover:2010.2808
|
||||||
|
user: vscode
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
- "caf=Azure CAF"
|
- "caf=Azure CAF"
|
||||||
|
|
|
@ -0,0 +1,272 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) Microsoft Corporation
|
||||||
|
# Licensed under the MIT License.
|
||||||
|
#
|
||||||
|
|
||||||
|
name: landingzones
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- 'documentation/**'
|
||||||
|
- '_pictures/**'
|
||||||
|
- 'README.md'
|
||||||
|
- 'CHANGELOG.md'
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- 'documentation/**'
|
||||||
|
- '_pictures/**'
|
||||||
|
- 'README.md'
|
||||||
|
- 'CHANGELOG.md'
|
||||||
|
schedule:
|
||||||
|
- cron: '0 4 * * *'
|
||||||
|
|
||||||
|
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 }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
foundations100:
|
||||||
|
name: foundations-100
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
max-parallel: 1
|
||||||
|
matrix:
|
||||||
|
random_length: ['5']
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: aztfmod/rover:2010.2808
|
||||||
|
options: --user 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- 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 }}
|
||||||
|
|
||||||
|
echo "local user: $(whoami)"
|
||||||
|
|
||||||
|
- name: launchpad
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_launchpad -a apply \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/caf_launchpad/scenario/100 \
|
||||||
|
-level level0 \
|
||||||
|
-launchpad \
|
||||||
|
-parallelism=30 \
|
||||||
|
--environment ${{ github.run_id }} \
|
||||||
|
'-var random_length=${{ matrix.random_length }}' \
|
||||||
|
'-var prefix=g${{ github.run_id }}' \
|
||||||
|
'-var tags={testing_job_id="${{ github.run_id }}"}'
|
||||||
|
|
||||||
|
- name: foundations
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_foundations -a apply \
|
||||||
|
-level level1 \
|
||||||
|
-parallelism=30 \
|
||||||
|
--environment ${{ github.run_id }}
|
||||||
|
|
||||||
|
networking100:
|
||||||
|
name: networking-100
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
needs: foundations100
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config_files: [
|
||||||
|
"caf_networking/scenario/100-single-region-hub",
|
||||||
|
"caf_networking/scenario/101-multi-region-hub",
|
||||||
|
"caf_networking/scenario/105-hub-and-spoke",
|
||||||
|
"caf_networking/scenario/106-hub-virtual-wan-firewall"
|
||||||
|
]
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: aztfmod/rover:2010.2808
|
||||||
|
options: --user 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- 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: deploy example
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_networking/ -a apply \
|
||||||
|
-tfstate $(basename ${{ matrix.config_files }}).tfstate \
|
||||||
|
-level level2 \
|
||||||
|
-parallelism=30 \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/${{ matrix.config_files }} \
|
||||||
|
--environment ${{ github.run_id }}
|
||||||
|
|
||||||
|
- name: destroy example
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_networking/ -a destroy \
|
||||||
|
-tfstate $(basename ${{ matrix.config_files }}).tfstate \
|
||||||
|
-level level2 \
|
||||||
|
-parallelism=30 \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/${{ matrix.config_files }} \
|
||||||
|
--environment ${{ github.run_id }} \
|
||||||
|
-refresh=false \
|
||||||
|
-auto-approve
|
||||||
|
|
||||||
|
foundations200:
|
||||||
|
name: foundations-200
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: networking100
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
max-parallel: 1
|
||||||
|
matrix:
|
||||||
|
random_length: ['5']
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: aztfmod/rover:2010.2808
|
||||||
|
options: --user 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- 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 }}
|
||||||
|
|
||||||
|
echo "local user: $(whoami)"
|
||||||
|
|
||||||
|
- name: launchpad-200-upgrade
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_launchpad -a apply \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/caf_launchpad/scenario/200 \
|
||||||
|
-level level0 \
|
||||||
|
-launchpad \
|
||||||
|
-parallelism=30 \
|
||||||
|
--environment ${{ github.run_id }} \
|
||||||
|
'-var random_length=${{ matrix.random_length }}' \
|
||||||
|
'-var prefix=g${{ github.run_id }}' \
|
||||||
|
'-var tags={testing_job_id="${{ github.run_id }}"}'
|
||||||
|
|
||||||
|
- name: foundations-200-upgrade
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_foundations -a apply \
|
||||||
|
-level level1 \
|
||||||
|
--environment ${{ github.run_id }}
|
||||||
|
|
||||||
|
networking200:
|
||||||
|
name: networking-200
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
needs: foundations200
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config_files: [
|
||||||
|
"caf_networking/scenario/200-single-region-hub",
|
||||||
|
"caf_networking/scenario/201-multi-region-hub",
|
||||||
|
"caf_networking/scenario/210-aks-private"
|
||||||
|
]
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: aztfmod/rover:2010.2808
|
||||||
|
options: --user 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- 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: deploy example
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_networking/ -a apply \
|
||||||
|
-tfstate $(basename ${{ matrix.config_files }}).tfstate \
|
||||||
|
-level level2 \
|
||||||
|
-parallelism=30 \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/${{ matrix.config_files }} \
|
||||||
|
--environment ${{ github.run_id }}
|
||||||
|
|
||||||
|
- name: destroy example
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_networking/ -a destroy \
|
||||||
|
-tfstate $(basename ${{ matrix.config_files }}).tfstate \
|
||||||
|
-level level2 \
|
||||||
|
-parallelism=30 \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/${{ matrix.config_files }} \
|
||||||
|
--environment ${{ github.run_id }} \
|
||||||
|
-refresh=false \
|
||||||
|
-auto-approve
|
||||||
|
|
||||||
|
foundations_destroy:
|
||||||
|
name: foundations_destroy
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: always()
|
||||||
|
needs: networking200
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
random_length: ['5']
|
||||||
|
|
||||||
|
container:
|
||||||
|
image: aztfmod/rover:2010.2808
|
||||||
|
options: --user 0
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- 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 }}
|
||||||
|
|
||||||
|
echo "local user: $(whoami)"
|
||||||
|
|
||||||
|
- name: foundations
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_foundations -a destroy \
|
||||||
|
-level level1 \
|
||||||
|
-parallelism=30 \
|
||||||
|
--environment ${{ github.run_id }} \
|
||||||
|
-auto-approve
|
||||||
|
|
||||||
|
- name: Remove launchpad
|
||||||
|
run: |
|
||||||
|
/tf/rover/rover.sh -lz ${GITHUB_WORKSPACE}/landingzones/caf_launchpad -a destroy \
|
||||||
|
-var-folder ${GITHUB_WORKSPACE}/landingzones/caf_launchpad/scenario/200 \
|
||||||
|
-level level0 \
|
||||||
|
-launchpad \
|
||||||
|
-parallelism=30 \
|
||||||
|
--environment ${{ github.run_id }} \
|
||||||
|
'-var random_length=${{ matrix.random_length }}' \
|
||||||
|
'-var prefix=g${{ github.run_id }}' \
|
||||||
|
'-var tags={testing_job_id="${{ github.run_id }}"}' \
|
||||||
|
-auto-approve
|
||||||
|
|
||||||
|
|
||||||
|
- name: Complete purge
|
||||||
|
if: ${{ always() }}
|
||||||
|
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 }}')].objectId" -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.environment=='${{ github.run_id }}'].name" -o tsv`; do az keyvault purge --name $i; done
|
||||||
|
for i in `az group list --query "[?tags.environment=='${{ 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
|
|
@ -1,278 +0,0 @@
|
||||||
#
|
|
||||||
# Copyright (c) Microsoft Corporation
|
|
||||||
# Licensed under the MIT License.
|
|
||||||
#
|
|
||||||
|
|
||||||
name: landingzones
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- 'documentation/**'
|
|
||||||
- '_pictures/**'
|
|
||||||
- 'README.md'
|
|
||||||
- 'CHANGELOG.md'
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
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 }}
|
|
||||||
TFVARS_PATH: '/tf/caf/caf-terraform-landingzones'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tfsec:
|
|
||||||
name: Run TFsec
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Terraform security scan
|
|
||||||
uses: triat/terraform-security-scan@v2.0.2
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
level0:
|
|
||||||
name: level0
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
max-parallel: 1
|
|
||||||
matrix:
|
|
||||||
region: ["westus2"]
|
|
||||||
convention: ["random"]
|
|
||||||
|
|
||||||
container:
|
|
||||||
image: aztfmod/rover:2009.0210
|
|
||||||
options: --user 0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
||||||
echo "local user: $(whoami)"
|
|
||||||
|
|
||||||
- name: Locate launchpad
|
|
||||||
run: |
|
|
||||||
ln -s ${GITHUB_WORKSPACE} /tf/caf
|
|
||||||
|
|
||||||
id=$(az storage account list --query "[?tags.tfstate=='level0' && tags.environment=='${{ github.run_id }}']" -o json | jq -r .[0].id)
|
|
||||||
|
|
||||||
if [ "${id}" == "null" ]; then
|
|
||||||
/tf/rover/rover.sh -lz /tf/caf/caf-terraform-landingzones/landingzones/launchpad -a apply \
|
|
||||||
-launchpad \
|
|
||||||
--environment ${{ github.run_id }} \
|
|
||||||
'-var prefix=g${{ github.run_id }}' \
|
|
||||||
'-var location=${{ matrix.region }}' \
|
|
||||||
'-var convention=${{ matrix.convention }}' \
|
|
||||||
'-var tags={testing_job_id="${{ github.run_id }}"}'
|
|
||||||
fi
|
|
||||||
|
|
||||||
caf_foundations:
|
|
||||||
name: caf_foundations
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs: level0
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
landingzone: ["landingzone_caf_foundations"]
|
|
||||||
region: ["southeastasia"]
|
|
||||||
convention: ["random"]
|
|
||||||
environment: ["integration-tests"]
|
|
||||||
|
|
||||||
container:
|
|
||||||
image: aztfmod/rover:2009.0210
|
|
||||||
options: --user 0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: setup context
|
|
||||||
id: context
|
|
||||||
run: |
|
|
||||||
ln -s ${GITHUB_WORKSPACE} /tf/caf
|
|
||||||
echo "ls /tf/caf" && ls -lsa /tf/caf
|
|
||||||
ls -lsa /tmp
|
|
||||||
|
|
||||||
# workspace='caffoundationsci'
|
|
||||||
# echo ::set-env name=TF_VAR_workspace::${workspace}
|
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
||||||
echo "local user: $(whoami)"
|
|
||||||
|
|
||||||
- name: deploy caf_foundations
|
|
||||||
run: |
|
|
||||||
/tf/rover/rover.sh -lz /tf/caf/caf-terraform-landingzones/landingzones/${{ matrix.landingzone }} -a apply \
|
|
||||||
--environment ${{ github.run_id }} \
|
|
||||||
-var prefix=g${{ github.run_id}} \
|
|
||||||
'-var tags={testing_job_id="${{ github.run_id }}"}' \
|
|
||||||
'-var-file ${{ env.TFVARS_PATH }}/environments/${{ matrix.environment }}/${{ matrix.landingzone }}/${{ matrix.landingzone }}_${{ matrix.region }}_${{ matrix.convention }}.tfvars'
|
|
||||||
|
|
||||||
landingzones:
|
|
||||||
name: landingzones
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs: [level0, caf_foundations]
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
landingzone: ["landingzone_networking"]
|
|
||||||
examples: ["101-multiple-vnets", "102-multiple-vnets-peering", "103-hub-vnet-with-firewall", "104-hub-vnet-with-firewall-bastion", "105-hub-virtual-wan-firewall"]
|
|
||||||
convention: ["cafrandom"]
|
|
||||||
|
|
||||||
container:
|
|
||||||
image: aztfmod/rover:2009.0210
|
|
||||||
options: --user 0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: setup context
|
|
||||||
id: context
|
|
||||||
run: |
|
|
||||||
ln -s ${GITHUB_WORKSPACE} /tf/caf
|
|
||||||
echo "ls /tf/caf" && ls -lsa /tf/caf
|
|
||||||
ls -lsa /tmp
|
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
||||||
echo "local user: $(whoami)"
|
|
||||||
|
|
||||||
- name: Deploy landing_zone
|
|
||||||
run: |
|
|
||||||
/tf/rover/rover.sh -lz /tf/caf/caf-terraform-landingzones/landingzones/${{ matrix.landingzone }} -a apply \
|
|
||||||
-env ${{ github.run_id }} \
|
|
||||||
'-var tags={testing_job_id="${{ github.run_id }}"}' \
|
|
||||||
-tfstate ${{ matrix.examples }}_landingzone_networking.tfstate \
|
|
||||||
'-var-file ${{ env.TFVARS_PATH }}/landingzones/${{ matrix.landingzone }}/examples/${{ matrix.examples }}/configuration.tfvars'
|
|
||||||
|
|
||||||
- name: Destroy landing_zone
|
|
||||||
if: always()
|
|
||||||
run: |
|
|
||||||
/tf/rover/rover.sh -lz /tf/caf/caf-terraform-landingzones/landingzones/${{ matrix.landingzone }} -a destroy \
|
|
||||||
--environment ${{ github.run_id }} \
|
|
||||||
'-var tags={testing_job_id="${{ github.run_id }}"}' \
|
|
||||||
-tfstate ${{ matrix.examples }}_landingzone_networking.tfstate \
|
|
||||||
'-var-file ${{ env.TFVARS_PATH }}/landingzones/${{ matrix.landingzone }}/examples/${{ matrix.examples }}/configuration.tfvars'
|
|
||||||
|
|
||||||
|
|
||||||
caf_foundations_destroy:
|
|
||||||
name: caf_foundations_destroy
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: always()
|
|
||||||
needs: landingzones
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
landingzone: ["landingzone_caf_foundations"]
|
|
||||||
region: ["southeastasia"]
|
|
||||||
convention: ["random"]
|
|
||||||
environment: ["integration-tests"]
|
|
||||||
|
|
||||||
container:
|
|
||||||
image: aztfmod/rover:2009.0210
|
|
||||||
options: --user 0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: setup context
|
|
||||||
id: context
|
|
||||||
run: |
|
|
||||||
ln -s ${GITHUB_WORKSPACE} /tf/caf
|
|
||||||
echo "ls /tf/caf" && ls -lsa /tf/caf
|
|
||||||
ls -lsa /tmp
|
|
||||||
|
|
||||||
# workspace='caffoundationsci'
|
|
||||||
# echo ::set-env name=TF_VAR_workspace::${workspace}
|
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
||||||
echo "local user: $(whoami)"
|
|
||||||
|
|
||||||
- name: destroy caf_foundations
|
|
||||||
run: |
|
|
||||||
/tf/rover/rover.sh -lz /tf/caf/caf-terraform-landingzones/landingzones/${{ matrix.landingzone }} -a destroy \
|
|
||||||
--environment ${{ github.run_id }} \
|
|
||||||
-var prefix=g${{ github.run_id}} \
|
|
||||||
'-var tags={testing_job_id="${{ github.run_id }}"}' \
|
|
||||||
'-var-file ${{ env.TFVARS_PATH }}/environments/${{ matrix.environment }}/${{ matrix.landingzone }}/${{ matrix.landingzone }}_${{ matrix.region }}_${{ matrix.convention }}.tfvars' \
|
|
||||||
'-auto-approve'
|
|
||||||
|
|
||||||
level0_destroy:
|
|
||||||
name: level0_destroy
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: always()
|
|
||||||
needs: caf_foundations_destroy
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
region: ["westus2"]
|
|
||||||
convention: ["random"]
|
|
||||||
|
|
||||||
container:
|
|
||||||
image: aztfmod/rover:2009.0210
|
|
||||||
options: --user 0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
||||||
echo "local user: $(whoami)"
|
|
||||||
|
|
||||||
- name: Remove launchpad
|
|
||||||
run: |
|
|
||||||
ln -s ${GITHUB_WORKSPACE} /tf/caf
|
|
||||||
|
|
||||||
/tf/rover/rover.sh -lz /tf/caf/caf-terraform-landingzones/landingzones/launchpad -a destroy \
|
|
||||||
-launchpad \
|
|
||||||
-env ${{ github.run_id }} \
|
|
||||||
'-var prefix=g${{ github.run_id }}' \
|
|
||||||
'-var location=${{ matrix.region }}' \
|
|
||||||
'-var convention=${{ matrix.convention }}' \
|
|
||||||
'-var tags={testing_job_id="${{ github.run_id }}"}' \
|
|
||||||
-auto-approve
|
|
||||||
|
|
||||||
|
|
||||||
- name: Complete purge
|
|
||||||
if: ${{ always() }}
|
|
||||||
run: |
|
|
||||||
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 }}')].objectId" -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 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
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# See http://pre-commit.com for more information
|
||||||
|
# See http://pre-commit.com/hooks.html for more hooks
|
||||||
|
repos:
|
||||||
|
- repo: git://github.com/antonbabenko/pre-commit-terraform
|
||||||
|
rev: v1.43.0
|
||||||
|
hooks:
|
||||||
|
- id: terraform_fmt
|
||||||
|
# - id: terraform_docs
|
||||||
|
# - id: terraform_tflint
|
||||||
|
# - id: terraform_tfsec
|
||||||
|
- repo: git://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v3.3.0
|
||||||
|
hooks:
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: check-yaml
|
||||||
|
- id: check-added-large-files
|
||||||
|
# - repo: git://github.com/markdownlint/markdownlint
|
||||||
|
# rev: v0.9.0
|
||||||
|
# hooks:
|
||||||
|
# - id: markdownlint
|
11
CHANGELOG.md
|
@ -1,4 +1,13 @@
|
||||||
## v8.0.2001 (August 2020)
|
## v9.0.2009 (September 2020)
|
||||||
|
|
||||||
|
BREAKING CHANGES:
|
||||||
|
|
||||||
|
* Iterating on our new key-based iterative model to simplify deployment and maintenance, this is a major refactoring that will bring compatibility with enterprise-scale landing zones and extensible platform for construction sets (solutions and applications) deployed on top of core landing zones.
|
||||||
|
|
||||||
|
FEATURES:
|
||||||
|
* **added support for azurerm 2.28 :** On all sample landing zones [azurerm provider](https://github.com/terraform-providers/terraform-provider-azurerm/releases/tag/v2.28.0)
|
||||||
|
|
||||||
|
## v8.0.2008 (August 2020)
|
||||||
|
|
||||||
BREAKING CHANGES:
|
BREAKING CHANGES:
|
||||||
|
|
||||||
|
|
52
README.md
|
@ -2,7 +2,6 @@
|
||||||
[![VScodespaces](https://img.shields.io/endpoint?url=https%3A%2F%2Faka.ms%2Fvso-badge)](https://online.visualstudio.com/environments/new?name=caf%20landing%20zones&repo=azure/caf-terraform-landingzones)
|
[![VScodespaces](https://img.shields.io/endpoint?url=https%3A%2F%2Faka.ms%2Fvso-badge)](https://online.visualstudio.com/environments/new?name=caf%20landing%20zones&repo=azure/caf-terraform-landingzones)
|
||||||
[![Gitter](https://badges.gitter.im/aztfmod/community.svg)](https://gitter.im/aztfmod/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
[![Gitter](https://badges.gitter.im/aztfmod/community.svg)](https://gitter.im/aztfmod/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
||||||
|
|
||||||
# Azure Cloud Adoption Framework landing zones for Terraform
|
# Azure Cloud Adoption Framework landing zones for Terraform
|
||||||
|
|
||||||
Microsoft [Cloud Adoption Framework for Azure](https://aka.ms/caf) provides you with guidance and best practices to adopt Azure.
|
Microsoft [Cloud Adoption Framework for Azure](https://aka.ms/caf) provides you with guidance and best practices to adopt Azure.
|
||||||
|
@ -24,25 +23,64 @@ Cloud Adoption Framework for Azure Terraform landing zones is an Open Source pro
|
||||||
* Propose a prescriptive guidance on how to enable DevOps for infrastructure as code on Microsoft Azure.
|
* Propose a prescriptive guidance on how to enable DevOps for infrastructure as code on Microsoft Azure.
|
||||||
* Foster a community of Azure *Terraformers* using a common set of practices and sharing best practices.
|
* Foster a community of Azure *Terraformers* using a common set of practices and sharing best practices.
|
||||||
|
|
||||||
|
## What's new in this release
|
||||||
|
|
||||||
|
This release is relying extensively on Terraform 0.13 capabilities (module iterations, conditional modules, variables validation, etc.).
|
||||||
|
|
||||||
|
Those new features allow more complex and more dynamic code composition. The following concepts are used:
|
||||||
|
|
||||||
|
* **No-code environment composition**: a landing zone environment can be composed customizing variable files and code must be robust enough to accommodate combinations and composition.
|
||||||
|
* **Flexible foundations to meet customer needs**: everything is customizable at all layers.
|
||||||
|
* **Key-based configuration and customization**: all configuration objects will call each other based on the object keys.
|
||||||
|
* **Iteration-based objects deployment**: a landing zone calls all its modules, iterating on complex objects for technical resources deployment.
|
||||||
|
* **Enterprise-scale support**: added support for foundations landing zones to optionally leverage Azure Enterprise-scale module.
|
||||||
|
* **Terraform Cloud/Enterprise bootstrap**: added initial support for Hashicorp Terraform Cloud/Enterprise to support environment bootstrap.
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
See our [Getting Started](./documentation/getting_started/getting_started.md) on your laptop, or on the web with [Getting Started on VSCodespaces](./documentation/getting_started/getting_started_codespaces.md).
|
See our [Getting Started](./documentation/getting_started/getting_started.md) on your laptop, or on the web with [Getting Started on VSCodespaces](./documentation/getting_started/getting_started_codespaces.md).
|
||||||
|
|
||||||
See our [Getting Started Video](https://www.youtube.com/watch?v=t1exCkWft60)
|
See our [Getting Started Video](https://www.youtube.com/watch?v=t1exCkWft60)
|
||||||
|
|
||||||
|
## Sample configuration repository
|
||||||
|
|
||||||
|
When starting an enterprise deployment, we recommend you start creating a configuration repository where you start crafting you configuration environment.
|
||||||
|
|
||||||
|
You can find the [starter repository here](https://github.com/Azure/caf-terraform-landingzones-starter)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
More details on how to develop, deploy and operate with landing zones can be found in the reference section [here](./documentation/README.md)
|
More details on how to develop, deploy and operate with landing zones can be found in the reference section [here](./documentation/README.md)
|
||||||
|
|
||||||
## Sample landing zones
|
## Sample landing zones
|
||||||
|
|
||||||
Currently we provide you with the following sample landing zones:
|
Currently we provide you with the following core sample landing zones:
|
||||||
|
|
||||||
| Name | Purpose |
|
| Name | Purpose |
|
||||||
|---------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [landingzone_caf_foundations](./landingzones/landingzone_caf_foundations) | setup all the fundamentals for a subscription (logging, accounting, security.). You can find all details of the caf_foundations landing zone [Here](./landingzones/landingzone_caf_foundations/readme.md) |
|
| [caf_foundations](./landingzones/caf_foundations) | setup all the fundamentals for a subscription (logging, accounting, security.). You can find all details of the caf_foundations landing zone [Here](./landingzones/landingzone_caf_foundations/readme.md) |
|
||||||
| [landingzone_networking](./landingzones/landingzone_networking) | enables creation of any Azure networking combination of Virtual Networks-based hub-and-spoke topologies or Azure Virtual WAN based topologies. |
|
| [caf_networking](./landingzones/caf_networking) | enables creation of any Azure networking combination of Virtual Networks-based hub-and-spoke topologies or Azure Virtual WAN based topologies. |
|
||||||
| [launchpad](./landingzones/launchpad) | provides the state management capabilities and security features leveraging Azure storage for the backend, provides secret management and modular approach to support plugin for Azure DevOps automated pipeline creation (and others) |
|
| [caf_shared_services](./landingzones/caf_shared_services) | provides shared services like monitoring, Azure Backup, Azure Site Recovery etc. |
|
||||||
|
| [caf_launchpad](./landingzones/caf_launchpad) | provides the state management capabilities and security features leveraging Azure storage for the backend, provides secret management and modular approach to support plugin for Azure DevOps automated pipeline creation (and others) |
|
||||||
|
|
||||||
|
For each landing zones, we provide different level of configuration examples to meet different purposes:
|
||||||
|
| level | scenario | requirements |
|
||||||
|
|-------|----------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------|
|
||||||
|
| 100 | Start with this one! basic functionalities and features, no RBAC or security hardening - for demo and simple POC | working on any subscription with Owner permissions |
|
||||||
|
| 200 | intermediate functionalities includes diagnostics features and Azure Active Directory groups | may need custom AAD permissions |
|
||||||
|
| 300 | advanced functionalities, includes RBAC features, virtual network and private link scenario and reduced portal view for hardened items | need custom AAD permissions |
|
||||||
|
| 400 | advanced functionalities, includes RBAC features and security hardening | need custom AAD permissions |
|
||||||
|
|
||||||
|
## Landing zone solutions
|
||||||
|
|
||||||
|
Once you deploy the core components, you can leverage the following additional solution landing zones (work in progress!):
|
||||||
|
|
||||||
|
| Solution | URL |
|
||||||
|
|---------------------------|-------------------------------------------------------|
|
||||||
|
| Azure Kubernetes Services | https://github.com/aztfmod/landingzone_aks |
|
||||||
|
| Data and Analytics | https://github.com/aztfmod/landingzone_data_analytics |
|
||||||
|
| SAP HANA on Azure | Coming Soon |
|
||||||
|
| Shared Image Gallery | Coming soon |
|
||||||
|
|
||||||
## Repositories
|
## Repositories
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
# Setting up identity bootstrap account
|
||||||
|
|
||||||
|
The purpose of the CAF Level 0 (L0) bootstrap Azure AD application is to own the creation of the launchpads. During that process a new Azure AD application is created with less permissions on the directory and also more specific Azure permissions to fulfill the Azure operations of the
|
||||||
|
level0 (subscription creation for example)
|
||||||
|
|
||||||
|
This document explains the manual process to create the L0 Azure AD app and the following information must be captured:
|
||||||
|
|
||||||
|
| Variable | Item | Value |
|
||||||
|
| -------------------- | ------------------------ | ---- |
|
||||||
|
|ARM\_CLIENT\_ID | Application (client) ID | |
|
||||||
|
|ARM\_CLIENT\_SECRET | Client secret | |
|
||||||
|
|ARM\_TENANT\_ID | Directory (tenant) ID | |
|
||||||
|
|ARM\_SUBSCRIPTION\_ID | Subscription ID | |
|
||||||
|
|
||||||
|
## Create Azure AD L0 App
|
||||||
|
|
||||||
|
Go to Azure Active Directory
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image1.png)
|
||||||
|
|
||||||
|
Create a **new** Azure **Active Directory Application**
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image2.png)
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image3.png)
|
||||||
|
|
||||||
|
From the property pane select "**API permissions**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image4.png)
|
||||||
|
|
||||||
|
**Remove** the default one
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image5.png)
|
||||||
|
|
||||||
|
**Confirm the deletion**
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image6.png)
|
||||||
|
|
||||||
|
Click on "**Add a permission**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image7.png)
|
||||||
|
|
||||||
|
Select "**Application permissions**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image8.png)
|
||||||
|
|
||||||
|
Select from "**Application**", "**Application.ReadWrite.OwnedBy**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image9.png)
|
||||||
|
|
||||||
|
Then from "**Directory**" select "**Directory.ReadWrite.All**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image10.png)
|
||||||
|
|
||||||
|
Complete the operation by pressing the blue button "**Add permissions**"
|
||||||
|
|
||||||
|
Click again on "*Add permission*"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image11.png)
|
||||||
|
|
||||||
|
Select the "**Microsoft Graph**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image12.png)
|
||||||
|
|
||||||
|
Select "**Application permissions**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image13.png)
|
||||||
|
|
||||||
|
From "**AppRoleAssignment**" select "**AppRoleAssignment.ReadWrite.All**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image14.png)
|
||||||
|
|
||||||
|
From "**DelegatedPermissionGrant**" select "**DelegatedPermissionGrant.ReadWrite.All**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image15.png)
|
||||||
|
|
||||||
|
From "**Directory**" select "**Directory.ReadWrite.All**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/MSGraph_directory.png)
|
||||||
|
|
||||||
|
Complete the operation by clicking on the blue button "**Add permissions**"
|
||||||
|
|
||||||
|
You need to be logged-in with a user who has directory role "**Global Admin**" or permission to grant consents. When ready press the button "**Grant admin consent for \[name of your tenant\]**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/Grant_Admin_Consent.png)
|
||||||
|
|
||||||
|
Confirm
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image17.png)
|
||||||
|
|
||||||
|
You can see the consents have been given with the green tick button
|
||||||
|
|
||||||
|
![](./images/Bootstrap/Granted_Admin_Consent.png)
|
||||||
|
|
||||||
|
Now the Azure Active Directory Application has been created and given the right permission on the APIs, you need to set a complex password.
|
||||||
|
|
||||||
|
From the property pane select "**Certificates & secrets**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image19.png)
|
||||||
|
|
||||||
|
Click on "**New client secret**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image20.png)
|
||||||
|
|
||||||
|
Put a description -- *date of the creation of the secret* as an example
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image21.png)
|
||||||
|
|
||||||
|
When ready click on the blue button "Add". Note the password will be displayed only after the creation. Copy the password as you will not be able to retrieve it again later. If you missed that step, delete the password and recreate a new one.
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image22.png)
|
||||||
|
|
||||||
|
### Capture the tenant ID
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image23.png)
|
||||||
|
|
||||||
|
Capture the client ID
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image24.png)
|
||||||
|
|
||||||
|
### Capture the subscription ID
|
||||||
|
|
||||||
|
From the Azure Portal search bar, type "**Subscription**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image25.png)
|
||||||
|
|
||||||
|
Capture the subscription ID
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image26.png)
|
||||||
|
|
||||||
|
## Grant subscription owner to level0-security
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image25.png)
|
||||||
|
|
||||||
|
Click on the subscription
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image26.png)
|
||||||
|
|
||||||
|
Go to "**Access control (IAM)**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image27.png)
|
||||||
|
|
||||||
|
Select "**Add**".. "**Add role assignment**"
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image28.png)
|
||||||
|
|
||||||
|
Select Role as "**Owner**". Set the Azure Active Directory application name you created earlier.
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image29.png)
|
||||||
|
|
||||||
|
Click on the name and then on the "**save**" button
|
||||||
|
|
||||||
|
![](./images/Bootstrap/image30.png)
|
||||||
|
|
||||||
|
If all the steps have been completed successfully, you are ready to deploy the level 0 open source launchpad.
|
|
@ -0,0 +1,97 @@
|
||||||
|
# Enterprise Adoption Guide on Cloud Adoption Framework for Azure - Landing zones on Terraform
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
In this guide, we summarize steps to get started in an enteprise environment.
|
||||||
|
|
||||||
|
|
||||||
|
# Get Started (Step By Step)
|
||||||
|
|
||||||
|
![](./images/Enterprise/Getting_Started.png)
|
||||||
|
|
||||||
|
## Azure Sandpit Environment
|
||||||
|
|
||||||
|
Successful implementations tend to focus on building first a sandpit/innovation hub environment where all stakeholders (IT operations, security, compliance, information protection, finance, and business) define their requirements.
|
||||||
|
|
||||||
|
The DevOps team focuses on building, automating, testing modules, and landing zones to create an infrastructure environment that is good enough.
|
||||||
|
|
||||||
|
We define a sandpit environment as an environment where innovation and experimentations can happen "freely".
|
||||||
|
As such is it composed of:
|
||||||
|
- One or more subscriptions that are isolated from ANY customer environment.
|
||||||
|
- A separate Azure AD tenant space.
|
||||||
|
|
||||||
|
## Azure DevOps
|
||||||
|
|
||||||
|
### Projects
|
||||||
|
|
||||||
|
Ideally multiple projects needed to fully utilize Azure landing zones capabilities:
|
||||||
|
|
||||||
|
* **Main Project** - Repository of your private Terraform code and project management for landing zones adoption in your organization
|
||||||
|
* **Configuration Projects** - For each environments (Production, Non-production, Sandpit) that you plan to leverage Azure Terraform landing zone, dedicated project in Azure Devops is needed to fully utilize the automation mechanism provided. This will reduce the risk and minimize error on mixing environments configuration files(.tfvars),pipelines and variables.
|
||||||
|
|
||||||
|
Examples Azure DevOps setup:
|
||||||
|
|
||||||
|
| Organization | Project | Purpose |
|
||||||
|
| ------------ | ------- | ------- |
|
||||||
|
| Contoso | Azure Terraform Landing Zone | Project Management of LZ and Repository for custom terraform code that specific to Contoso requirements |
|
||||||
|
| Contoso | contososandpit | Repo to Store configuration file (tfvars), Pipeline, agent pool specific to sandpit |
|
||||||
|
| Contoso | contosodev | Repo to Store configuration file (tfvars), Pipeline, agent pool specific to nonprod |
|
||||||
|
| Contoso | contosoprod | Repo to Store configuration file (tfvars), Pipeline, agent pool specific to prod |
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
#### Sandpit IaC Configuration:
|
||||||
|
|
||||||
|
![](./images/Enterprise/Sandpit_IAC.png)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
#### Prod & NonProd IaC Configuration:
|
||||||
|
|
||||||
|
![](./images/Enterprise/Prod_NonPROD_IAC.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Repositories
|
||||||
|
|
||||||
|
During the lifecycle of the landing zones deployment you will probably find that it is easier to work first with a mono-repository environment but we recommend using multiple repositories as follow:
|
||||||
|
* **Configuration repository**: [this template can be used](https://github.com/azure/caf-terraform-landingzones-starter) as configuration repository for CAF landing zones, containing definition of the configuration for your different environments.
|
||||||
|
* **Logic repository**: this Azure CAF landing zone repository. Documentation to come on how to fork this repository.
|
||||||
|
|
||||||
|
This approach allows you to easily:
|
||||||
|
* check-in your configuration in your specific Git repository.
|
||||||
|
* resync the code with the public codebase for updates.
|
||||||
|
* customize the code if needed and contribute back to the community.
|
||||||
|
|
||||||
|
### Full IaC Architecture (Contoso example)
|
||||||
|
|
||||||
|
![](./images/Enterprise/environment_seperation.png)
|
||||||
|
|
||||||
|
## Bootstrap process
|
||||||
|
|
||||||
|
### Bootstrap identity
|
||||||
|
In order to start consuming Azure Terraform landing zones, we need to create a privileged account to boostrap the environment.
|
||||||
|
|
||||||
|
You can opt for:
|
||||||
|
1. Using an user account with enough permission (Azure Active Directory Global Administrator)
|
||||||
|
2. Provision the identity bootstrap account with Azure AD application, you can refer to [the following documentation](./bootstrap_account_provisioning.md)
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
Once you done on those 3 important steps your organization is ready to adopt Azure Terraform Landing Zone. You can start by [following this documentation](../getting_started/getting_started.md) in order to setup your local development environment.
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
*if you are using Azure AD application for bootstrapping you might need to login with below command (with all the details from previous step [from following documentation](./bootstrap_account_provisioning.md)):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export ARM_CLIENT_ID=
|
||||||
|
export ARM_CLIENT_SECRET=
|
||||||
|
export ARM_TENANT_ID=
|
||||||
|
export ARM_SUBSCRIPTION_ID=
|
||||||
|
|
||||||
|
az login --service-principal -u ${ARM_CLIENT_ID} -p ${ARM_CLIENT_SECRET} --tenant ${ARM_TENANT_ID}
|
||||||
|
az account set --subscription ${ARM_SUBSCRIPTION_ID}
|
||||||
|
```
|
||||||
|
|
||||||
|
You are good to go. Start with launchpad and continue with higher level landing zones.
|
После Ширина: | Высота: | Размер: 35 KiB |
После Ширина: | Высота: | Размер: 36 KiB |
После Ширина: | Высота: | Размер: 7.1 KiB |
После Ширина: | Высота: | Размер: 45 KiB |
После Ширина: | Высота: | Размер: 14 KiB |
После Ширина: | Высота: | Размер: 1.8 KiB |
После Ширина: | Высота: | Размер: 15 KiB |
После Ширина: | Высота: | Размер: 16 KiB |
После Ширина: | Высота: | Размер: 12 KiB |
После Ширина: | Высота: | Размер: 12 KiB |
После Ширина: | Высота: | Размер: 46 KiB |
После Ширина: | Высота: | Размер: 9.9 KiB |
После Ширина: | Высота: | Размер: 47 KiB |
После Ширина: | Высота: | Размер: 4.5 KiB |
После Ширина: | Высота: | Размер: 18 KiB |
После Ширина: | Высота: | Размер: 13 KiB |
После Ширина: | Высота: | Размер: 10 KiB |
После Ширина: | Высота: | Размер: 6.9 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 25 KiB |
После Ширина: | Высота: | Размер: 7.9 KiB |
После Ширина: | Высота: | Размер: 6.9 KiB |
После Ширина: | Высота: | Размер: 6.6 KiB |
После Ширина: | Высота: | Размер: 5.5 KiB |
После Ширина: | Высота: | Размер: 30 KiB |
После Ширина: | Высота: | Размер: 70 KiB |
После Ширина: | Высота: | Размер: 9.8 KiB |
После Ширина: | Высота: | Размер: 4.2 KiB |
После Ширина: | Высота: | Размер: 29 KiB |
После Ширина: | Высота: | Размер: 14 KiB |
После Ширина: | Высота: | Размер: 89 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 18 KiB |
После Ширина: | Высота: | Размер: 38 KiB |
После Ширина: | Высота: | Размер: 163 KiB |
После Ширина: | Высота: | Размер: 152 KiB |
После Ширина: | Высота: | Размер: 71 KiB |
|
@ -40,8 +40,6 @@ You will have to accept local mapping to your filesystem when Docker prompts you
|
||||||
|
|
||||||
After a while, your environment is ready, note on the lower left part of Visual Studio Code, that you are now in your Azure CAF rover, which is your environment to use Azure landing zones.
|
After a while, your environment is ready, note on the lower left part of Visual Studio Code, that you are now in your Azure CAF rover, which is your environment to use Azure landing zones.
|
||||||
|
|
||||||
## Deploying your first landing zone
|
|
||||||
|
|
||||||
You must be authenticated first:
|
You must be authenticated first:
|
||||||
For that we will rely on Azure authentication as completed by Azure Cli, via browser method:
|
For that we will rely on Azure authentication as completed by Azure Cli, via browser method:
|
||||||
|
|
||||||
|
@ -55,35 +53,52 @@ We recommend that you verify the output of the login and make sure the subscript
|
||||||
az account set --subscription <subscription_GUID>
|
az account set --subscription <subscription_GUID>
|
||||||
```
|
```
|
||||||
|
|
||||||
On the first run, you need to use the launchpad to create the foundations for Terraform environment:
|
## Deploying the DevOps requirements
|
||||||
|
|
||||||
|
On the first run, you need to use the launchpad to create the foundations for Terraform environment. This will set storage accounts to store the state files, and key vaults to get you started with a secure environment. It can eventually be upgraded to support your DevOps environment (pipelines, etc.)
|
||||||
|
|
||||||
|
You can find more information on the launchpad settings [Here](../../landingzones/caf_launchpad)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rover -lz /tf/caf/landingzones/launchpad -a apply -launchpad
|
rover -launchpad -lz /tf/caf/landingzones/caf_launchpad \
|
||||||
|
-var-folder /tf/caf/landingzones/caf_launchpad/scenario/100 \
|
||||||
|
-a apply
|
||||||
```
|
```
|
||||||
|
|
||||||
This command will interactively prompt you for *var.location*, asking for the name of a supported Azure region **where you want to deploy the Terraform state and dependencies**. You can specify that in the argument as in the following example:
|
## Deploying the foundations
|
||||||
|
|
||||||
|
Next step is to deploy the foundations (this typically could include management groups, policies, etc.). We can start with it empty, and enrich it later.
|
||||||
|
|
||||||
|
You can find more information on the launchpad settings [Here](../../landingzones/caf_launchpad)
|
||||||
|
|
||||||
|
|
||||||
|
Get started with the basic foundations:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rover -lz /tf/caf/landingzones/launchpad -a apply -launchpad -var 'location=westus'
|
rover -lz /tf/caf/landingzones/caf_foundations \
|
||||||
|
-level level1 \
|
||||||
|
-a apply
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then launch your first landing zone!
|
## Deploying a networking scenario
|
||||||
|
|
||||||
Please note that each landing zone come with its own deployment settings, which may deploy resources in different region than where you set the foundations.
|
You can deploy one of the typical Azure network topologies (hub, hub and spoke, Virtual WAN).
|
||||||
|
|
||||||
You are ready to start:
|
Have a look at the example scenario [Here](../../landingzones/caf_networking) and pick one you want to deploy.
|
||||||
|
|
||||||
|
You can deploy a simple hub networking using:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rover -lz /tf/caf/landingzones/landingzone_caf_foundations -a plan
|
rover -lz /tf/caf/landingzones/caf_networking \
|
||||||
|
-level level2 \
|
||||||
|
-var-folder /tf/caf/landingzones/caf_networking/scenario/100-single-region-hub \
|
||||||
|
-a apply
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
## Destroying your test
|
||||||
rover -lz /tf/caf/landingzones/landingzone_caf_foundations -a apply
|
|
||||||
```
|
Once you are done testing, just use the same commands as before, juste replace the last line ```-a apply``` by ```-a destroy```.
|
||||||
|
|
||||||
```bash
|
|
||||||
rover -lz /tf/caf/landingzones/landingzone_caf_foundations -a destroy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating your development environment
|
## Updating your development environment
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ Open a Terminal using ```CTRL``` + ```J``` or ```Command``` + ```J```
|
||||||
You are ready to use landing zones by launching the rover as below:
|
You are ready to use landing zones by launching the rover as below:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/tf/rover/rover.sh
|
rover
|
||||||
```
|
```
|
||||||
|
|
||||||
![Create](../../_pictures/getting_started/vs_codespaces_rover.png)
|
![Create](../../_pictures/getting_started/vs_codespaces_rover.png)
|
||||||
|
@ -47,7 +47,7 @@ You must be authenticated first:
|
||||||
For that we will rely on Azure authentication as completed by Azure Cli, via browser method:
|
For that we will rely on Azure authentication as completed by Azure Cli, via browser method:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/tf/rover/rover.sh login
|
rover login
|
||||||
```
|
```
|
||||||
|
|
||||||
We recommend that you verify the output of the login and make sure the subscription selected by default is the one you want to work on. If not, you can use the following switch:
|
We recommend that you verify the output of the login and make sure the subscription selected by default is the one you want to work on. If not, you can use the following switch:
|
||||||
|
@ -56,34 +56,49 @@ We recommend that you verify the output of the login and make sure the subscript
|
||||||
az account set --subscription <subscription_GUID>
|
az account set --subscription <subscription_GUID>
|
||||||
```
|
```
|
||||||
|
|
||||||
On the first run, you need to apply the launchpad as the first landing zone:
|
|
||||||
|
## Deploying the DevOps requirements
|
||||||
|
|
||||||
|
On the first run, you need to use the launchpad to create the foundations for Terraform environment. This will set storage accounts to store the state files, and key vaults to get you started with a secure environment. It can eventually be upgraded to support your DevOps environment (pipelines, etc.)
|
||||||
|
|
||||||
|
You can find more information on the launchpad settings [Here](../../landingzones/caf_launchpad)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/tf/rover/rover.sh -lz /tf/caf/landingzones/launchpad -a apply -launchpad
|
rover -launchpad -lz /tf/caf/landingzones/caf_launchpad \
|
||||||
|
-var-folder /tf/caf/landingzones/caf_launchpad/scenario/100 \
|
||||||
|
-a apply
|
||||||
```
|
```
|
||||||
|
|
||||||
You can specify a location for the launchpad using the following command:
|
## Deploying the foundations
|
||||||
|
|
||||||
|
Next step is to deploy the foundations (this typically could include management groups, policies, etc.). We can start with it empty, and enrich it later.
|
||||||
|
|
||||||
|
You can find more information on the launchpad settings [Here](../../landingzones/caf_launchpad)
|
||||||
|
|
||||||
|
|
||||||
|
Get started with the basic foundations:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/tf/rover/rover.sh -lz /tf/caf/landingzones/launchpad -a apply -launchpad -var location=westus
|
rover -lz /tf/caf/landingzones/caf_foundations \
|
||||||
|
-level level1 \
|
||||||
|
-a apply
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then launch your first landing zone!
|
## Deploying a networking scenario
|
||||||
|
|
||||||
Please note that each landing zone come with its own deployment settings, which may deploy resources in different region than where you set the foundations.
|
You can deploy one of the typical Azure network topologies (hub, hub and spoke, Virtual WAN).
|
||||||
|
|
||||||
You are ready to start:
|
Have a look at the example scenario [Here](../../landingzones/caf_networking) and pick one you want to deploy.
|
||||||
|
|
||||||
|
You can deploy a simple hub networking using:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/tf/rover/rover.sh -lz /tf/caf/landingzones/landingzone_caf_foundations -a plan
|
rover -lz /tf/caf/landingzones/caf_networking \
|
||||||
|
-level level2 \
|
||||||
|
-var-folder /tf/caf/landingzones/caf_networking/scenario/100-single-region-hub \
|
||||||
|
-a apply
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
## Destroying your test
|
||||||
/tf/rover/rover.sh -lz /tf/caf/landingzones/landingzone_caf_foundations -a apply
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
Once you are done testing, just use the same commands as before, juste replace the last line ```-a apply``` by ```-a destroy```.
|
||||||
/tf/rover/rover.sh -lz /tf/caf/landingzones/landingzone_caf_foundations -a destroy
|
|
||||||
```
|
|
||||||
|
|
||||||
Happy deployment with Azure landing zones, let us know your feedback and how you need it to evolve.
|
|
||||||
|
|
|
@ -1,225 +0,0 @@
|
||||||
# Sample Cloud Adoption Framework foundations landing zone
|
|
||||||
|
|
||||||
## globalsettings
|
|
||||||
global_settings = {
|
|
||||||
#specifies the set of locations you are going to use in this landing zone
|
|
||||||
location_map = {
|
|
||||||
southeastasia = "southeastasia"
|
|
||||||
eastasia = "eastasia"
|
|
||||||
}
|
|
||||||
|
|
||||||
#naming convention to be used as defined in naming convention module, accepted values are cafclassic, cafrandom, random, passthrough
|
|
||||||
convention = "cafrandom"
|
|
||||||
|
|
||||||
#Set of tags for core operations
|
|
||||||
tags_hub = {
|
|
||||||
owner = "CAF"
|
|
||||||
deploymentType = "Terraform"
|
|
||||||
costCenter = "1664"
|
|
||||||
BusinessUnit = "SHARED"
|
|
||||||
DR = "NON-DR-ENABLED"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set of resource groups to land the foundations
|
|
||||||
resource_groups_hub = {
|
|
||||||
southeastasia = {
|
|
||||||
HUB-CORE-SEC = {
|
|
||||||
name = "hub-core-sec-sea"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
HUB-OPERATIONS = {
|
|
||||||
name = "hub-operations-sea"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eastasia = {
|
|
||||||
HUB-CORE-SEC = {
|
|
||||||
name = "hub-core-sec-hk"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
HUB-OPERATIONS = {
|
|
||||||
name = "hub-operations-hk"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## accounting settings
|
|
||||||
accounting_settings = {
|
|
||||||
|
|
||||||
# Azure diagnostics logs retention period
|
|
||||||
southeastasia = {
|
|
||||||
# Azure Subscription activity logs retention period
|
|
||||||
azure_activity_log_enabled = false
|
|
||||||
azure_activity_logs_name = "actlogs"
|
|
||||||
azure_activity_logs_event_hub = false
|
|
||||||
azure_activity_logs_retention = 365
|
|
||||||
azure_activity_audit = {
|
|
||||||
log = [
|
|
||||||
# ["Audit category name", "Audit enabled)"]
|
|
||||||
["Administrative", true],
|
|
||||||
["Security", true],
|
|
||||||
["ServiceHealth", true],
|
|
||||||
["Alert", true],
|
|
||||||
["Recommendation", true],
|
|
||||||
["Policy", true],
|
|
||||||
["Autoscale", true],
|
|
||||||
["ResourceHealth", true],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
azure_diagnostics_logs_name = "diaglogs"
|
|
||||||
azure_diagnostics_logs_event_hub = false
|
|
||||||
|
|
||||||
#Logging and monitoring
|
|
||||||
analytics_workspace_name = "caflalogs-sg"
|
|
||||||
|
|
||||||
##Log analytics solutions to be deployed
|
|
||||||
solution_plan_map = {
|
|
||||||
NetworkMonitoring = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/NetworkMonitoring"
|
|
||||||
},
|
|
||||||
ADAssessment = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/ADAssessment"
|
|
||||||
},
|
|
||||||
ADReplication = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/ADReplication"
|
|
||||||
},
|
|
||||||
AgentHealthAssessment = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/AgentHealthAssessment"
|
|
||||||
},
|
|
||||||
DnsAnalytics = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/DnsAnalytics"
|
|
||||||
},
|
|
||||||
ContainerInsights = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/ContainerInsights"
|
|
||||||
},
|
|
||||||
KeyVaultAnalytics = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/KeyVaultAnalytics"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eastasia = {
|
|
||||||
# Azure Subscription activity logs retention period
|
|
||||||
azure_activity_log_enabled = false
|
|
||||||
azure_activity_logs_name = "actlogs"
|
|
||||||
azure_activity_logs_event_hub = false
|
|
||||||
azure_activity_logs_retention = 365
|
|
||||||
azure_activity_audit = {
|
|
||||||
log = [
|
|
||||||
# ["Audit category name", "Audit enabled)"]
|
|
||||||
["Administrative", true],
|
|
||||||
["Security", true],
|
|
||||||
["ServiceHealth", true],
|
|
||||||
["Alert", true],
|
|
||||||
["Recommendation", true],
|
|
||||||
["Policy", true],
|
|
||||||
["Autoscale", true],
|
|
||||||
["ResourceHealth", true],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
azure_diagnostics_logs_name = "diaglogs"
|
|
||||||
azure_diagnostics_logs_event_hub = false
|
|
||||||
|
|
||||||
#Logging and monitoring
|
|
||||||
analytics_workspace_name = "caflalogs-hk"
|
|
||||||
|
|
||||||
##Log analytics solutions to be deployed
|
|
||||||
solution_plan_map = {
|
|
||||||
NetworkMonitoring = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/NetworkMonitoring"
|
|
||||||
},
|
|
||||||
ADAssessment = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/ADAssessment"
|
|
||||||
},
|
|
||||||
ADReplication = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/ADReplication"
|
|
||||||
},
|
|
||||||
AgentHealthAssessment = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/AgentHealthAssessment"
|
|
||||||
},
|
|
||||||
DnsAnalytics = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/DnsAnalytics"
|
|
||||||
},
|
|
||||||
ContainerInsights = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/ContainerInsights"
|
|
||||||
},
|
|
||||||
KeyVaultAnalytics = {
|
|
||||||
"publisher" = "Microsoft"
|
|
||||||
"product" = "OMSGallery/KeyVaultAnalytics"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## governance
|
|
||||||
governance_settings = {
|
|
||||||
southeastasia = {
|
|
||||||
#current code supports only two levels of managemenr groups and one root
|
|
||||||
deploy_mgmt_groups = false
|
|
||||||
management_groups = {
|
|
||||||
root = {
|
|
||||||
name = "caf-rootmgmtgroup"
|
|
||||||
subscriptions = []
|
|
||||||
#list your subscriptions ID in this field as ["GUID1", "GUID2"]
|
|
||||||
children = {
|
|
||||||
child1 = {
|
|
||||||
name = "tree1child1"
|
|
||||||
subscriptions = []
|
|
||||||
}
|
|
||||||
child2 = {
|
|
||||||
name = "tree1child2"
|
|
||||||
subscriptions = []
|
|
||||||
}
|
|
||||||
child3 = {
|
|
||||||
name = "tree1child3"
|
|
||||||
subscriptions = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
policy_matrix = {
|
|
||||||
#autoenroll_asc = true - to be implemented via builtin policies
|
|
||||||
autoenroll_monitor_vm = true
|
|
||||||
autoenroll_netwatcher = false
|
|
||||||
|
|
||||||
no_public_ip_spoke = false
|
|
||||||
cant_create_ip_spoke = false
|
|
||||||
managed_disks_only = true
|
|
||||||
restrict_locations = false
|
|
||||||
list_of_allowed_locs = ["southeastasia", "eastasia"]
|
|
||||||
restrict_supported_svc = false
|
|
||||||
list_of_supported_svc = ["Microsoft.Network/publicIPAddresses", "Microsoft.Compute/disks"]
|
|
||||||
msi_location = "southeastasia"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eastasia = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
## security
|
|
||||||
security_settings = {
|
|
||||||
#Azure Security Center Configuration
|
|
||||||
enable_security_center = false
|
|
||||||
security_center = {
|
|
||||||
contact_email = "email@email.com"
|
|
||||||
contact_phone = "9293829328"
|
|
||||||
alerts_to_admins = true
|
|
||||||
alert_notifications = true
|
|
||||||
}
|
|
||||||
#Enables Azure Sentinel on the Log Analaytics repo
|
|
||||||
enable_sentinel = true
|
|
||||||
}
|
|
|
@ -1,172 +0,0 @@
|
||||||
# Configuration sample for Azure Virtual WAN hub and spoke
|
|
||||||
virtual_hub_config = {
|
|
||||||
virtual_wan = {
|
|
||||||
resource_group_name = "virtualwan"
|
|
||||||
name = "ContosovWAN"
|
|
||||||
dns_name = "private.contoso.com"
|
|
||||||
|
|
||||||
hubs = {
|
|
||||||
hub1 = {
|
|
||||||
hub_name = "SEA-HUB"
|
|
||||||
region = "southeastasia"
|
|
||||||
hub_address_prefix = "10.0.3.0/24"
|
|
||||||
deploy_firewall = true
|
|
||||||
peerings = {}
|
|
||||||
firewall_name = "azfwsg"
|
|
||||||
firewall_resource_groupe_name = "azfwsg"
|
|
||||||
deploy_p2s = false
|
|
||||||
p2s_config = {
|
|
||||||
name = "caf-sea-vpn-p2s"
|
|
||||||
scale_unit = 2
|
|
||||||
connection_configuration = {
|
|
||||||
name = "client-connections"
|
|
||||||
vpn_client_address_pool = {
|
|
||||||
address_prefixes = ["192.168.0.0/24"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
server_config = {
|
|
||||||
vpn_authentication_types = ["Certificate"]
|
|
||||||
client_root_certificate = {
|
|
||||||
name = "DigiCert-Federated-ID-Root-CA"
|
|
||||||
public_cert_data = <<EOF
|
|
||||||
MIIDuzCCAqOgAwIBAgIQCHTZWCM+IlfFIRXIvyKSrjANBgkqhkiG9w0BAQsFADBn
|
|
||||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
|
||||||
d3cuZGlnaWNlcnQuY29tMSYwJAYDVQQDEx1EaWdpQ2VydCBGZWRlcmF0ZWQgSUQg
|
|
||||||
Um9vdCBDQTAeFw0xMzAxMTUxMjAwMDBaFw0zMzAxMTUxMjAwMDBaMGcxCzAJBgNV
|
|
||||||
BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp
|
|
||||||
Y2VydC5jb20xJjAkBgNVBAMTHURpZ2lDZXJ0IEZlZGVyYXRlZCBJRCBSb290IENB
|
|
||||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvAEB4pcCqnNNOWE6Ur5j
|
|
||||||
QPUH+1y1F9KdHTRSza6k5iDlXq1kGS1qAkuKtw9JsiNRrjltmFnzMZRBbX8Tlfl8
|
|
||||||
zAhBmb6dDduDGED01kBsTkgywYPxXVTKec0WxYEEF0oMn4wSYNl0lt2eJAKHXjNf
|
|
||||||
GTwiibdP8CUR2ghSM2sUTI8Nt1Omfc4SMHhGhYD64uJMbX98THQ/4LMGuYegou+d
|
|
||||||
GTiahfHtjn7AboSEknwAMJHCh5RlYZZ6B1O4QbKJ+34Q0eKgnI3X6Vc9u0zf6DH8
|
|
||||||
Dk+4zQDYRRTqTnVO3VT8jzqDlCRuNtq6YvryOWN74/dq8LQhUnXHvFyrsdMaE1X2
|
|
||||||
DwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNV
|
|
||||||
HQ4EFgQUGRdkFnbGt1EWjKwbUne+5OaZvRYwHwYDVR0jBBgwFoAUGRdkFnbGt1EW
|
|
||||||
jKwbUne+5OaZvRYwDQYJKoZIhvcNAQELBQADggEBAHcqsHkrjpESqfuVTRiptJfP
|
|
||||||
9JbdtWqRTmOf6uJi2c8YVqI6XlKXsD8C1dUUaaHKLUJzvKiazibVuBwMIT84AyqR
|
|
||||||
QELn3e0BtgEymEygMU569b01ZPxoFSnNXc7qDZBDef8WfqAV/sxkTi8L9BkmFYfL
|
|
||||||
uGLOhRJOFprPdoDIUBB+tmCl3oDcBy3vnUeOEioz8zAkprcb3GHwHAK+vHmmfgcn
|
|
||||||
WsfMLH4JCLa/tRYL+Rw/N3ybCkDp00s0WUZ+AoDywSl0Q/ZEnNY0MsFiw6LyIdbq
|
|
||||||
M/s/1JRtO3bDSzD9TazRVzn2oBqzSa8VgIo5C1nOnoAKJTlsClJKvIhnRlaLQqk=
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deploy_s2s = false
|
|
||||||
s2s_config = {
|
|
||||||
name = "caf-sea-vpn-s2s"
|
|
||||||
scale_unit = 1
|
|
||||||
}
|
|
||||||
deploy_er = false
|
|
||||||
er_config = {
|
|
||||||
name = "caf-sea-er"
|
|
||||||
scale_units = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
hub2 = {
|
|
||||||
hub_name = "HK-HUB"
|
|
||||||
region = "eastasia"
|
|
||||||
hub_address_prefix = "10.0.4.0/24"
|
|
||||||
deploy_firewall = true
|
|
||||||
firewall_name = "azfhk"
|
|
||||||
firewall_resource_groupe_name = "azfhk"
|
|
||||||
peerings = {
|
|
||||||
## this key must match with the key of the virtual network declared in the var.spokes structure
|
|
||||||
spoke1 = {
|
|
||||||
# TODO: add support for remote_virtual_network_id = <ID of the virtual network>
|
|
||||||
# optional if the virtual network has been provisionned outside.
|
|
||||||
hub_to_vitual_network_traffic_allowed = true
|
|
||||||
vitual_network_to_hub_gateways_traffic_allowed = true
|
|
||||||
internet_security_enabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deploy_p2s = false
|
|
||||||
p2s_config = {}
|
|
||||||
deploy_s2s = false
|
|
||||||
s2s_config = {}
|
|
||||||
deploy_er = false
|
|
||||||
er_config = {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spokes = {
|
|
||||||
spoke1 = {
|
|
||||||
rg = {
|
|
||||||
name = "virtualhub-spoke-test"
|
|
||||||
location = "eastasia"
|
|
||||||
}
|
|
||||||
peering_name = "spoke1-hub-hk-link"
|
|
||||||
network = {
|
|
||||||
vnet = {
|
|
||||||
name = "Core-Network"
|
|
||||||
address_space = ["10.0.10.0/24"]
|
|
||||||
}
|
|
||||||
specialsubnets = {}
|
|
||||||
|
|
||||||
subnets = {
|
|
||||||
subnet0 = {
|
|
||||||
name = "Web_tier"
|
|
||||||
cidr = ["10.0.10.0/26"]
|
|
||||||
nsg_name = "Web_tier_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "HTTP-In",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "80"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "HTTPS-In",
|
|
||||||
priority = "101"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "443"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet2 = {
|
|
||||||
name = "Data_tier"
|
|
||||||
cidr = ["10.0.10.128/26"]
|
|
||||||
nsg_name = "Data_tier_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "TDS-In",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "1433"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,435 +0,0 @@
|
||||||
# Configuration sample for a hub and spoke environment
|
|
||||||
# definition of variables for the virtual network
|
|
||||||
rg_network = {
|
|
||||||
CORE-NET = {
|
|
||||||
name = "network-core"
|
|
||||||
}
|
|
||||||
TRANSIT-NET = {
|
|
||||||
name = "network-transit"
|
|
||||||
}
|
|
||||||
EDGE-NET = {
|
|
||||||
name = "network-edge"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# settings for the core network blueprint
|
|
||||||
core_networking = {
|
|
||||||
shared_services_vnet = {
|
|
||||||
vnet = {
|
|
||||||
name = "Core-Network"
|
|
||||||
address_space = ["10.0.0.0/8"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
AzureFirewallSubnet = {
|
|
||||||
name = "AzureFirewallSubnet" #Must be called AzureFirewallSubnet
|
|
||||||
cidr = ["10.0.4.0/24"]
|
|
||||||
}
|
|
||||||
GatewaySubnet = {
|
|
||||||
name = "GatewaySubnet" #Must be called GateWaySubnet in order to host a Virtual Network Gateway
|
|
||||||
cidr = ["10.0.255.224/27"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet0 = {
|
|
||||||
name = "Active_Directory"
|
|
||||||
cidr = ["10.0.1.0/24"]
|
|
||||||
nsg_name = "Active_Directory_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "W32Time",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "123"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "RPC-Endpoint-Mapper",
|
|
||||||
priority = "101"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "135"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "Kerberos-password-change",
|
|
||||||
priority = "102"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "464"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "RPC-Dynamic-range",
|
|
||||||
priority = "103"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "49152-65535"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP",
|
|
||||||
priority = "104"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "389"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP-SSL",
|
|
||||||
priority = "105"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "636"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP-GC",
|
|
||||||
priority = "106"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "3268"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP-GC-SSL",
|
|
||||||
priority = "107"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "3269"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "DNS",
|
|
||||||
priority = "108"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "53"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "Kerberos",
|
|
||||||
priority = "109"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "88"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "SMB",
|
|
||||||
priority = "110"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "445"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet1 = {
|
|
||||||
name = "AzureBastionSubnet" #Must be called AzureBastionSubnet
|
|
||||||
cidr = ["10.0.0.128/25"]
|
|
||||||
nsg_name = "AzureBastionSubnet_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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for Azure Firewall
|
|
||||||
# Must be standard and static for
|
|
||||||
firewall_ip_addr_config = {
|
|
||||||
ip_name = "firewall"
|
|
||||||
allocation_method = "Static"
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Azure Firewall settings
|
|
||||||
az_fw_config = {
|
|
||||||
name = "azfw"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureFirewallApplicationRule", true, true, 30],
|
|
||||||
["AzureFirewallNetworkRule", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the UDR object
|
|
||||||
udr_web_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "0.0.0.0/0"
|
|
||||||
route_name = "web_to_az_firewall"
|
|
||||||
subnet_to_udr = "Web_tier"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
udr_transit_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "10.0.1.0/24"
|
|
||||||
route_name = "transit_to_az_firewall"
|
|
||||||
subnet_to_udr = "GatewaySubnet"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
## DDoS standard configuration
|
|
||||||
enable_ddos_standard = false
|
|
||||||
ddos_name = "ddos_protection_plan"
|
|
||||||
|
|
||||||
## settings for Azure bastion configuration
|
|
||||||
## not enabled, uncomment the code in the networking shared services blueprint.
|
|
||||||
enable_bastion = false
|
|
||||||
bastion_ip_addr_config = {
|
|
||||||
ip_name = "bastion"
|
|
||||||
ip_addr = {
|
|
||||||
allocation_method = "Static"
|
|
||||||
#Dynamic Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure
|
|
||||||
|
|
||||||
#properties below are optional
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
#dns_prefix = "arnaudmytest"
|
|
||||||
#timeout = 15 #TCP timeout for idle connections. The value can be set between 4 and 30 minutes.
|
|
||||||
#zones = [1] #1 zone number, IP address must be standard, ZoneRedundant argument is not supported in provider at time of writing
|
|
||||||
#reverse_fqdn = ""
|
|
||||||
#public_ip_prefix_id = "/subscriptions/00000000-00000-0000-0000-000000000000/resourceGroups/uqvh-hub-ingress-net/providers/Microsoft.Network/publicIPPrefixes/myprefix"
|
|
||||||
#refer to the prefix and check sku types are same in IP and prefix
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bastion_config = {
|
|
||||||
name = "azurebastion"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["BastionAuditLogs", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
# ["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Settings for the Virtual Network gateway to be created
|
|
||||||
provision_gateway = false
|
|
||||||
gateway_config = {
|
|
||||||
gateway_type = "VPN"
|
|
||||||
# Possible values are "VPN" or "ExpressRoute"
|
|
||||||
vpn_gateway_name = "vpngateway"
|
|
||||||
active_active = false
|
|
||||||
#An active-active gateway requires a HighPerformance or an UltraPerformance sku. If false, an active-standby gateway will be created. Defaults to false.
|
|
||||||
enable_bgp = false
|
|
||||||
#If true, BGP (Border Gateway Protocol) will be enabled for this Virtual Network Gateway. Defaults to false.
|
|
||||||
vpn_gateway_sku = "Basic"
|
|
||||||
#Valid options are Basic, Standard, HighPerformance, UltraPerformance, ErGw1AZ, ErGw2AZ, ErGw3AZ, VpnGw1, VpnGw2, VpnGw3, VpnGw1AZ, VpnGw2AZ, and VpnGw3AZ
|
|
||||||
#and depend on the gateway_type (ER or VPN) and vpn_type arguments, ie: PolicyBased gateway only supports the Basic sku.
|
|
||||||
vpn_gateway_type = "RouteBased"
|
|
||||||
#The routing type of the Virtual Network Gateway. Valid options are RouteBased or PolicyBased. Defaults to RouteBased.
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["GatewayDiagnosticLog", true, true, 30],
|
|
||||||
["TunnelDiagnosticLog", true, true, 30],
|
|
||||||
["RouteDiagnosticLog", true, true, 30],
|
|
||||||
["IKEDiagnosticLog", true, true, 30],
|
|
||||||
["P2SDiagnosticLog", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
pip = {
|
|
||||||
name = "vpn"
|
|
||||||
allocation_method = "Dynamic"
|
|
||||||
sku = "Basic"
|
|
||||||
#For basic SKU, you can pick the zone to be deployed - if you want multi zone - pick Standard IP and pick AZ aware VPN gateway SKU
|
|
||||||
#dns_prefix = "arnaudvpn"
|
|
||||||
#zones = ["1"]
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Settings for the connection to be established
|
|
||||||
#Settings for the local network connection
|
|
||||||
connection_name = "onpremconnection"
|
|
||||||
remote_network_connect = true
|
|
||||||
|
|
||||||
remote_network = {
|
|
||||||
gateway_name = "caf_local_network"
|
|
||||||
gateway_ip = "1.2.3.4"
|
|
||||||
gateway_adress_space = ["1.0.0.0/8"]
|
|
||||||
|
|
||||||
bgp_settings = {
|
|
||||||
# asn =
|
|
||||||
# bgp_peering_address =
|
|
||||||
# peer_weight =
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##Settings for the Azure Key Vault
|
|
||||||
akv_config = {
|
|
||||||
name = "vpn-akv"
|
|
||||||
akv_features = {
|
|
||||||
enabled_for_disk_encryption = true
|
|
||||||
enabled_for_deployment = true
|
|
||||||
enabled_for_template_deployment = true
|
|
||||||
}
|
|
||||||
sku_name = "standard"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AuditEvent", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,265 +0,0 @@
|
||||||
# Configuration sample for a hub and spoke environment
|
|
||||||
# definition of variables for the virtual network
|
|
||||||
rg_network = {
|
|
||||||
CORE-NET = {
|
|
||||||
name = "network-core"
|
|
||||||
}
|
|
||||||
TRANSIT-NET = {
|
|
||||||
name = "network-transit"
|
|
||||||
}
|
|
||||||
EDGE-NET = {
|
|
||||||
name = "network-edge"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# settings for the core network blueprint
|
|
||||||
core_networking = {
|
|
||||||
shared_services_vnet = {
|
|
||||||
vnet = {
|
|
||||||
name = "Core-Network"
|
|
||||||
address_space = ["10.0.0.0/8"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
AzureFirewallSubnet = {
|
|
||||||
name = "AzureFirewallSubnet" #Must be called AzureFirewallSubnet
|
|
||||||
cidr = "10.0.4.0/24"
|
|
||||||
}
|
|
||||||
GatewaySubnet = {
|
|
||||||
name = "GatewaySubnet" #Must be called GateWaySubnet in order to host a Virtual Network Gateway
|
|
||||||
cidr = "10.0.255.224/27"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet0 = {
|
|
||||||
name = "Active_Directory"
|
|
||||||
cidr = "10.0.1.0/24"
|
|
||||||
nsg_inbound = [
|
|
||||||
# {"Name", "Priority", "Direction", "Action", "Protocol", "source_port_range", "destination_port_range", "source_address_prefix", "destination_address_prefix" },
|
|
||||||
["W32Time", "100", "Inbound", "Allow", "udp", "*", "123", "*", "*"],
|
|
||||||
["RPC-Endpoint-Mapper", "101", "Inbound", "Allow", "tcp", "*", "135", "*", "*"],
|
|
||||||
["Kerberos-password-change", "102", "Inbound", "Allow", "*", "*", "464", "*", "*"],
|
|
||||||
["RPC-Dynamic-range", "103", "Inbound", "Allow", "tcp", "*", "49152-65535", "*", "*"],
|
|
||||||
["LDAP", "104", "Inbound", "Allow", "*", "*", "389", "*", "*"],
|
|
||||||
["LDAP-SSL", "105", "Inbound", "Allow", "tcp", "*", "636", "*", "*"],
|
|
||||||
["LDAP-GC", "106", "Inbound", "Allow", "tcp", "*", "3268", "*", "*"],
|
|
||||||
["LDAP-GC-SSL", "107", "Inbound", "Allow", "tcp", "*", "3269", "*", "*"],
|
|
||||||
["DNS", "108", "Inbound", "Allow", "*", "*", "53", "*", "*"],
|
|
||||||
["Kerberos", "109", "Inbound", "Allow", "*", "*", "88", "*", "*"],
|
|
||||||
["SMB", "110", "Inbound", "Allow", "tcp", "*", "445", "*", "*"],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet1 = {
|
|
||||||
name = "AzureBastionSubnet" #Must be called AzureBastionSubnet
|
|
||||||
cidr = "10.0.0.128/25"
|
|
||||||
nsg_inbound = [
|
|
||||||
["bastion-in-allow", "100", "Inbound", "Allow", "tcp", "*", "443", "*", "*"],
|
|
||||||
["bastion-control-in-allow-443", "120", "Inbound", "Allow", "tcp", "*", "443", "GatewayManager", "*"],
|
|
||||||
["bastion-control-in-allow-4443", "121", "Inbound", "Allow", "tcp", "*", "4443", "GatewayManager", "*"],
|
|
||||||
]
|
|
||||||
nsg_outbound = [
|
|
||||||
["bastion-vnet-out-allow-22", "100", "Outbound", "Allow", "tcp", "*", "22", "*", "VirtualNetwork"],
|
|
||||||
["bastion-vnet-out-allow-3389", "101", "Outbound", "Allow", "tcp", "*", "3389", "*", "VirtualNetwork"],
|
|
||||||
["bastion-azure-out-allow", "120", "Outbound", "Allow", "tcp", "*", "443", "*", "AzureCloud"],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for Azure Firewall
|
|
||||||
# Must be standard and static for
|
|
||||||
firewall_ip_addr_config = {
|
|
||||||
ip_name = "firewall"
|
|
||||||
allocation_method = "Static"
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Azure Firewall settings
|
|
||||||
az_fw_config = {
|
|
||||||
name = "azfw"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureFirewallApplicationRule", true, true, 30],
|
|
||||||
["AzureFirewallNetworkRule", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the UDR object
|
|
||||||
udr_web_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "0.0.0.0/0"
|
|
||||||
route_name = "web_to_az_firewall"
|
|
||||||
subnet_to_udr = "Web_tier"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
udr_transit_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "10.0.1.0/24"
|
|
||||||
route_name = "transit_to_az_firewall"
|
|
||||||
subnet_to_udr = "GatewaySubnet"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
## DDoS standard configuration
|
|
||||||
enable_ddos_standard = false
|
|
||||||
ddos_name = "ddos_protection_plan"
|
|
||||||
|
|
||||||
## settings for Azure bastion configuration
|
|
||||||
## not enabled, uncomment the code in the networking shared services blueprint.
|
|
||||||
enable_bastion = true
|
|
||||||
bastion_ip_addr_config = {
|
|
||||||
ip_name = "bastion"
|
|
||||||
ip_addr = {
|
|
||||||
allocation_method = "Static"
|
|
||||||
#Dynamic Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure
|
|
||||||
|
|
||||||
#properties below are optional
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
#dns_prefix = "arnaudmytest"
|
|
||||||
#timeout = 15 #TCP timeout for idle connections. The value can be set between 4 and 30 minutes.
|
|
||||||
#zones = [1] #1 zone number, IP address must be standard, ZoneRedundant argument is not supported in provider at time of writing
|
|
||||||
#reverse_fqdn = ""
|
|
||||||
#public_ip_prefix_id = "/subscriptions/00000000-00000-0000-0000-000000000000/resourceGroups/uqvh-hub-ingress-net/providers/Microsoft.Network/publicIPPrefixes/myprefix"
|
|
||||||
#refer to the prefix and check sku types are same in IP and prefix
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bastion_config = {
|
|
||||||
name = "azurebastion"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["BastionAuditLogs", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
# ["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Settings for the Virtual Network gateway to be created
|
|
||||||
provision_gateway = false
|
|
||||||
gateway_config = {
|
|
||||||
gateway_type = "VPN"
|
|
||||||
# Possible values are "VPN" or "ExpressRoute"
|
|
||||||
vpn_gateway_name = "vpngateway"
|
|
||||||
active_active = false
|
|
||||||
#An active-active gateway requires a HighPerformance or an UltraPerformance sku. If false, an active-standby gateway will be created. Defaults to false.
|
|
||||||
enable_bgp = false
|
|
||||||
#If true, BGP (Border Gateway Protocol) will be enabled for this Virtual Network Gateway. Defaults to false.
|
|
||||||
vpn_gateway_sku = "Basic"
|
|
||||||
#Valid options are Basic, Standard, HighPerformance, UltraPerformance, ErGw1AZ, ErGw2AZ, ErGw3AZ, VpnGw1, VpnGw2, VpnGw3, VpnGw1AZ, VpnGw2AZ, and VpnGw3AZ
|
|
||||||
#and depend on the gateway_type (ER or VPN) and vpn_type arguments, ie: PolicyBased gateway only supports the Basic sku.
|
|
||||||
vpn_gateway_type = "RouteBased"
|
|
||||||
#The routing type of the Virtual Network Gateway. Valid options are RouteBased or PolicyBased. Defaults to RouteBased.
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["GatewayDiagnosticLog", true, true, 30],
|
|
||||||
["TunnelDiagnosticLog", true, true, 30],
|
|
||||||
["RouteDiagnosticLog", true, true, 30],
|
|
||||||
["IKEDiagnosticLog", true, true, 30],
|
|
||||||
["P2SDiagnosticLog", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
pip = {
|
|
||||||
name = "vpn"
|
|
||||||
allocation_method = "Dynamic"
|
|
||||||
sku = "Basic"
|
|
||||||
#For basic SKU, you can pick the zone to be deployed - if you want multi zone - pick Standard IP and pick AZ aware VPN gateway SKU
|
|
||||||
#dns_prefix = "arnaudvpn"
|
|
||||||
#zones = ["1"]
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Settings for the connection to be established
|
|
||||||
#Settings for the local network connection
|
|
||||||
connection_name = "onpremconnection"
|
|
||||||
remote_network_connect = true
|
|
||||||
|
|
||||||
remote_network = {
|
|
||||||
gateway_name = "caf_local_network"
|
|
||||||
gateway_ip = "1.2.3.4"
|
|
||||||
gateway_adress_space = ["1.0.0.0/8"]
|
|
||||||
|
|
||||||
bgp_settings = {
|
|
||||||
# asn =
|
|
||||||
# bgp_peering_address =
|
|
||||||
# peer_weight =
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##Settings for the Azure Key Vault
|
|
||||||
akv_config = {
|
|
||||||
name = "vpn-akv"
|
|
||||||
akv_features = {
|
|
||||||
enabled_for_disk_encryption = true
|
|
||||||
enabled_for_deployment = true
|
|
||||||
enabled_for_template_deployment = true
|
|
||||||
}
|
|
||||||
sku_name = "standard"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AuditEvent", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,265 +0,0 @@
|
||||||
# Configuration sample for a hub and spoke environment
|
|
||||||
# definition of variables for the virtual network
|
|
||||||
rg_network = {
|
|
||||||
CORE-NET = {
|
|
||||||
name = "network-core"
|
|
||||||
}
|
|
||||||
TRANSIT-NET = {
|
|
||||||
name = "network-transit"
|
|
||||||
}
|
|
||||||
EDGE-NET = {
|
|
||||||
name = "network-edge"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# settings for the core network blueprint
|
|
||||||
core_networking = {
|
|
||||||
shared_services_vnet = {
|
|
||||||
vnet = {
|
|
||||||
name = "Core-Network"
|
|
||||||
address_space = ["10.0.0.0/8"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
AzureFirewallSubnet = {
|
|
||||||
name = "AzureFirewallSubnet" #Must be called AzureFirewallSubnet
|
|
||||||
cidr = "10.0.4.0/24"
|
|
||||||
}
|
|
||||||
GatewaySubnet = {
|
|
||||||
name = "GatewaySubnet" #Must be called GateWaySubnet in order to host a Virtual Network Gateway
|
|
||||||
cidr = "10.0.255.224/27"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet0 = {
|
|
||||||
name = "Active_Directory"
|
|
||||||
cidr = "10.0.1.0/24"
|
|
||||||
nsg_inbound = [
|
|
||||||
# {"Name", "Priority", "Direction", "Action", "Protocol", "source_port_range", "destination_port_range", "source_address_prefix", "destination_address_prefix" },
|
|
||||||
["W32Time", "100", "Inbound", "Allow", "udp", "*", "123", "*", "*"],
|
|
||||||
["RPC-Endpoint-Mapper", "101", "Inbound", "Allow", "tcp", "*", "135", "*", "*"],
|
|
||||||
["Kerberos-password-change", "102", "Inbound", "Allow", "*", "*", "464", "*", "*"],
|
|
||||||
["RPC-Dynamic-range", "103", "Inbound", "Allow", "tcp", "*", "49152-65535", "*", "*"],
|
|
||||||
["LDAP", "104", "Inbound", "Allow", "*", "*", "389", "*", "*"],
|
|
||||||
["LDAP-SSL", "105", "Inbound", "Allow", "tcp", "*", "636", "*", "*"],
|
|
||||||
["LDAP-GC", "106", "Inbound", "Allow", "tcp", "*", "3268", "*", "*"],
|
|
||||||
["LDAP-GC-SSL", "107", "Inbound", "Allow", "tcp", "*", "3269", "*", "*"],
|
|
||||||
["DNS", "108", "Inbound", "Allow", "*", "*", "53", "*", "*"],
|
|
||||||
["Kerberos", "109", "Inbound", "Allow", "*", "*", "88", "*", "*"],
|
|
||||||
["SMB", "110", "Inbound", "Allow", "tcp", "*", "445", "*", "*"],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet1 = {
|
|
||||||
name = "AzureBastionSubnet" #Must be called AzureBastionSubnet
|
|
||||||
cidr = "10.0.0.128/25"
|
|
||||||
nsg_inbound = [
|
|
||||||
["bastion-in-allow", "100", "Inbound", "Allow", "tcp", "*", "443", "*", "*"],
|
|
||||||
["bastion-control-in-allow-443", "120", "Inbound", "Allow", "tcp", "*", "443", "GatewayManager", "*"],
|
|
||||||
["bastion-control-in-allow-4443", "121", "Inbound", "Allow", "tcp", "*", "4443", "GatewayManager", "*"],
|
|
||||||
]
|
|
||||||
nsg_outbound = [
|
|
||||||
["bastion-vnet-out-allow-22", "100", "Outbound", "Allow", "tcp", "*", "22", "*", "VirtualNetwork"],
|
|
||||||
["bastion-vnet-out-allow-3389", "101", "Outbound", "Allow", "tcp", "*", "3389", "*", "VirtualNetwork"],
|
|
||||||
["bastion-azure-out-allow", "120", "Outbound", "Allow", "tcp", "*", "443", "*", "AzureCloud"],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for Azure Firewall
|
|
||||||
# Must be standard and static for
|
|
||||||
firewall_ip_addr_config = {
|
|
||||||
ip_name = "firewall"
|
|
||||||
allocation_method = "Static"
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Azure Firewall settings
|
|
||||||
az_fw_config = {
|
|
||||||
name = "azfw"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureFirewallApplicationRule", true, true, 30],
|
|
||||||
["AzureFirewallNetworkRule", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the UDR object
|
|
||||||
udr_web_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "0.0.0.0/0"
|
|
||||||
route_name = "web_to_az_firewall"
|
|
||||||
subnet_to_udr = "Web_tier"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
udr_transit_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "10.0.1.0/24"
|
|
||||||
route_name = "transit_to_az_firewall"
|
|
||||||
subnet_to_udr = "GatewaySubnet"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
## DDoS standard configuration
|
|
||||||
enable_ddos_standard = false
|
|
||||||
ddos_name = "ddos_protection_plan"
|
|
||||||
|
|
||||||
## settings for Azure bastion configuration
|
|
||||||
## not enabled, uncomment the code in the networking shared services blueprint.
|
|
||||||
enable_bastion = false
|
|
||||||
bastion_ip_addr_config = {
|
|
||||||
ip_name = "bastion"
|
|
||||||
ip_addr = {
|
|
||||||
allocation_method = "Static"
|
|
||||||
#Dynamic Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure
|
|
||||||
|
|
||||||
#properties below are optional
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
#dns_prefix = "arnaudmytest"
|
|
||||||
#timeout = 15 #TCP timeout for idle connections. The value can be set between 4 and 30 minutes.
|
|
||||||
#zones = [1] #1 zone number, IP address must be standard, ZoneRedundant argument is not supported in provider at time of writing
|
|
||||||
#reverse_fqdn = ""
|
|
||||||
#public_ip_prefix_id = "/subscriptions/00000000-00000-0000-0000-000000000000/resourceGroups/uqvh-hub-ingress-net/providers/Microsoft.Network/publicIPPrefixes/myprefix"
|
|
||||||
#refer to the prefix and check sku types are same in IP and prefix
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bastion_config = {
|
|
||||||
name = "azurebastion"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["BastionAuditLogs", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
# ["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Settings for the Virtual Network gateway to be created
|
|
||||||
provision_gateway = false
|
|
||||||
gateway_config = {
|
|
||||||
gateway_type = "VPN"
|
|
||||||
# Possible values are "VPN" or "ExpressRoute"
|
|
||||||
vpn_gateway_name = "vpngateway"
|
|
||||||
active_active = false
|
|
||||||
#An active-active gateway requires a HighPerformance or an UltraPerformance sku. If false, an active-standby gateway will be created. Defaults to false.
|
|
||||||
enable_bgp = false
|
|
||||||
#If true, BGP (Border Gateway Protocol) will be enabled for this Virtual Network Gateway. Defaults to false.
|
|
||||||
vpn_gateway_sku = "Basic"
|
|
||||||
#Valid options are Basic, Standard, HighPerformance, UltraPerformance, ErGw1AZ, ErGw2AZ, ErGw3AZ, VpnGw1, VpnGw2, VpnGw3, VpnGw1AZ, VpnGw2AZ, and VpnGw3AZ
|
|
||||||
#and depend on the gateway_type (ER or VPN) and vpn_type arguments, ie: PolicyBased gateway only supports the Basic sku.
|
|
||||||
vpn_gateway_type = "RouteBased"
|
|
||||||
#The routing type of the Virtual Network Gateway. Valid options are RouteBased or PolicyBased. Defaults to RouteBased.
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["GatewayDiagnosticLog", true, true, 30],
|
|
||||||
["TunnelDiagnosticLog", true, true, 30],
|
|
||||||
["RouteDiagnosticLog", true, true, 30],
|
|
||||||
["IKEDiagnosticLog", true, true, 30],
|
|
||||||
["P2SDiagnosticLog", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
pip = {
|
|
||||||
name = "vpn"
|
|
||||||
allocation_method = "Dynamic"
|
|
||||||
sku = "Basic"
|
|
||||||
#For basic SKU, you can pick the zone to be deployed - if you want multi zone - pick Standard IP and pick AZ aware VPN gateway SKU
|
|
||||||
#dns_prefix = "arnaudvpn"
|
|
||||||
#zones = ["1"]
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Settings for the connection to be established
|
|
||||||
#Settings for the local network connection
|
|
||||||
connection_name = "onpremconnection"
|
|
||||||
remote_network_connect = true
|
|
||||||
|
|
||||||
remote_network = {
|
|
||||||
gateway_name = "caf_local_network"
|
|
||||||
gateway_ip = "1.2.3.4"
|
|
||||||
gateway_adress_space = ["1.0.0.0/8"]
|
|
||||||
|
|
||||||
bgp_settings = {
|
|
||||||
# asn =
|
|
||||||
# bgp_peering_address =
|
|
||||||
# peer_weight =
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##Settings for the Azure Key Vault
|
|
||||||
akv_config = {
|
|
||||||
name = "vpn-akv"
|
|
||||||
akv_features = {
|
|
||||||
enabled_for_disk_encryption = true
|
|
||||||
enabled_for_deployment = true
|
|
||||||
enabled_for_template_deployment = true
|
|
||||||
}
|
|
||||||
sku_name = "standard"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AuditEvent", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
resource_groups = {
|
|
||||||
vnet_us = {
|
|
||||||
name = "vnet-hub-us"
|
|
||||||
location = "westus2"
|
|
||||||
useprefix = true
|
|
||||||
max_length = 40
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vnets = {
|
|
||||||
hub_us = {
|
|
||||||
resource_group_key = "vnet_us"
|
|
||||||
location = "westus2"
|
|
||||||
vnet = {
|
|
||||||
name = "hub"
|
|
||||||
address_space = ["10.10.100.0/24"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
AzureFirewallSubnet = {
|
|
||||||
name = "AzureFirewallSubnet" #Must be called AzureFirewallSubnet
|
|
||||||
cidr = ["10.10.100.192/26"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
}
|
|
||||||
# Override the default var.diagnostics.vnet
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
firewalls = {
|
|
||||||
# Southeastasia firewall (do not change the key when created)
|
|
||||||
westus2 = {
|
|
||||||
location = "westus2"
|
|
||||||
resource_group_key = "vnet_us"
|
|
||||||
vnet_key = "hub_us"
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for Azure Firewall
|
|
||||||
# Must be standard and static for
|
|
||||||
firewall_ip_addr_config = {
|
|
||||||
ip_name = "firewall"
|
|
||||||
allocation_method = "Static"
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Azure Firewall settings
|
|
||||||
az_fw_config = {
|
|
||||||
name = "azfw"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureFirewallApplicationRule", true, true, 30],
|
|
||||||
["AzureFirewallNetworkRule", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,420 +0,0 @@
|
||||||
# definition of variables for the virtual network
|
|
||||||
rg_network = {
|
|
||||||
CORE-NET = {
|
|
||||||
name = "-network-core"
|
|
||||||
}
|
|
||||||
TRANSIT-NET = {
|
|
||||||
name = "-network-transit"
|
|
||||||
}
|
|
||||||
EDGE-NET = {
|
|
||||||
name = "-network-edge"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# settings for the core network blueprint
|
|
||||||
core_networking = {
|
|
||||||
shared_services_vnet = {
|
|
||||||
vnet = {
|
|
||||||
name = "Core-Network"
|
|
||||||
address_space = ["10.0.0.0/8"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
AzureFirewallSubnet = {
|
|
||||||
name = "AzureFirewallSubnet" #Must be called AzureFirewallSubnet
|
|
||||||
cidr = ["10.0.4.0/24"]
|
|
||||||
}
|
|
||||||
GatewaySubnet = {
|
|
||||||
name = "GatewaySubnet" #Must be called GateWaySubnet in order to host a Virtual Network Gateway
|
|
||||||
cidr = ["10.0.255.224/27"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet0 = {
|
|
||||||
name = "Web_tier"
|
|
||||||
cidr = ["10.0.1.0/24"]
|
|
||||||
nsg_name = "Web_tier_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "HTTP-In",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "80"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "HTTPS-In",
|
|
||||||
priority = "101"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "443"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet1 = {
|
|
||||||
name = "Business_tier"
|
|
||||||
cidr = ["10.0.2.0/24"]
|
|
||||||
nsg_name = "Business_tier_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "HTTP-In",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "80"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "HTTPS-In",
|
|
||||||
priority = "101"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "443"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "HTTP-Out",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Outbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "80"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "HTTPS-Out",
|
|
||||||
priority = "101"
|
|
||||||
direction = "Outbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "443"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet2 = {
|
|
||||||
name = "Data_tier"
|
|
||||||
cidr = ["10.0.3.0/24"]
|
|
||||||
nsg_name = "Data_tier_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "TDS-In",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "1433"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet3 = {
|
|
||||||
name = "AzureBastionSubnet" #Must be called AzureBastionSubnet
|
|
||||||
cidr = ["10.0.0.128/25"]
|
|
||||||
nsg_name = "AzureBastionSubnet_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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
# netwatcher = {
|
|
||||||
# create = true
|
|
||||||
# #create the network watcher for a subscription and for the location of the vnet
|
|
||||||
# name = "arnaud-nw-test"
|
|
||||||
# #name of the network watcher to be created
|
|
||||||
|
|
||||||
# flow_logs_settings = {
|
|
||||||
# enabled = true
|
|
||||||
# retention = true
|
|
||||||
# period = 7
|
|
||||||
# }
|
|
||||||
|
|
||||||
# traffic_analytics_settings = {
|
|
||||||
# enabled = true
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for Azure Firewall
|
|
||||||
# Must be standard and static for
|
|
||||||
ip_addr_config = {
|
|
||||||
ip_name = "firewall"
|
|
||||||
allocation_method = "Static"
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Azure Firewall settings
|
|
||||||
az_fw_config = {
|
|
||||||
name = "azfw"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureFirewallApplicationRule", true, true, 30],
|
|
||||||
["AzureFirewallNetworkRule", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the UDR object
|
|
||||||
udr_web_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "0.0.0.0/0"
|
|
||||||
route_name = "web_to_az_firewall"
|
|
||||||
subnet_to_udr = "Web_tier"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
udr_transit_to_az_firewall = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "10.0.1.0/24"
|
|
||||||
route_name = "transit_to_az_firewall"
|
|
||||||
subnet_to_udr = "GatewaySubnet"
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
## DDoS standard configuration
|
|
||||||
enable_ddos_standard = false
|
|
||||||
ddos_name = "ddos_protection_plan"
|
|
||||||
|
|
||||||
## settings for Azure bastion configuration
|
|
||||||
## not enabled, uncomment the code in the networking shared services blueprint.
|
|
||||||
enable_bastion = true
|
|
||||||
bastion_ip_addr_config = {
|
|
||||||
ip_name = "bastion"
|
|
||||||
ip_addr = {
|
|
||||||
allocation_method = "Static"
|
|
||||||
#Dynamic Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure
|
|
||||||
|
|
||||||
#properties below are optional
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
#dns_prefix = "arnaudmytest"
|
|
||||||
#timeout = 15 #TCP timeout for idle connections. The value can be set between 4 and 30 minutes.
|
|
||||||
#zones = [1] #1 zone number, IP address must be standard, ZoneRedundant argument is not supported in provider at time of writing
|
|
||||||
#reverse_fqdn = ""
|
|
||||||
#public_ip_prefix_id = "/subscriptions/00000000-00000-0000-0000-000000000000/resourceGroups/uqvh-hub-ingress-net/providers/Microsoft.Network/publicIPPrefixes/myprefix"
|
|
||||||
#refer to the prefix and check sku types are same in IP and prefix
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bastion_config = {
|
|
||||||
name = "azurebastionalz"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["BastionAuditLogs", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
# ["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Settings for the Virtual Network gateway to be created
|
|
||||||
provision_gateway = false
|
|
||||||
gateway_config = {
|
|
||||||
gateway_type = "VPN"
|
|
||||||
# Possible values are "VPN" or "ExpressRoute"
|
|
||||||
vpn_gateway_name = "vpngateway"
|
|
||||||
active_active = false
|
|
||||||
#An active-active gateway requires a HighPerformance or an UltraPerformance sku. If false, an active-standby gateway will be created. Defaults to false.
|
|
||||||
enable_bgp = false
|
|
||||||
#If true, BGP (Border Gateway Protocol) will be enabled for this Virtual Network Gateway. Defaults to false.
|
|
||||||
vpn_gateway_sku = "Basic"
|
|
||||||
#Valid options are Basic, Standard, HighPerformance, UltraPerformance, ErGw1AZ, ErGw2AZ, ErGw3AZ, VpnGw1, VpnGw2, VpnGw3, VpnGw1AZ, VpnGw2AZ, and VpnGw3AZ
|
|
||||||
#and depend on the gateway_type (ER or VPN) and vpn_type arguments, ie: PolicyBased gateway only supports the Basic sku.
|
|
||||||
vpn_gateway_type = "RouteBased"
|
|
||||||
#The routing type of the Virtual Network Gateway. Valid options are RouteBased or PolicyBased. Defaults to RouteBased.
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["GatewayDiagnosticLog", true, true, 30],
|
|
||||||
["TunnelDiagnosticLog", true, true, 30],
|
|
||||||
["RouteDiagnosticLog", true, true, 30],
|
|
||||||
["IKEDiagnosticLog", true, true, 30],
|
|
||||||
["P2SDiagnosticLog", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
pip = {
|
|
||||||
name = "vpn"
|
|
||||||
allocation_method = "Dynamic"
|
|
||||||
sku = "Basic"
|
|
||||||
#For basic SKU, you can pick the zone to be deployed - if you want multi zone - pick Standard IP and pick AZ aware VPN gateway SKU
|
|
||||||
#dns_prefix = "arnaudvpn"
|
|
||||||
#zones = ["1"]
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#Settings for the connection to be established
|
|
||||||
#Settings for the local network connection
|
|
||||||
connection_name = "onpremconnection"
|
|
||||||
remote_network_connect = true
|
|
||||||
|
|
||||||
remote_network = {
|
|
||||||
gateway_name = "caf_local_network"
|
|
||||||
gateway_ip = "1.2.3.4"
|
|
||||||
gateway_adress_space = ["1.0.0.0/8"]
|
|
||||||
|
|
||||||
bgp_settings = {
|
|
||||||
# asn =
|
|
||||||
# bgp_peering_address =
|
|
||||||
# peer_weight =
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
##Settings for the Azure Key Vault
|
|
||||||
akv_config = {
|
|
||||||
name = "vpn-akv"
|
|
||||||
akv_features = {
|
|
||||||
enabled_for_disk_encryption = true
|
|
||||||
enabled_for_deployment = true
|
|
||||||
enabled_for_template_deployment = true
|
|
||||||
}
|
|
||||||
sku_name = "standard"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AuditEvent", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
# nothing
|
|
|
@ -1,577 +0,0 @@
|
||||||
# settings for the shared network blueprint
|
|
||||||
resource_groups_shared_services = {
|
|
||||||
HUB-CORE-NET = {
|
|
||||||
name = "-hub-network-shared"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enable_ddos_standard = false
|
|
||||||
ddos_name = "ddos_protection_plan"
|
|
||||||
|
|
||||||
shared_services_vnet = {
|
|
||||||
vnet = {
|
|
||||||
name = "Shared-Services"
|
|
||||||
address_space = ["10.101.4.0/22"]
|
|
||||||
dns = []
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet0 = {
|
|
||||||
name = "Critical_Applications"
|
|
||||||
cidr = ["10.101.4.0/25"]
|
|
||||||
nsg_name = "Critical_Applications_nsg"
|
|
||||||
service_endpoints = []
|
|
||||||
}
|
|
||||||
subnet1 = {
|
|
||||||
name = "Active_Directory"
|
|
||||||
cidr = ["10.101.4.128/27"]
|
|
||||||
service_endpoints = []
|
|
||||||
nsg_name = "Active_Directory_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "W32Time",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "123"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "RPC-Endpoint-Mapper",
|
|
||||||
priority = "101"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "135"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "Kerberos-password-change",
|
|
||||||
priority = "102"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "464"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "RPC-Dynamic-range",
|
|
||||||
priority = "103"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "49152-65535"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP",
|
|
||||||
priority = "104"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "389"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP-SSL",
|
|
||||||
priority = "105"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "636"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP-GC",
|
|
||||||
priority = "106"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "3268"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "LDAP-GC-SSL",
|
|
||||||
priority = "107"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "3269"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "DNS",
|
|
||||||
priority = "108"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "53"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "Kerberos",
|
|
||||||
priority = "109"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "*"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "88"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "SMB",
|
|
||||||
priority = "110"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "tcp"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "445"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet2 = {
|
|
||||||
name = "SQL_Servers"
|
|
||||||
cidr = ["10.101.4.160/27"]
|
|
||||||
service_endpoints = []
|
|
||||||
nsg_name = "Data_tier_nsg"
|
|
||||||
nsg = [
|
|
||||||
{
|
|
||||||
name = "TDS-In",
|
|
||||||
priority = "100"
|
|
||||||
direction = "Inbound"
|
|
||||||
access = "Allow"
|
|
||||||
protocol = "UDP"
|
|
||||||
source_port_range = "*"
|
|
||||||
destination_port_range = "1433"
|
|
||||||
source_address_prefix = "*"
|
|
||||||
destination_address_prefix = "*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
subnet4 = {
|
|
||||||
name = "AzureBastionSubnet"
|
|
||||||
cidr = ["10.101.4.192/27"]
|
|
||||||
nsg_name = "AzureBastionSubnet_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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## settings for Azure bastion configuration
|
|
||||||
## not enabled, uncomment the code in the networking shared services blueprint.
|
|
||||||
enable_bastion = true
|
|
||||||
bastion_config = {
|
|
||||||
name = "azurebastion"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["BastionAuditLogs", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
# ["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
ip_name = "caf-pip-bastion"
|
|
||||||
ip_addr = {
|
|
||||||
allocation_method = "Static"
|
|
||||||
#Dynamic Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure
|
|
||||||
|
|
||||||
#properties below are optional
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
#dns_prefix = "arnaudmytest"
|
|
||||||
#timeout = 15 #TCP timeout for idle connections. The value can be set between 4 and 30 minutes.
|
|
||||||
#zones = [1] #1 zone number, IP address must be standard, ZoneRedundant argument is not supported in provider at time of writing
|
|
||||||
#reverse_fqdn = ""
|
|
||||||
#public_ip_prefix_id = "/subscriptions/00000000-00000-0000-0000-000000000000/resourceGroups/uqvh-hub-ingress-net/providers/Microsoft.Network/publicIPPrefixes/myprefix"
|
|
||||||
#refer to the prefix and check sku types are same in IP and prefix
|
|
||||||
}
|
|
||||||
ip_diags = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# settings for the shared egress blueprint
|
|
||||||
resource_groups_shared_egress = {
|
|
||||||
HUB-EGRESS-NET = {
|
|
||||||
name = "-hub-network-egress"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the shared services egress vnet - note that Azure Firewall subnet must be at least /26
|
|
||||||
networking_egress = {
|
|
||||||
vnet = {
|
|
||||||
name = "Shared-Egress"
|
|
||||||
address_space = ["10.0.0.0/25"]
|
|
||||||
dns = ["192.168.0.16", "192.168.0.64"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
AzureFirewallSubnet = {
|
|
||||||
name = "AzureFirewallSubnet"
|
|
||||||
cidr = ["10.0.0.0/26"]
|
|
||||||
service_endpoints = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet1 = {
|
|
||||||
name = "Network_Monitoring"
|
|
||||||
cidr = ["10.0.0.64/26"]
|
|
||||||
nsg_name = "Network_Monitoring_nsg"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for egress
|
|
||||||
# Must be standard and static for Azure Firewall
|
|
||||||
ip_addr_config = {
|
|
||||||
ip_name = "caf-pip-egress"
|
|
||||||
allocation_method = "Static"
|
|
||||||
#Dynamic Public IP Addresses aren't allocated until they're assigned to a resource (such as a Virtual Machine or a Load Balancer) by design within Azure
|
|
||||||
|
|
||||||
#properties below are optional
|
|
||||||
sku = "Standard" #defaults to Basic
|
|
||||||
ip_version = "IPv4" #defaults to IP4, Only dynamic for IPv6, Supported arguments are IPv4 or IPv6, NOT Both
|
|
||||||
#dns_prefix = "arnaudmytest"
|
|
||||||
#timeout = 15 #TCP timeout for idle connections. The value can be set between 4 and 30 minutes.
|
|
||||||
#zones = [1] #1 zone number, IP address must be standard, ZoneRedundant argument is not supported in provider at time of writing
|
|
||||||
#reverse_fqdn = ""
|
|
||||||
#public_ip_prefix_id = "/subscriptions/00000000-00000-0000-0000-000000000000/resourceGroups/uqvh-hub-ingress-net/providers/Microsoft.Network/publicIPPrefixes/myprefix"
|
|
||||||
#refer to the prefix and check sku types are same in IP and prefix
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Azure Firewall settings
|
|
||||||
az_fw_config = {
|
|
||||||
name = "az-fw-caf"
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureFirewallApplicationRule", true, true, 30],
|
|
||||||
["AzureFirewallNetworkRule", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the UDR object
|
|
||||||
udr_object = {
|
|
||||||
nexthop_type = "VirtualAppliance"
|
|
||||||
prefix = "0.0.0.0/0"
|
|
||||||
route_name = "myWay"
|
|
||||||
subnets_to_udr = ""
|
|
||||||
nexthop_ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
# settings for the transit network blueprint
|
|
||||||
|
|
||||||
#resource group creation
|
|
||||||
resource_groups_shared_transit = {
|
|
||||||
HUB-NET-TRANSIT = {
|
|
||||||
name = "-hub-network-transit"
|
|
||||||
location = "southeastasia"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the shared services egress vnet
|
|
||||||
networking_transit = {
|
|
||||||
vnet = {
|
|
||||||
name = "Shared-Transit"
|
|
||||||
address_space = ["172.16.0.0/23"]
|
|
||||||
dns = ["192.168.0.16", "192.168.0.64"]
|
|
||||||
}
|
|
||||||
specialsubnets = {
|
|
||||||
GatewaySubnet = {
|
|
||||||
name = "GatewaySubnet" #Must be called GateWaySubnet in order to host a Virtual Network Gateway
|
|
||||||
cidr = ["172.16.0.0/24"]
|
|
||||||
service_endpoints = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subnets = {
|
|
||||||
subnet1 = {
|
|
||||||
name = "NetworkMonitoring"
|
|
||||||
cidr = ["172.16.1.0/24"]
|
|
||||||
nsg_name = "NetworkMonitoring_msg"
|
|
||||||
service_endpoints = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["VMProtectionAlerts", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the public IP address to be used for egress
|
|
||||||
public_ip_addr = {
|
|
||||||
name = "caf-pip-vpn"
|
|
||||||
allocation_method = "Dynamic"
|
|
||||||
sku = "Basic"
|
|
||||||
#For basic SKU, you can pick the zone to be deployed - if you want multi zone - pick Standard IP and pick AZ aware VPN gateway SKU
|
|
||||||
#dns_prefix = "arnaudvpn"
|
|
||||||
#zones = ["1"]
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["DDoSProtectionNotifications", true, true, 30],
|
|
||||||
["DDoSMitigationFlowLogs", true, true, 30],
|
|
||||||
["DDoSMitigationReports", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Settings for the Virtual Network gateway to be created
|
|
||||||
provision_gateway = false
|
|
||||||
gateway_config = {
|
|
||||||
gateway_type = "VPN"
|
|
||||||
# Possible values are "VPN" or "ExpressRoute"
|
|
||||||
vpn_gateway_name = "mygateway"
|
|
||||||
active_active = false
|
|
||||||
#An active-active gateway requires a HighPerformance or an UltraPerformance sku. If false, an active-standby gateway will be created. Defaults to false.
|
|
||||||
enable_bgp = false
|
|
||||||
#If true, BGP (Border Gateway Protocol) will be enabled for this Virtual Network Gateway. Defaults to false.
|
|
||||||
vpn_gateway_sku = "Basic"
|
|
||||||
#Valid options are Basic, Standard, HighPerformance, UltraPerformance, ErGw1AZ, ErGw2AZ, ErGw3AZ, VpnGw1, VpnGw2, VpnGw3, VpnGw1AZ, VpnGw2AZ, and VpnGw3AZ
|
|
||||||
#and depend on the gateway_type (ER or VPN) and vpn_type arguments, ie: PolicyBased gateway only supports the Basic sku.
|
|
||||||
vpn_gateway_type = "RouteBased"
|
|
||||||
#The routing type of the Virtual Network Gateway. Valid options are RouteBased or PolicyBased. Defaults to RouteBased.
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["GatewayDiagnosticLog", true, true, 30],
|
|
||||||
["TunnelDiagnosticLog", true, true, 30],
|
|
||||||
["RouteDiagnosticLog", true, true, 30],
|
|
||||||
["IKEDiagnosticLog", true, true, 30],
|
|
||||||
["P2SDiagnosticLog", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#Settings for the connection to be established
|
|
||||||
#Settings for the local network connection
|
|
||||||
connection_name = "onpremconnection"
|
|
||||||
remote_network_connect = true
|
|
||||||
|
|
||||||
remote_network = {
|
|
||||||
gateway_name = "caf_local_network"
|
|
||||||
gateway_ip = "1.2.3.4"
|
|
||||||
gateway_adress_space = ["1.0.0.0/8"]
|
|
||||||
}
|
|
||||||
|
|
||||||
##Settings for the Azure Key Vault
|
|
||||||
|
|
||||||
akv_config = {
|
|
||||||
name = "techakv"
|
|
||||||
akv_features = {
|
|
||||||
enabled_for_disk_encryption = true
|
|
||||||
enabled_for_deployment = true
|
|
||||||
enabled_for_template_deployment = true
|
|
||||||
}
|
|
||||||
sku_name = "premium"
|
|
||||||
# network_acls = {
|
|
||||||
# bypass = "AzureServices"
|
|
||||||
# default_action = "Deny"
|
|
||||||
# }
|
|
||||||
diagnostics = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AuditEvent", true, true, 60],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 60],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# settings for the operations blueprint
|
|
||||||
|
|
||||||
# #Azure Site Recovery Configuration
|
|
||||||
asr_config = {
|
|
||||||
asr_vault_name = "asr"
|
|
||||||
asr_diags = {
|
|
||||||
log_analytics_destination_type = "Dedicated"
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AzureBackupReport", true, true, 30],
|
|
||||||
["CoreAzureBackup", true, true, 30],
|
|
||||||
["AddonAzureBackupAlerts", true, true, 30],
|
|
||||||
["AddonAzureBackupJobs", true, true, 30],
|
|
||||||
["AddonAzureBackupPolicy", true, true, 30],
|
|
||||||
["AddonAzureBackupProtectedInstance", true, true, 30],
|
|
||||||
["AddonAzureBackupStorage", true, true, 30],
|
|
||||||
["AzureSiteRecoveryJobs", true, true, 30],
|
|
||||||
["AzureSiteRecoveryEvents", true, true, 30],
|
|
||||||
["AzureSiteRecoveryReplicatedItems", true, true, 30],
|
|
||||||
["AzureSiteRecoveryReplicationStats", true, true, 30],
|
|
||||||
["AzureSiteRecoveryRecoveryPoints", true, true, 30],
|
|
||||||
["AzureSiteRecoveryReplicationDataUploadRate", true, true, 30],
|
|
||||||
["AzureSiteRecoveryProtectedDiskDataChurn", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
#["AllMetrics", 60, True],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#Azure Automation account name
|
|
||||||
auto_config = {
|
|
||||||
auto_account = "azauto"
|
|
||||||
auto_diags = {
|
|
||||||
log = [
|
|
||||||
# ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["JobLogs", true, true, 30],
|
|
||||||
["JobStreams", true, true, 30],
|
|
||||||
["DscNodeStatus", true, true, 30],
|
|
||||||
]
|
|
||||||
metric = [
|
|
||||||
# ["Category name", "Metric Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
|
|
||||||
["AllMetrics", true, true, 30],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Cloud Adoption Framework for Azure - Landing zones on Terraform - Foundations
|
||||||
|
|
||||||
|
The foundations landing zone allows you to manage the core components of an environment:
|
||||||
|
|
||||||
|
* Management groups
|
||||||
|
* Policies
|
||||||
|
* Auditing and Accounting, deployment or connection to existing ones.
|
||||||
|
|
||||||
|
Foundations landing zone operates at **level 1**.
|
||||||
|
|
||||||
|
For a review of the hierarchy approach of Cloud Adoption Framework for Azure landing zones on Terraform, you can refer to [the following documentation](../../documentation/code_architecture/hierarchy.md).
|
||||||
|
|
||||||
|
</BR>
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
CAF foundations landing zone leverages the enterprise-scale module in order to deploy its core components.
|
||||||
|
|
||||||
|
## Deploying CAF foundations
|
||||||
|
|
||||||
|
By default, the content of this landing zone is empty unless you specify a configuration file to enable it.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# To deploy the CAF foundations in passthrough mode
|
||||||
|
rover -lz /tf/caf/landingzones/caf_foundations \
|
||||||
|
-level level1 \
|
||||||
|
-a apply
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deploying CAF foundations with enterprise-scale (experimental)
|
||||||
|
|
||||||
|
This is currently work in progress.
|
||||||
|
Use the following configuration file in order to get started with the enterprise-scale module integration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rover -lz /tf/caf/landingzones/caf_foundations \
|
||||||
|
-var-folder /tf/caf/landingzones/caf_foundations/scenario/200 \
|
||||||
|
-level level1 \
|
||||||
|
-a apply
|
||||||
|
```
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
module "enterprise_scale" {
|
||||||
|
source = "Azure/caf-enterprise-scale/azurerm"
|
||||||
|
version = "0.0.6-preview"
|
||||||
|
|
||||||
|
root_parent_id = data.azurerm_client_config.current.tenant_id
|
||||||
|
|
||||||
|
# Define a custom ID to use for the root Management Group
|
||||||
|
# Also used as a prefix for all core Management Group IDs
|
||||||
|
root_id = "caf"
|
||||||
|
|
||||||
|
# Control whether to deploy the default core landing zones // default = true
|
||||||
|
deploy_core_landing_zones = false
|
||||||
|
|
||||||
|
# Control whether to deploy the demo landing zones // default = false
|
||||||
|
deploy_demo_landing_zones = false
|
||||||
|
|
||||||
|
# Set a path for the custom archetype library path
|
||||||
|
library_path = try(format("%s%s", path.root, var.enterprise_scale.library_path), "")
|
||||||
|
|
||||||
|
# Deploys the custom landing zone configuration as defined in config file
|
||||||
|
custom_landing_zones = try(var.enterprise_scale.management_groups, {})
|
||||||
|
|
||||||
|
default_location = local.global_settings.regions[local.global_settings.default_region]
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
locals {
|
||||||
|
landingzone = {
|
||||||
|
current = {
|
||||||
|
storage_account_name = var.tfstate_storage_account_name
|
||||||
|
container_name = var.tfstate_container_name
|
||||||
|
resource_group_name = var.tfstate_resource_group_name
|
||||||
|
}
|
||||||
|
lower = {
|
||||||
|
storage_account_name = var.lower_storage_account_name
|
||||||
|
container_name = var.lower_container_name
|
||||||
|
resource_group_name = var.lower_resource_group_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "terraform_remote_state" "remote" {
|
||||||
|
for_each = try(var.landingzone.tfstates, {})
|
||||||
|
|
||||||
|
backend = var.landingzone.backend_type
|
||||||
|
config = {
|
||||||
|
storage_account_name = local.landingzone[try(each.value.level, "current")].storage_account_name
|
||||||
|
container_name = local.landingzone[try(each.value.level, "current")].container_name
|
||||||
|
resource_group_name = local.landingzone[try(each.value.level, "current")].resource_group_name
|
||||||
|
key = each.value.tfstate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
landingzone_tag = {
|
||||||
|
"landingzone" = var.landingzone.key
|
||||||
|
}
|
||||||
|
|
||||||
|
tags = merge(var.tags, local.landingzone_tag, { "level" = var.landingzone.level }, { "environment" = local.global_settings.environment }, { "rover_version" = var.rover_version })
|
||||||
|
|
||||||
|
global_settings = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings
|
||||||
|
|
||||||
|
diagnostics = {
|
||||||
|
diagnostics_definition = merge(data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.diagnostics_definition, var.diagnostics_definition)
|
||||||
|
diagnostics_destinations = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.diagnostics_destinations
|
||||||
|
storage_accounts = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.storage_accounts
|
||||||
|
log_analytics = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.log_analytics
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
remote = {
|
||||||
|
managed_identities = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.managed_identities[key], {}))
|
||||||
|
}
|
||||||
|
azuread_groups = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.azuread_groups[key], {}))
|
||||||
|
}
|
||||||
|
vnets = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.vnets[key], {}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
azurerm = {
|
||||||
|
source = "hashicorp/azurerm"
|
||||||
|
version = "~> 2.32.0"
|
||||||
|
}
|
||||||
|
azuread = {
|
||||||
|
source = "hashicorp/azuread"
|
||||||
|
version = "~> 1.0.0"
|
||||||
|
}
|
||||||
|
random = {
|
||||||
|
source = "hashicorp/random"
|
||||||
|
version = "~> 2.2.1"
|
||||||
|
}
|
||||||
|
null = {
|
||||||
|
source = "hashicorp/null"
|
||||||
|
version = "~> 2.1.0"
|
||||||
|
}
|
||||||
|
tls = {
|
||||||
|
source = "hashicorp/tls"
|
||||||
|
version = "~> 2.2.0"
|
||||||
|
}
|
||||||
|
azurecaf = {
|
||||||
|
source = "aztfmod/azurecaf"
|
||||||
|
version = "~> 1.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required_version = ">= 0.13"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
provider "azurerm" {
|
||||||
|
features {
|
||||||
|
key_vault {
|
||||||
|
purge_soft_delete_on_destroy = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "azurerm_client_config" "current" {}
|
||||||
|
data "azurerm_subscription" "current" {}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
|
||||||
|
# Update the tfstates map
|
||||||
|
tfstates = merge(
|
||||||
|
map(var.landingzone.key,
|
||||||
|
map(
|
||||||
|
"storage_account_name", var.tfstate_storage_account_name,
|
||||||
|
"container_name", var.tfstate_container_name,
|
||||||
|
"resource_group_name", var.tfstate_resource_group_name,
|
||||||
|
"key", var.tfstate_key,
|
||||||
|
"level", var.landingzone.level,
|
||||||
|
"tenant_id", var.tenant_id,
|
||||||
|
"subscription_id", data.azurerm_client_config.current.subscription_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
,
|
||||||
|
data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.tfstates
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
output global_settings {
|
||||||
|
value = local.global_settings
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
output diagnostics {
|
||||||
|
value = local.diagnostics
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
output vnets {
|
||||||
|
value = local.remote.vnets
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
output managed_identities {
|
||||||
|
value = local.remote.managed_identities
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
output azuread_groups {
|
||||||
|
value = local.remote.azuread_groups
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
output tfstates {
|
||||||
|
value = local.tfstates
|
||||||
|
sensitive = true
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
landingzone = {
|
||||||
|
backend_type = "azurerm"
|
||||||
|
global_settings_key = "launchpad"
|
||||||
|
level = "level1"
|
||||||
|
key = "caf_foundations"
|
||||||
|
tfstates = {
|
||||||
|
launchpad = {
|
||||||
|
level = "lower"
|
||||||
|
tfstate = "caf_launchpad.tfstate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enterprise_scale = {
|
||||||
|
#path to the policies definition and assignment repo
|
||||||
|
library_path = "/scenario/200/lib"
|
||||||
|
|
||||||
|
#management groups hierarchy configuration
|
||||||
|
management_groups = {
|
||||||
|
caf = {
|
||||||
|
display_name = "CAF-RootManagementGroup"
|
||||||
|
parent_management_group_id = ""
|
||||||
|
subscription_ids = []
|
||||||
|
archetype_config = {
|
||||||
|
archetype_id = "es_root"
|
||||||
|
parameters = {}
|
||||||
|
access_control = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child-caf = {
|
||||||
|
display_name = "CAF-ChildManagementGroup"
|
||||||
|
parent_management_group_id = "caf"
|
||||||
|
subscription_ids = []
|
||||||
|
archetype_config = {
|
||||||
|
archetype_id = "es_management"
|
||||||
|
parameters = {
|
||||||
|
ES-Deploy-ForwardDiagLog = {
|
||||||
|
logAnalytics = "central_logs_region1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
access_control = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"es_management": {
|
||||||
|
"policy_assignments": [
|
||||||
|
"ES-Deploy-ASC-Standard"
|
||||||
|
],
|
||||||
|
"policy_definitions": [
|
||||||
|
],
|
||||||
|
"policy_set_definitions": [],
|
||||||
|
"role_assignments": [],
|
||||||
|
"role_definitions": []
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"es_root": {
|
||||||
|
"policy_assignments": [
|
||||||
|
"ES-Deploy-ASC-Standard"
|
||||||
|
],
|
||||||
|
"policy_definitions": [
|
||||||
|
"ES-Deploy-ASC-Standard"
|
||||||
|
],
|
||||||
|
"policy_set_definitions": [],
|
||||||
|
"role_assignments": [],
|
||||||
|
"role_definitions": []
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Allowed-Locations",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Specifies the allowed locations (regions) where resources can be deployed",
|
||||||
|
"displayName": "ES-Allowed-Resource-Locations",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {
|
||||||
|
"listOfAllowedLocations": {
|
||||||
|
"value": [
|
||||||
|
"uksouth",
|
||||||
|
"ukwest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "None"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Allowed-RSG-Locations",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Specifies the allowed locations (regions) where Resource Groups can be deployed",
|
||||||
|
"displayName": "ES-Allowed-ResourceGroup-Locations",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {
|
||||||
|
"listOfAllowedLocations": {
|
||||||
|
"value": [
|
||||||
|
"uksouth",
|
||||||
|
"ukwest"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/e765b5de-1225-4ba3-bd56-1ac6695af988",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "None"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Deploy-ASC-ContExport",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Deploy ASC Continuous Export To Log Analytics Workspace.",
|
||||||
|
"displayName": "ES-Deploy-ASC-ContinuousExportToWorkspace",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {
|
||||||
|
"resourceGroupLocation": {
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"workspaceResourceId": {
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/ES-Deploy-ASC-ContinuousExportToWorkspace",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "SystemAssigned"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Deploy-ASC-Monitoring",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Enable Monitoring in Azure Security Center.",
|
||||||
|
"displayName": "ES-Deploy-ASC-Monitoring",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {
|
||||||
|
"aadAuthenticationInSqlServerMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"diskEncryptionMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"encryptionOfAutomationAccountMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityDesignateLessThanOwnersMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityDesignateMoreThanOneOwnerMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityEnableMFAForWritePermissionsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityRemoveDeprecatedAccountMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityRemoveDeprecatedAccountWithOwnerPermissionsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityRemoveExternalAccountWithOwnerPermissionsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityRemoveExternalAccountWithReadPermissionsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"identityRemoveExternalAccountWithWritePermissionsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"jitNetworkAccessMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"networkSecurityGroupsOnSubnetsMonitoringEffect": {
|
||||||
|
"value": "AuditIfNotExists"
|
||||||
|
},
|
||||||
|
"sqlDbEncryptionMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"sqlManagedInstanceAdvancedDataSecurityEmailAdminsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"sqlManagedInstanceAdvancedDataSecurityEmailsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"sqlServerAdvancedDataSecurityEmailAdminsMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"sqlServerAdvancedDataSecurityMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"systemUpdatesMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"useRbacRulesMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"vmssSystemUpdatesMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
},
|
||||||
|
"windowsDefenderExploitGuardMonitoringEffect": {
|
||||||
|
"value": "Disabled"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policySetDefinitions/1f3afdf9-d0c9-4c3d-847f-89da613e70a8",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "SystemAssigned"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Deploy-ASC-Standard",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Deploy Azure Security Center Standard Tier.",
|
||||||
|
"displayName": "ES-Deploy-ASC-Standard",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {},
|
||||||
|
"policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/ES-Deploy-ASC-Standard",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "SystemAssigned"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Deploy-ForwardActLogs",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Ensures that Activity Log Diagnostics settings are set to push logs into Log Analytics workspace.",
|
||||||
|
"displayName": "ES-Deploy-Diagnostics-ForwardActivityLogs",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {
|
||||||
|
"logAnalytics": {
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/ES-Deploy-Diagnostics-LogAnalytics",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "SystemAssigned"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Deploy-ForwardDiagLog",
|
||||||
|
"type": "Microsoft.Authorization/policyAssignments",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Ensures that Azure resources are configured to forward diagnostic logs and metrics to an Azure Log Analytics workspace.",
|
||||||
|
"displayName": "ES-Deploy-Diagnostics-ForwardDiagnosticLogs",
|
||||||
|
"notScopes": [],
|
||||||
|
"parameters": {
|
||||||
|
"logAnalytics": {
|
||||||
|
"value": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policySetDefinitions/ES-Deploy-Diagnostics-LogAnalytics",
|
||||||
|
"scope": "${current_scope_resource_id}"
|
||||||
|
},
|
||||||
|
"sku": {
|
||||||
|
"name": "A0",
|
||||||
|
"tier": "Free"
|
||||||
|
},
|
||||||
|
"location": "${default_location}",
|
||||||
|
"identity": {
|
||||||
|
"type": "SystemAssigned"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,284 @@
|
||||||
|
{
|
||||||
|
"name": "ES-Deploy-ASC-Standard",
|
||||||
|
"type": "Microsoft.Authorization/policyDefinitions",
|
||||||
|
"apiVersion": "2019-09-01",
|
||||||
|
"properties": {
|
||||||
|
"description": "Ensures that subscriptions have Security Center Standard enabled.",
|
||||||
|
"displayName": "ES-Deploy-ASC-Standard",
|
||||||
|
"mode": "All",
|
||||||
|
"parameters": {
|
||||||
|
"pricingTierVMs": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierVMs",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
},
|
||||||
|
"pricingTierSqlServers": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierSqlServers",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
},
|
||||||
|
"pricingTierAppServices": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierAppServices",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
},
|
||||||
|
"pricingTierStorageAccounts": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierStorageAccounts",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
},
|
||||||
|
"pricingTierContainerRegistry": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierContainerRegistry",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
},
|
||||||
|
"pricingTierKeyVaults": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierKeyVaults",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
},
|
||||||
|
"pricingTierKubernetesService": {
|
||||||
|
"type": "String",
|
||||||
|
"metadata": {
|
||||||
|
"displayName": "pricingTierKubernetesService",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"allowedValues": [
|
||||||
|
"Standard",
|
||||||
|
"Free"
|
||||||
|
],
|
||||||
|
"defaultValue": "Standard"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policyRule": {
|
||||||
|
"if": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"field": "type",
|
||||||
|
"equals": "Microsoft.Resources/subscriptions"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"effect": "deployIfNotExists",
|
||||||
|
"details": {
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"deploymentScope": "subscription",
|
||||||
|
"existenceScope": "subscription",
|
||||||
|
"roleDefinitionIds": [
|
||||||
|
"/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
|
||||||
|
],
|
||||||
|
"existenceCondition": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"field": "Microsoft.Security/pricings/pricingTier",
|
||||||
|
"equals": "Standard"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "type",
|
||||||
|
"equals": "Microsoft.Security/pricings"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"deployment": {
|
||||||
|
"location": "northeurope",
|
||||||
|
"properties": {
|
||||||
|
"mode": "incremental",
|
||||||
|
"parameters": {
|
||||||
|
"pricingTierVMs": {
|
||||||
|
"value": "[parameters('pricingTierVMs')]"
|
||||||
|
},
|
||||||
|
"pricingTierSqlServers": {
|
||||||
|
"value": "[parameters('pricingTierSqlServers')]"
|
||||||
|
},
|
||||||
|
"pricingTierAppServices": {
|
||||||
|
"value": "[parameters('pricingTierAppServices')]"
|
||||||
|
},
|
||||||
|
"pricingTierStorageAccounts": {
|
||||||
|
"value": "[parameters('pricingTierStorageAccounts')]"
|
||||||
|
},
|
||||||
|
"pricingTierContainerRegistry": {
|
||||||
|
"value": "[parameters('pricingTierContainerRegistry')]"
|
||||||
|
},
|
||||||
|
"pricingTierKeyVaults": {
|
||||||
|
"value": "[parameters('pricingTierKeyVaults')]"
|
||||||
|
},
|
||||||
|
"pricingTierKubernetesService": {
|
||||||
|
"value": "[parameters('pricingTierKubernetesService')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"template": {
|
||||||
|
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
|
||||||
|
"contentVersion": "1.0.0.0",
|
||||||
|
"parameters": {
|
||||||
|
"pricingTierVMs": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "pricingTierVMs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pricingTierSqlServers": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "pricingTierSqlServers"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pricingTierAppServices": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "pricingTierAppServices"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pricingTierStorageAccounts": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "pricingTierStorageAccounts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pricingTierContainerRegistry": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "ContainerRegistry"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pricingTierKeyVaults": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "KeyVaults"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pricingTierKubernetesService": {
|
||||||
|
"type": "string",
|
||||||
|
"metadata": {
|
||||||
|
"description": "KubernetesService"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"variables": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "VirtualMachines",
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierVMs')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "StorageAccounts",
|
||||||
|
"dependsOn": [
|
||||||
|
"[concat('Microsoft.Security/pricings/VirtualMachines')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierStorageAccounts')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "AppServices",
|
||||||
|
"dependsOn": [
|
||||||
|
"[concat('Microsoft.Security/pricings/StorageAccounts')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierAppServices')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "SqlServers",
|
||||||
|
"dependsOn": [
|
||||||
|
"[concat('Microsoft.Security/pricings/AppServices')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierSqlServers')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "KeyVaults",
|
||||||
|
"dependsOn": [
|
||||||
|
"[concat('Microsoft.Security/pricings/SqlServers')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierKeyVaults')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "KubernetesService",
|
||||||
|
"dependsOn": [
|
||||||
|
"[concat('Microsoft.Security/pricings/KeyVaults')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierKubernetesService')]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Microsoft.Security/pricings",
|
||||||
|
"apiVersion": "2018-06-01",
|
||||||
|
"name": "ContainerRegistry",
|
||||||
|
"dependsOn": [
|
||||||
|
"[concat('Microsoft.Security/pricings/KubernetesService')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"pricingTier": "[parameters('pricingTierContainerRegistry')]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Map of the remote data state
|
||||||
|
variable lower_storage_account_name {}
|
||||||
|
variable lower_container_name {}
|
||||||
|
variable lower_resource_group_name {}
|
||||||
|
|
||||||
|
variable tfstate_storage_account_name {
|
||||||
|
description = "This value is propulated by the rover"
|
||||||
|
}
|
||||||
|
variable tfstate_container_name {
|
||||||
|
description = "This value is propulated by the rover"
|
||||||
|
}
|
||||||
|
variable tfstate_key {
|
||||||
|
description = "This value is propulated by the rover"
|
||||||
|
}
|
||||||
|
variable tfstate_resource_group_name {
|
||||||
|
description = "This value is propulated by the rover"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable landingzone {
|
||||||
|
default = {
|
||||||
|
backend_type = "azurerm"
|
||||||
|
global_settings_key = "launchpad"
|
||||||
|
level = "level1"
|
||||||
|
key = "foundations"
|
||||||
|
tfstates = {
|
||||||
|
launchpad = {
|
||||||
|
level = "lower"
|
||||||
|
tfstate = "caf_launchpad.tfstate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable tenant_id {}
|
||||||
|
variable rover_version {}
|
||||||
|
variable logged_user_objectId {
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
variable logged_aad_app_objectId {
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
variable tags {
|
||||||
|
type = map
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable enterprise_scale {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable diagnostics_definition {
|
||||||
|
default = {}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
# The PAT token must be provisioned in a different deployment
|
||||||
|
provider "azuredevops" {
|
||||||
|
org_service_url = var.azure_devops.url
|
||||||
|
personal_access_token = data.azurerm_key_vault_secret.pat.value
|
||||||
|
}
|
||||||
|
|
||||||
|
data "azurerm_key_vault_secret" "pat" {
|
||||||
|
name = var.azure_devops.pats["admin"].secret_name
|
||||||
|
key_vault_id = local.remote.keyvaults[var.azure_devops.pats["admin"].lz_key][var.azure_devops.pats["admin"].keyvault_key].id
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data "azuredevops_project" "project" {
|
||||||
|
project_name = var.azure_devops.project
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
|
||||||
|
locals {
|
||||||
|
organization_agent_pools = try(var.azure_devops.organization_agent_pools, {})
|
||||||
|
project_agent_pools = try(var.azure_devops.project_agent_pools, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## Agent pools
|
||||||
|
## Those pools are created in the organization, not the project
|
||||||
|
resource "azuredevops_agent_pool" "pool" {
|
||||||
|
for_each = try(var.azure_devops.organization_agent_pools, {})
|
||||||
|
|
||||||
|
name = each.value.name
|
||||||
|
auto_provision = lookup(each.value, "auto_provision", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# add the agent pools into the project
|
||||||
|
#
|
||||||
|
|
||||||
|
data "azuredevops_agent_pool" "pool" {
|
||||||
|
depends_on = [azuredevops_agent_pool.pool]
|
||||||
|
for_each = try(var.azure_devops.project_agent_pools, {})
|
||||||
|
|
||||||
|
name = each.value.name
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azuredevops_agent_queue" "agent_queue" {
|
||||||
|
for_each = data.azuredevops_agent_pool.pool
|
||||||
|
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
agent_pool_id = each.value.id
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = [
|
||||||
|
agent_pool_id
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Grant acccess to queue to all pipelines in the project
|
||||||
|
#
|
||||||
|
|
||||||
|
resource "azuredevops_resource_authorization" "queue" {
|
||||||
|
for_each = data.azuredevops_agent_pool.pool
|
||||||
|
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
resource_id = azuredevops_agent_queue.agent_queue[each.key].id
|
||||||
|
type = "queue"
|
||||||
|
authorized = true
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
data "azuredevops_git_repositories" "repos" {
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
locals {
|
||||||
|
repositories = zipmap(tolist(data.azuredevops_git_repositories.repos.repositories.*.name), tolist(data.azuredevops_git_repositories.repos.repositories))
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azuredevops_build_definition" "build_definition" {
|
||||||
|
|
||||||
|
for_each = try(var.azure_devops.pipelines, {})
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
name = each.value.name
|
||||||
|
path = each.value.folder
|
||||||
|
|
||||||
|
variable_groups = lookup(each.value, "variable_group_keys", null) == null ? null : [
|
||||||
|
for key in each.value.variable_group_keys :
|
||||||
|
azuredevops_variable_group.variable_group[key].id
|
||||||
|
]
|
||||||
|
|
||||||
|
repository {
|
||||||
|
repo_id = local.repositories[each.value.git_repo_name].id
|
||||||
|
repo_type = each.value.repo_type
|
||||||
|
yml_path = each.value.yaml
|
||||||
|
branch_name = lookup(each.value, "branch_name", null)
|
||||||
|
# service_connection_id = lookup(each.value, "repo_type", null) == "github" ? null : azuredevops_serviceendpoint_azurerm.github[each.value.service_connection_key].id
|
||||||
|
}
|
||||||
|
|
||||||
|
ci_trigger {
|
||||||
|
use_yaml = true
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "variable" {
|
||||||
|
for_each = try(each.value.variables, {})
|
||||||
|
|
||||||
|
content {
|
||||||
|
name = variable.key
|
||||||
|
value = variable.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
|
||||||
|
data "azurerm_key_vault_secret" "client_secret" {
|
||||||
|
depends_on = [module.caf]
|
||||||
|
for_each = try(var.azure_devops.service_endpoints, {})
|
||||||
|
|
||||||
|
name = format("%s-client-secret", local.combined.aad_apps[var.landingzone.key][each.value.aad_app_key].keyvaults[each.value.secret_keyvault_key].secret_name_client_secret)
|
||||||
|
key_vault_id = local.combined.aad_apps[var.landingzone.key][each.value.aad_app_key].keyvaults[each.value.secret_keyvault_key].id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azuredevops_serviceendpoint_azurerm" "azure" {
|
||||||
|
depends_on = [module.caf]
|
||||||
|
for_each = try(var.azure_devops.service_endpoints, {})
|
||||||
|
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
service_endpoint_name = each.value.endpoint_name
|
||||||
|
credentials {
|
||||||
|
serviceprincipalid = local.combined.aad_apps[var.landingzone.key][each.value.aad_app_key].azuread_application.application_id
|
||||||
|
serviceprincipalkey = data.azurerm_key_vault_secret.client_secret[each.key].value
|
||||||
|
}
|
||||||
|
azurerm_spn_tenantid = local.combined.aad_apps[var.landingzone.key][each.value.aad_app_key].tenant_id
|
||||||
|
azurerm_subscription_id = each.value.subscription_id
|
||||||
|
azurerm_subscription_name = each.value.subscription_name
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Grant acccess to service endpoint to all pipelines in the project
|
||||||
|
#
|
||||||
|
|
||||||
|
resource "azuredevops_resource_authorization" "endpoint" {
|
||||||
|
for_each = azuredevops_serviceendpoint_azurerm.azure
|
||||||
|
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
resource_id = each.value.id
|
||||||
|
type = "endpoint"
|
||||||
|
authorized = true
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#
|
||||||
|
# permissions required:
|
||||||
|
# - vso.variablegroups_manage (create)
|
||||||
|
# + vso.buid (update)
|
||||||
|
# + vso.build_execute (destroy)
|
||||||
|
#
|
||||||
|
resource "azuredevops_variable_group" "variable_group" {
|
||||||
|
for_each = try(var.azure_devops.variable_groups, {})
|
||||||
|
|
||||||
|
project_id = data.azuredevops_project.project.id
|
||||||
|
name = each.value.name
|
||||||
|
description = try(each.value.description, null)
|
||||||
|
allow_access = try(each.value.allow_access, false)
|
||||||
|
|
||||||
|
dynamic "key_vault" {
|
||||||
|
for_each = lookup(each.value, "keyvault", null) == null ? [] : [1]
|
||||||
|
|
||||||
|
content {
|
||||||
|
name = try(each.value.keyvault.lz_key, null) == null ? local.combined.keyvaults[var.landingzone.key][each.value.keyvault.keyvault_key].name : local.combined.keyvaults[each.value.keyvault.lz_key][each.value.keyvault.keyvault_key].name
|
||||||
|
service_endpoint_id = azuredevops_serviceendpoint_azurerm.azure[each.value.keyvault.serviceendpoint_key].id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic "variable" {
|
||||||
|
for_each = {
|
||||||
|
for key, variable in each.value.variables : key => {
|
||||||
|
name = key == "name" ? variable : key
|
||||||
|
value = key == "name" ? null : variable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
content {
|
||||||
|
# When used with Keyvault, the name must be the keyvault secret name and value must not be set
|
||||||
|
name = variable.value.name
|
||||||
|
value = variable.value.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Двоичные данные
landingzones/caf_launchpad/add-ons/azure_devops/documentation/images/pat_token.png
Normal file
После Ширина: | Высота: | Размер: 76 KiB |
|
@ -0,0 +1,84 @@
|
||||||
|
locals {
|
||||||
|
landingzone = {
|
||||||
|
current = {
|
||||||
|
storage_account_name = var.tfstate_storage_account_name
|
||||||
|
container_name = var.tfstate_container_name
|
||||||
|
resource_group_name = var.tfstate_resource_group_name
|
||||||
|
}
|
||||||
|
lower = {
|
||||||
|
storage_account_name = var.lower_storage_account_name
|
||||||
|
container_name = var.lower_container_name
|
||||||
|
resource_group_name = var.lower_resource_group_name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "terraform_remote_state" "remote" {
|
||||||
|
for_each = try(var.landingzone.tfstates, {})
|
||||||
|
|
||||||
|
backend = var.landingzone.backend_type
|
||||||
|
config = {
|
||||||
|
storage_account_name = local.landingzone[try(each.value.level, "current")].storage_account_name
|
||||||
|
container_name = local.landingzone[try(each.value.level, "current")].container_name
|
||||||
|
resource_group_name = local.landingzone[try(each.value.level, "current")].resource_group_name
|
||||||
|
key = each.value.tfstate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
landingzone_tag = {
|
||||||
|
"landingzone" = var.landingzone.key
|
||||||
|
}
|
||||||
|
|
||||||
|
tags = merge(var.tags, local.landingzone_tag, { "level" = var.landingzone.level }, { "environment" = local.global_settings.environment }, { "rover_version" = var.rover_version })
|
||||||
|
|
||||||
|
global_settings = {
|
||||||
|
prefix = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.prefix
|
||||||
|
prefix_with_hyphen = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.prefix_with_hyphen
|
||||||
|
prefix_start_alpha = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.prefix_start_alpha
|
||||||
|
default_region = try(var.global_settings.default_region, data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.default_region)
|
||||||
|
environment = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.environment
|
||||||
|
regions = try(var.global_settings.regions, data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.regions)
|
||||||
|
passthrough = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.passthrough
|
||||||
|
random_length = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.global_settings.random_length
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnostics = {
|
||||||
|
diagnostics_definition = merge(data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.diagnostics_definition, var.diagnostics_definition)
|
||||||
|
diagnostics_destinations = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.diagnostics_destinations
|
||||||
|
storage_accounts = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.storage_accounts
|
||||||
|
log_analytics = data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.diagnostics.log_analytics
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
combined = {
|
||||||
|
aad_apps = merge(local.remote.aad_apps, map(var.landingzone.key, module.caf.aad_apps))
|
||||||
|
azuread_groups = merge(local.remote.azuread_groups, map(var.landingzone.key, module.caf.azuread_groups))
|
||||||
|
keyvaults = merge(local.remote.keyvaults, map(var.landingzone.key, module.caf.keyvaults))
|
||||||
|
managed_identities = merge(local.remote.managed_identities, map(var.landingzone.key, module.caf.managed_identities))
|
||||||
|
}
|
||||||
|
|
||||||
|
remote = {
|
||||||
|
aad_apps = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.aad_apps[key], {}))
|
||||||
|
}
|
||||||
|
|
||||||
|
azuread_groups = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.azuread_groups[key], {}))
|
||||||
|
}
|
||||||
|
|
||||||
|
keyvaults = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.keyvaults[key], {}))
|
||||||
|
}
|
||||||
|
|
||||||
|
managed_identities = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.managed_identities[key], {}))
|
||||||
|
}
|
||||||
|
|
||||||
|
vnets = {
|
||||||
|
for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.vnets[key], {}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
azurerm = {
|
||||||
|
source = "hashicorp/azurerm"
|
||||||
|
version = "~> 2.32.0"
|
||||||
|
}
|
||||||
|
azuread = {
|
||||||
|
source = "hashicorp/azuread"
|
||||||
|
version = "~> 1.0.0"
|
||||||
|
}
|
||||||
|
random = {
|
||||||
|
source = "hashicorp/random"
|
||||||
|
version = "~> 2.2.1"
|
||||||
|
}
|
||||||
|
null = {
|
||||||
|
source = "hashicorp/null"
|
||||||
|
version = "~> 2.1.0"
|
||||||
|
}
|
||||||
|
external = {
|
||||||
|
source = "hashicorp/external"
|
||||||
|
version = "~> 1.2.0"
|
||||||
|
}
|
||||||
|
azuredevops = {
|
||||||
|
source = "terraform-providers/azuredevops"
|
||||||
|
version = "~> 0.0.1"
|
||||||
|
}
|
||||||
|
tls = {
|
||||||
|
source = "hashicorp/tls"
|
||||||
|
version = "~> 2.2.0"
|
||||||
|
}
|
||||||
|
azurecaf = {
|
||||||
|
source = "aztfmod/azurecaf"
|
||||||
|
version = "~>1.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required_version = ">= 0.13"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "azurerm" {
|
||||||
|
features {
|
||||||
|
key_vault {
|
||||||
|
purge_soft_delete_on_destroy = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "azurerm_client_config" "current" {}
|
||||||
|
|
||||||
|
|
||||||
|
locals {
|
||||||
|
|
||||||
|
|
||||||
|
tfstates = merge(
|
||||||
|
map(var.landingzone.backend_type,
|
||||||
|
map(
|
||||||
|
"storage_account_name", var.tfstate_storage_account_name,
|
||||||
|
"container_name", var.tfstate_container_name,
|
||||||
|
"resource_group_name", var.tfstate_resource_group_name,
|
||||||
|
"key", var.tfstate_key,
|
||||||
|
"level", var.landingzone.level,
|
||||||
|
"tenant_id", var.tenant_id,
|
||||||
|
"subscription_id", data.azurerm_client_config.current.subscription_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
,
|
||||||
|
data.terraform_remote_state.remote[var.landingzone.global_settings_key].outputs.tfstates
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
output keyvaults {
|
||||||
|
value = map(
|
||||||
|
var.landingzone.key, module.caf.keyvaults
|
||||||
|
)
|
||||||
|
sensitive = true
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Cloud Adoption Framework for Azure - Landing zones on Terraform - Azure Devops add-on
|
||||||
|
|
||||||
|
The Azure Devops add-ons allow you to setup you Azure Devops environment as a platform to automate all your subsequent landing zone deployment from level 0 until level 4 through Azure pipelines with self hosted agents.
|
||||||
|
|
||||||
|
* Azure Devops:
|
||||||
|
- Agent Pools (Organization and Project Level)
|
||||||
|
- Service Endpoint
|
||||||
|
- Variables and Variable Groups
|
||||||
|
- Pipelines
|
||||||
|
|
||||||
|
* Azure (Connection with Azure Devops):
|
||||||
|
- Azure AD Application
|
||||||
|
- Custom Role
|
||||||
|
- Keyvault and access policies for Azure AD App
|
||||||
|
|
||||||
|
Azure Devops add-on landing zone operates at **level 0**
|
||||||
|
|
||||||
|
For a review of the hierarchy approach of Cloud Adoption Framework for Azure landing zones on Terraform, you can refer to [the following documentation](../../documentation/code_architecture/hierarchy.md).
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Landing zone:
|
||||||
|
* CAF Launchpad (Scenario 200 or above)
|
||||||
|
|
||||||
|
Azure Devops (example):
|
||||||
|
* Organization: https://dev.azure.com/azure-terraform
|
||||||
|
* Project : contoso_demo (https://dev.azure.com/azure-terraform/contoso_demo)
|
||||||
|
* Repo : caf-configuration (https://dev.azure.com/azure-terraform/contoso_demo/_git/caf-configuration)
|
||||||
|
- In order for pipeline to work properly, YAML file should be in this repo and referred accordingly under pipeline section in azure_devops.tfvars
|
||||||
|
- sample yaml attached [here](./scenario/200-contoso_demo/pipeline/rover.yaml).
|
||||||
|
|
||||||
|
Azure:
|
||||||
|
* PAT Token : PAT Token should be updated in keyvault secret that deployed by launchpad LZ as below
|
||||||
|
|
||||||
|
![](./documentation/images/pat_token.png)
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rover -lz /tf/caf/landingzones/caf_launchpad/add-ons/azure_devops \
|
||||||
|
-tfstate azure_devops-contoso_demo.tfstate \
|
||||||
|
-var-folder /tf/caf/landingzones/caf_launchpad/add-ons/azure_devops/scenario/200-contoso_demo \
|
||||||
|
-parallelism 30 \
|
||||||
|
-level level0 \
|
||||||
|
-a apply -env sandpit
|
||||||
|
```
|
||||||
|
|
||||||
|
We are planning to release more examples on how to deploy the Azure Devops Agents.
|
|
@ -0,0 +1,232 @@
|
||||||
|
|
||||||
|
|
||||||
|
azure_devops = {
|
||||||
|
|
||||||
|
url = "https://dev.azure.com/azure-terraform/"
|
||||||
|
project = "contoso_demo"
|
||||||
|
|
||||||
|
# PAT Token should be updated manually to the keyvault after running launchpad
|
||||||
|
pats = {
|
||||||
|
admin = {
|
||||||
|
secret_name = "azdo-pat-admin"
|
||||||
|
lz_key = "launchpad"
|
||||||
|
keyvault_key = "secrets"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
organization_agent_pools = {
|
||||||
|
level0 = {
|
||||||
|
name = "caf-sandpit-level0"
|
||||||
|
auto_provision = false # When set to false the agent pool is not populated automatically into the devops projects (recommended)
|
||||||
|
}
|
||||||
|
level1 = {
|
||||||
|
name = "caf-sandpit-level1"
|
||||||
|
auto_provision = false
|
||||||
|
}
|
||||||
|
level2 = {
|
||||||
|
name = "caf-sandpit-level2"
|
||||||
|
auto_provision = false
|
||||||
|
}
|
||||||
|
level3 = {
|
||||||
|
name = "caf-sandpit-level3"
|
||||||
|
auto_provision = false
|
||||||
|
}
|
||||||
|
level4 = {
|
||||||
|
name = "caf-sandpit-level4"
|
||||||
|
auto_provision = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project_agent_pools = {
|
||||||
|
level0 = {
|
||||||
|
name = "caf-sandpit-level0"
|
||||||
|
}
|
||||||
|
level1 = {
|
||||||
|
name = "caf-sandpit-level1"
|
||||||
|
}
|
||||||
|
level2 = {
|
||||||
|
name = "caf-sandpit-level2"
|
||||||
|
}
|
||||||
|
level3 = {
|
||||||
|
name = "caf-sandpit-level3"
|
||||||
|
}
|
||||||
|
level4 = {
|
||||||
|
name = "caf-sandpit-level4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
service_endpoints = {
|
||||||
|
contoso_demo = {
|
||||||
|
endpoint_name = "terraformdev (terraformdev.onmicrosoft.com) - contoso_demo"
|
||||||
|
subscription_name = "ase-landingzone"
|
||||||
|
subscription_id = "1d53e782-9f46-4720-b6b3-cff29106e9f6"
|
||||||
|
aad_app_key = "contoso_demo"
|
||||||
|
secret_keyvault_key = "devops"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable_groups = {
|
||||||
|
global = {
|
||||||
|
name = "release-global" # changing that name requires to change it in the devops agents yaml variables group
|
||||||
|
allow_access = true
|
||||||
|
variables = {
|
||||||
|
HOME_FOLDER_USER = "vsts_azpcontainer"
|
||||||
|
ROVER_IMAGE = "aztfmod/rover:2010.2808"
|
||||||
|
TF_CLI_ARGS = "'-no-color'"
|
||||||
|
TF_CLI_ARGS_init = ""
|
||||||
|
TF_CLI_ARGS_plan = "'-input=false'"
|
||||||
|
TF_VAR_ARGS_destroy = "'-auto-approve -refresh=false'"
|
||||||
|
ENVIRONMENT = "sandpit"
|
||||||
|
LANDINGZONE_BRANCH = "2010.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level0 = {
|
||||||
|
name = "release-level0"
|
||||||
|
allow_access = true
|
||||||
|
variables = {
|
||||||
|
TF_VAR_pipeline_level = "level0"
|
||||||
|
ARM_USE_MSI = "true"
|
||||||
|
AGENT_POOL = "caf-sandpit-level0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level0_kv = {
|
||||||
|
name = "release-level0-msi"
|
||||||
|
allow_access = true
|
||||||
|
keyvault = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
keyvault_key = "level0"
|
||||||
|
serviceendpoint_key = "contoso_demo"
|
||||||
|
}
|
||||||
|
variables = {
|
||||||
|
name = "msi-resource-id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level1 = {
|
||||||
|
name = "release-level1"
|
||||||
|
allow_access = true
|
||||||
|
variables = {
|
||||||
|
TF_VAR_pipeline_level = "level1"
|
||||||
|
ARM_USE_MSI = "true"
|
||||||
|
AGENT_POOL = "caf-sandpit-level1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level1_kv = {
|
||||||
|
name = "release-level1-msi"
|
||||||
|
allow_access = true
|
||||||
|
keyvault = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
keyvault_key = "level1"
|
||||||
|
serviceendpoint_key = "contoso_demo"
|
||||||
|
}
|
||||||
|
variables = {
|
||||||
|
name = "msi-resource-id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level2 = {
|
||||||
|
name = "release-level2"
|
||||||
|
allow_access = true
|
||||||
|
variables = {
|
||||||
|
TF_VAR_pipeline_level = "level2"
|
||||||
|
ARM_USE_MSI = "true"
|
||||||
|
AGENT_POOL = "caf-sandpit-level2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level2_kv = {
|
||||||
|
name = "release-level2-msi"
|
||||||
|
allow_access = true
|
||||||
|
keyvault = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
keyvault_key = "level2"
|
||||||
|
serviceendpoint_key = "contoso_demo"
|
||||||
|
}
|
||||||
|
variables = {
|
||||||
|
name = "msi-resource-id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level3 = {
|
||||||
|
name = "release-level3"
|
||||||
|
allow_access = true
|
||||||
|
variables = {
|
||||||
|
TF_VAR_pipeline_level = "level3"
|
||||||
|
ARM_USE_MSI = "true"
|
||||||
|
AGENT_POOL = "caf-sandpit-level3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level3_kv = {
|
||||||
|
name = "release-level3-msi"
|
||||||
|
allow_access = true
|
||||||
|
keyvault = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
keyvault_key = "level3"
|
||||||
|
serviceendpoint_key = "contoso_demo"
|
||||||
|
}
|
||||||
|
variables = {
|
||||||
|
name = "msi-resource-id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pipelines = {
|
||||||
|
|
||||||
|
#
|
||||||
|
# Agent pools
|
||||||
|
#
|
||||||
|
|
||||||
|
devops_agent_level1_plan = {
|
||||||
|
name = "devops_agent_level1_plan"
|
||||||
|
folder = "\\configuration\\level1"
|
||||||
|
yaml = "configuration/pipeline/rover.yaml"
|
||||||
|
repo_type = "TfsGit"
|
||||||
|
git_repo_name = "caf-configuration"
|
||||||
|
variables = {
|
||||||
|
landingZoneName = "azdo-agent-level1",
|
||||||
|
terraformAction = "plan",
|
||||||
|
tfstateName = "azdo-agent-level1.tfstate"
|
||||||
|
configPath = "/configuration/level1/azuredevops/agent"
|
||||||
|
landingZonePath = "/public/landingzones/caf_launchpad/add-ons/azure_devops_agent"
|
||||||
|
level = "level1"
|
||||||
|
}
|
||||||
|
variable_group_keys = ["global", "level0", "level0_kv"]
|
||||||
|
}
|
||||||
|
devops_agent_level1_apply = {
|
||||||
|
name = "devops_agent_level1_apply"
|
||||||
|
folder = "\\configuration\\level1"
|
||||||
|
yaml = "configuration/pipeline/rover.yaml"
|
||||||
|
repo_type = "TfsGit"
|
||||||
|
git_repo_name = "caf-configuration"
|
||||||
|
variables = {
|
||||||
|
landingZoneName = "azdo-agent-level1",
|
||||||
|
terraformAction = "apply",
|
||||||
|
tfstateName = "azdo-agent-level1.tfstate"
|
||||||
|
configPath = "/configuration/level1/azuredevops/agent"
|
||||||
|
landingZonePath = "/public/landingzones/caf_launchpad/add-ons/azure_devops_agent"
|
||||||
|
level = "level1"
|
||||||
|
}
|
||||||
|
variable_group_keys = ["global", "level0", "level0_kv"]
|
||||||
|
}
|
||||||
|
devops_agent_level1_destroy = {
|
||||||
|
name = "devops_agent_level1_destroy"
|
||||||
|
folder = "\\configuration\\level1"
|
||||||
|
yaml = "configuration/pipeline/rover.yaml"
|
||||||
|
repo_type = "TfsGit"
|
||||||
|
git_repo_name = "caf-configuration"
|
||||||
|
variables = {
|
||||||
|
landingZoneName = "azdo-agent-level1",
|
||||||
|
terraformAction = "destroy",
|
||||||
|
tfstateName = "azdo-agent-level1.tfstate"
|
||||||
|
configPath = "/configuration/level1/azuredevops/agent"
|
||||||
|
landingZonePath = "/public/landingzones/caf_launchpad/add-ons/azure_devops_agent"
|
||||||
|
level = "level1"
|
||||||
|
}
|
||||||
|
variable_group_keys = ["global", "level0", "level0_kv"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
landingzone = {
|
||||||
|
backend_type = "azurerm"
|
||||||
|
global_settings_key = "launchpad"
|
||||||
|
level = "level0"
|
||||||
|
key = "azdo-contoso_demo"
|
||||||
|
tfstates = {
|
||||||
|
launchpad = {
|
||||||
|
level = "current"
|
||||||
|
tfstate = "caf_launchpad.tfstate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource_groups = {
|
||||||
|
rg1 = {
|
||||||
|
name = "devops-agents-security"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
keyvaults = {
|
||||||
|
devops = {
|
||||||
|
name = "devops"
|
||||||
|
resource_group_key = "rg1"
|
||||||
|
sku_name = "standard"
|
||||||
|
|
||||||
|
creation_policies = {
|
||||||
|
keyvault_level0_rw = {
|
||||||
|
# Reference a key to an azure ad group
|
||||||
|
lz_key = "launchpad"
|
||||||
|
azuread_group_key = "keyvault_level0_rw"
|
||||||
|
secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keyvault_access_policies_azuread_apps = {
|
||||||
|
level0 = {
|
||||||
|
contoso_demo = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
azuread_app_key = "contoso_demo"
|
||||||
|
secret_permissions = ["Get", "List"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level1 = {
|
||||||
|
contoso_demo = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
azuread_app_key = "contoso_demo"
|
||||||
|
secret_permissions = ["Get", "List"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level2 = {
|
||||||
|
contoso_demo = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
azuread_app_key = "contoso_demo"
|
||||||
|
secret_permissions = ["Get", "List"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level3 = {
|
||||||
|
contoso_demo = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
azuread_app_key = "contoso_demo"
|
||||||
|
secret_permissions = ["Get", "List"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level4 = {
|
||||||
|
contoso_demo = {
|
||||||
|
lz_key = "launchpad"
|
||||||
|
azuread_app_key = "contoso_demo"
|
||||||
|
secret_permissions = ["Get", "List"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
azuread_apps = {
|
||||||
|
|
||||||
|
contoso_demo = {
|
||||||
|
useprefix = true
|
||||||
|
application_name = "caf-level4-contoso_demo"
|
||||||
|
password_expire_in_days = 60
|
||||||
|
tenant_name = "terraformdev.onmicrosoft.com"
|
||||||
|
reply_urls = ["https://localhost"]
|
||||||
|
keyvaults = {
|
||||||
|
devops = {
|
||||||
|
secret_prefix = "aadapp-caf-level4-azdo-contoso_demo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_role_definitions = {
|
||||||
|
|
||||||
|
caf-azdo-to-azure-subscription = {
|
||||||
|
name = "caf-azure-devops-azure-app-service-improvement-program-TO-azure-subscription"
|
||||||
|
useprefix = true
|
||||||
|
description = "CAF Custom role for service principal in Azure Devops to access resources"
|
||||||
|
permissions = {
|
||||||
|
actions = [
|
||||||
|
"Microsoft.Resources/subscriptions/read",
|
||||||
|
"Microsoft.KeyVault/vaults/read"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
role_mapping = {
|
||||||
|
custom_role_mapping = {
|
||||||
|
subscriptions = {
|
||||||
|
logged_in_subscription = {
|
||||||
|
"caf-azdo-to-azure-subscription" = {
|
||||||
|
azuread_apps = {
|
||||||
|
keys = ["contoso_demo"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
parameters:
|
||||||
|
- name: timeoutInMinutes
|
||||||
|
displayName: 'Timeout in minutes'
|
||||||
|
type: number
|
||||||
|
default: 60
|
||||||
|
|
||||||
|
variables:
|
||||||
|
- group: release-global
|
||||||
|
|
||||||
|
resources:
|
||||||
|
containers:
|
||||||
|
- container: rover
|
||||||
|
image: $(ROVER_IMAGE)
|
||||||
|
options: --user 0:0 -e TF_PLUGIN_CACHE_DIR="/home/$(HOME_FOLDER_USER)/plugin-cache" -e TF_DATA_DIR="/home/$(HOME_FOLDER_USER)"
|
||||||
|
|
||||||
|
trigger: none
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: CAF_Rover
|
||||||
|
|
||||||
|
displayName: Azure Landing Zone
|
||||||
|
|
||||||
|
pool: $(AGENT_POOL)
|
||||||
|
|
||||||
|
continueOnError: false
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
clean: all
|
||||||
|
|
||||||
|
container: rover
|
||||||
|
|
||||||
|
timeoutInMinutes: ${{ parameters.timeoutInMinutes }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- checkout: self
|
||||||
|
|
||||||
|
- bash: |
|
||||||
|
git clone --branch $(LANDINGZONE_BRANCH) https://github.com/Azure/caf-terraform-landingzones.git ${BUILD_REPOSITORY_LOCALPATH}/public 2>/dev/null
|
||||||
|
|
||||||
|
az login --identity -u $(msi-resource-id)
|
||||||
|
|
||||||
|
/tf/rover/rover.sh -lz ${BUILD_REPOSITORY_LOCALPATH}$(landingZonePath) \
|
||||||
|
-tfstate $(tfstateName) \
|
||||||
|
-var-folder ${BUILD_REPOSITORY_LOCALPATH}$(configPath) \
|
||||||
|
-parallelism=30 \
|
||||||
|
-level $(level) \
|
||||||
|
-a $(terraformAction) \
|
||||||
|
-env $(ENVIRONMENT)
|
||||||
|
|
||||||
|
condition: ne(variables['terraformAction'], 'destroy')
|
||||||
|
failOnStderr: true
|
||||||
|
displayName: 'Terraform $(terraformAction)'
|
||||||
|
|
||||||
|
- bash: |
|
||||||
|
git clone --branch $(LANDINGZONE_BRANCH) https://github.com/Azure/caf-terraform-landingzones.git ${BUILD_REPOSITORY_LOCALPATH}/public 2>/dev/null
|
||||||
|
|
||||||
|
az login --identity -u $(msi-resource-id)
|
||||||
|
|
||||||
|
/tf/rover/rover.sh -lz ${BUILD_REPOSITORY_LOCALPATH}$(landingZonePath) \
|
||||||
|
-tfstate $(tfstateName) \
|
||||||
|
-var-folder ${BUILD_REPOSITORY_LOCALPATH}$(configPath) \
|
||||||
|
-parallelism=30 \
|
||||||
|
-level $(level) \
|
||||||
|
-a $(terraformAction) \
|
||||||
|
-auto-approve \
|
||||||
|
-env $(ENVIRONMENT)
|
||||||
|
|
||||||
|
condition: eq(variables['terraformAction'], 'destroy')
|
||||||
|
failOnStderr: true
|
||||||
|
displayName: 'Terraform destroy'
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
module "caf" {
|
||||||
|
source = "aztfmod/caf/azurerm"
|
||||||
|
version = "~> 0.4"
|
||||||
|
|
||||||
|
current_landingzone_key = var.landingzone.key
|
||||||
|
tenant_id = var.tenant_id
|
||||||
|
tfstates = local.tfstates
|
||||||
|
tags = local.tags
|
||||||
|
global_settings = local.global_settings
|
||||||
|
diagnostics = local.diagnostics
|
||||||
|
diagnostic_storage_accounts = var.diagnostic_storage_accounts
|
||||||
|
logged_user_objectId = var.logged_user_objectId
|
||||||
|
logged_aad_app_objectId = var.logged_aad_app_objectId
|
||||||
|
resource_groups = var.resource_groups
|
||||||
|
storage_accounts = var.storage_accounts
|
||||||
|
azuread_groups = var.azuread_groups
|
||||||
|
keyvaults = var.keyvaults
|
||||||
|
keyvault_access_policies = var.keyvault_access_policies
|
||||||
|
keyvault_access_policies_azuread_apps = var.keyvault_access_policies_azuread_apps
|
||||||
|
role_mapping = var.role_mapping
|
||||||
|
custom_role_definitions = var.custom_role_definitions
|
||||||
|
azuread_apps = var.azuread_apps
|
||||||
|
compute = {
|
||||||
|
virtual_machines = var.virtual_machines
|
||||||
|
}
|
||||||
|
storage = {
|
||||||
|
storage_account_blobs = var.storage_account_blobs
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_objects = {
|
||||||
|
keyvaults = local.remote.keyvaults
|
||||||
|
vnets = local.remote.vnets
|
||||||
|
managed_identities = local.remote.managed_identities
|
||||||
|
azuread_groups = local.remote.azuread_groups
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
# Map of the remote data state for lower level
|
||||||
|
variable lower_storage_account_name {}
|
||||||
|
variable lower_container_name {}
|
||||||
|
variable lower_resource_group_name {}
|
||||||
|
|
||||||
|
variable tfstate_storage_account_name {}
|
||||||
|
variable tfstate_container_name {}
|
||||||
|
variable tfstate_key {}
|
||||||
|
variable tfstate_resource_group_name {}
|
||||||
|
|
||||||
|
variable global_settings {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable tenant_id {}
|
||||||
|
variable landingzone {
|
||||||
|
}
|
||||||
|
variable rover_version {
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable logged_user_objectId {
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
variable logged_aad_app_objectId {
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
variable tags {
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
variable app_service_environments {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable app_service_plans {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable app_services {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable diagnostics_definition {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable resource_groups {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable network_security_group_definition {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable vnets {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable azurerm_redis_caches {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable mssql_servers {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable storage_accounts {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable storage_account_blobs {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable azuread_groups {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable keyvaults {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable keyvault_access_policies {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable keyvault_access_policies_azuread_apps {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable virtual_machines {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable diagnostic_storage_accounts {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable virtual_machine_extension_scripts {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable azure_devops {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable role_mapping {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable custom_role_definitions {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable azuread_apps {
|
||||||
|
default = {}
|
||||||
|
}
|
||||||
|
variable dynamic_keyvault_secrets {
|
||||||
|
default = {}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
module secret {
|
||||||
|
source = "./secret"
|
||||||
|
for_each = {
|
||||||
|
for key, value in var.settings : key => value
|
||||||
|
if try(value.value, null) == null
|
||||||
|
}
|
||||||
|
|
||||||
|
name = each.value.secret_name
|
||||||
|
value = try(each.value.value, null) == null ? try(var.objects[each.value.output_key][each.value.resource_key][each.value.attribute_key], var.objects[each.value.output_key][each.value.attribute_key]) : each.value.value
|
||||||
|
keyvault_id = var.keyvault_id
|
||||||
|
}
|
||||||
|
|
||||||
|
module secret_immutable {
|
||||||
|
source = "./secret_immutable"
|
||||||
|
for_each = {
|
||||||
|
for key, value in var.settings : key => value
|
||||||
|
if try(value.value, null) == ""
|
||||||
|
}
|
||||||
|
|
||||||
|
name = each.value.secret_name
|
||||||
|
value = try(each.value.value, null) == null ? try(var.objects[each.value.output_key][each.value.resource_key][each.value.attribute_key], var.objects[each.value.output_key][each.value.attribute_key]) : each.value.value
|
||||||
|
keyvault_id = var.keyvault_id
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
resource "azurerm_key_vault_secret" "secret" {
|
||||||
|
name = var.name
|
||||||
|
value = var.value
|
||||||
|
key_vault_id = var.keyvault_id
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
variable name {}
|
||||||
|
variable value {}
|
||||||
|
variable keyvault_id {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
resource "azurerm_key_vault_secret" "secret" {
|
||||||
|
count = var.value == "" ? 1 : 0
|
||||||
|
name = var.name
|
||||||
|
value = var.value
|
||||||
|
key_vault_id = var.keyvault_id
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = [
|
||||||
|
value
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
variable name {}
|
||||||
|
variable value {}
|
||||||
|
variable keyvault_id {}
|
|
@ -0,0 +1,3 @@
|
||||||
|
variable settings {}
|
||||||
|
variable objects {}
|
||||||
|
variable keyvault_id {}
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
module dynamic_keyvault_secrets {
|
||||||
|
source = "./dynamic_keyvault_secrets"
|
||||||
|
for_each = try(var.dynamic_keyvault_secrets, {})
|
||||||
|
|
||||||
|
settings = each.value
|
||||||
|
keyvault_id = module.caf.keyvaults[each.key].id
|
||||||
|
objects = module.caf
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
resource "azurerm_virtual_machine_extension" "devops_selfhosted_agent" {
|
||||||
|
for_each = {
|
||||||
|
for key, value in var.extensions : key => value
|
||||||
|
if key == "devops_selfhosted_agent"
|
||||||
|
}
|
||||||
|
|
||||||
|
name = "install_azure_devops_agent"
|
||||||
|
|
||||||
|
virtual_machine_id = var.virtual_machine_id
|
||||||
|
publisher = "Microsoft.Azure.Extensions"
|
||||||
|
type = "CustomScript"
|
||||||
|
type_handler_version = "2.1"
|
||||||
|
|
||||||
|
#timestamp: use this field only to trigger a re-run of the script by changing value of this field.
|
||||||
|
# Any integer value is acceptable; it must only be different than the previous value.
|
||||||
|
settings = jsonencode(
|
||||||
|
{
|
||||||
|
"timestamp" : each.value.version,
|
||||||
|
"fileUris" : concat(local.devops_selfhosted_agent.file_uris, local.devops_selfhosted_agent.storage_account_blobs_urls),
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
protected_settings = jsonencode(
|
||||||
|
{
|
||||||
|
"commandToExecute" : format("bash %s '%s' '%s' '%s' '%s' '%s' '%s' '%s'", var.extensions[each.key].agent_init_script, var.settings[each.key].azure_devops.url, var.settings[each.key].agent_pat, var.settings[each.key].azure_devops.agent_pool.name, var.settings[each.key].azure_devops.agent_pool.agent_name_prefix, var.settings[each.key].azure_devops.agent_pool.num_agents, var.settings[each.key].admin_username, var.settings[each.key].azure_devops.rover_version)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
devops_selfhosted_agent = {
|
||||||
|
file_uris = flatten(
|
||||||
|
[
|
||||||
|
for file_uris_key, file in try(var.extensions.devops_selfhosted_agent.fileUris, {}) : [
|
||||||
|
for file_uri_key in file.storage_blob_keys : var.settings.devops_selfhosted_agent.storage_accounts[file.storage_account_key].containers[file.container_key].blobs[file_uri_key].url
|
||||||
|
]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
storage_account_blobs_urls = try(var.settings.devops_selfhosted_agent.storage_account_blobs_urls, [])
|
||||||
|
}
|
||||||
|
}
|