├── .trivyignore ├── .terraformrc ├── scripts ├── post-push.sh ├── init.sh ├── yor-tag.sh ├── gosec.sh ├── tffmt.sh ├── run-golangci-lint.sh ├── fmt.sh ├── fumpt.sh ├── build-test.sh ├── cleanup.sh ├── deps-ensure.sh ├── post-push-starter.sh ├── autofix.sh ├── ci-update-test-record.sh ├── run-e2e-test.sh ├── run-unit-test.sh ├── cleanup-actions.sh ├── gofmtcheck.sh ├── fumptcheck.sh ├── generate.sh ├── ci-e2e.sh ├── terraform-fmt.sh ├── checkovcheck.sh ├── terrafmt.sh ├── ci-version-upgrade.sh ├── update-test-record.sh ├── deps-check.sh ├── version-upgrade-test.sh ├── install.sh ├── gencheck.sh ├── checkovplancheck.sh ├── terrafmt-check.sh ├── init-actions.sh ├── terraform-validate.sh └── run-tflint.sh ├── avm_scripts ├── run-e2e-test.sh ├── run-terraform-test.sh ├── grept-precommit-check.sh ├── grept-precommit.sh ├── terraform-fmt-apply.sh ├── go-fumpt.sh ├── gofmt.sh ├── deps-ensure.sh ├── gosec.sh ├── grept-apply.sh ├── mapotf-precommit.sh ├── ci-update-test-record.sh ├── run-golangci-lint.sh ├── gofmtcheck.sh ├── ci-e2e.sh ├── terraform-fmt.sh ├── autofix.sh ├── fumptcheck.sh ├── ci-version-upgrade.sh ├── post-push.sh ├── mapotf-precommit-check.sh ├── terrafmt.sh ├── update-test-record.sh ├── version-upgrade-test.sh ├── terrafmt-check.sh ├── docs-gen.sh ├── run-tftest.sh ├── test-example.sh ├── docs-check.sh ├── prepare-credential.sh ├── terraform-validate.sh ├── conftest.sh └── run-tflint.sh ├── avm_scripts_canary ├── run-e2e-test.sh ├── run-unit-test.sh ├── grept-precommit.sh ├── go-fumpt.sh ├── deps-ensure.sh ├── mapotf-precommit.sh ├── gosec.sh ├── grept-apply.sh ├── ci-update-test-record.sh ├── clean.sh ├── run-golangci-lint.sh ├── gofmtcheck.sh ├── ci-e2e.sh ├── terraform-fmt.sh ├── autofix.sh ├── fumptcheck.sh ├── ci-version-upgrade.sh ├── mapotf-precommit-check.sh ├── grept-precommit-check.sh ├── post-push.sh ├── checkovcheck.sh ├── terrafmt.sh ├── update-test-record.sh ├── version-upgrade-test.sh ├── checkovplancheck.sh ├── terrafmt-check.sh ├── test-example.sh ├── docs-gen.sh ├── docs-check.sh ├── terraform-validate.sh ├── yor-tag.sh └── run-tflint.sh ├── workflows ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── Feature_Request.yml │ └── Bug_Report.yml ├── dependabot.yml ├── post-push.yaml ├── breaking-change-detect.yaml ├── pull_request_template.md ├── pr-check.yaml ├── weekly-e2e.yaml └── acc-test.yaml ├── scaffold-ci-scripts ├── check-tflint-plugin-version.sh └── sync-tflint-plugin-version.sh ├── .github └── workflows │ ├── breaking-change-detect.yaml │ ├── avm-makefile.yaml │ ├── weekly-codeql.yaml │ ├── pr-check.yaml │ ├── tfvm_e2e.yaml │ └── post-push.yaml ├── CODE_OF_CONDUCT.md ├── version.env ├── dockerbuild.sh ├── avm_mapotf └── pre_commit │ ├── required_provider_versions.mptf.hcl │ ├── avm_headers_for_azapi.mptf.hcl │ └── main_telemetry_tf.mptf.hcl ├── .devcontainer └── devcontainer.json ├── LICENSE ├── test-avm-module.sh ├── .gitignore ├── SECURITY.md ├── GNUmakefile ├── avmmakefile ├── avm.tflint.hcl ├── avm.tflint_example.hcl ├── avm.tflint_module.hcl ├── README.md ├── .tflint.hcl ├── .tflint_module.hcl └── .tflint_example.hcl /.trivyignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.terraformrc: -------------------------------------------------------------------------------- 1 | disable_checkpoint = true 2 | -------------------------------------------------------------------------------- /scripts/post-push.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash -------------------------------------------------------------------------------- /avm_scripts/run-e2e-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | -------------------------------------------------------------------------------- /avm_scripts/run-terraform-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | -------------------------------------------------------------------------------- /avm_scripts_canary/run-e2e-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | -------------------------------------------------------------------------------- /avm_scripts_canary/run-unit-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash -------------------------------------------------------------------------------- /scripts/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sh scripts/init-actions.sh -------------------------------------------------------------------------------- /workflows/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /scripts/yor-tag.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "skip yor tag" -------------------------------------------------------------------------------- /avm_scripts/grept-precommit-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | -------------------------------------------------------------------------------- /scripts/gosec.sh: -------------------------------------------------------------------------------- 1 | echo "==> Bypassing gosec check for TFVM modules for now." -------------------------------------------------------------------------------- /scripts/tffmt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Formatting terraform code..." 2 | terraform fmt -recursive 3 | -------------------------------------------------------------------------------- /scripts/run-golangci-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Bypassing Golangci-lint for now..." -------------------------------------------------------------------------------- /scripts/fmt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Fixing source code with gofmt..." 2 | find . -name '*.go' | grep -v vendor | xargs gofmt -s -w -------------------------------------------------------------------------------- /scripts/fumpt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Fixing source code with Gofumpt..." 2 | find . -name '*.go' | grep -v vendor | xargs gofumpt -w -------------------------------------------------------------------------------- /avm_scripts/grept-precommit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | grept apply -a git::https://github.com/Azure/Azure-Verified-Modules-Grept.git//terraform -------------------------------------------------------------------------------- /avm_scripts/terraform-fmt-apply.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | echo "==> Fixing Terraform code with terraform fmt..." 5 | terraform fmt -recursive -------------------------------------------------------------------------------- /workflows/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/test" 5 | schedule: 6 | interval: "weekly" -------------------------------------------------------------------------------- /avm_scripts/go-fumpt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Fixing source code with Gofumpt..." 3 | set -e 4 | find . -name '*.go' | grep -v vendor | xargs gofumpt -w -------------------------------------------------------------------------------- /avm_scripts_canary/grept-precommit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | grept apply -a git::https://github.com/Azure/Azure-Verified-Modules-Grept.git//terraform -------------------------------------------------------------------------------- /scripts/build-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Build Test for CodeQL..." 3 | cd ./test 4 | rm -rf vendor 5 | go mod tidy 6 | go mod vendor 7 | go build ./... -------------------------------------------------------------------------------- /avm_scripts_canary/go-fumpt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Fixing source code with Gofumpt..." 3 | set -e 4 | find . -name '*.go' | grep -v vendor | xargs gofumpt -w -------------------------------------------------------------------------------- /scaffold-ci-scripts/check-tflint-plugin-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | set -e 4 | sh scaffold-ci-scripts/sync-tflint-plugin-version.sh 5 | git update-index --refresh -------------------------------------------------------------------------------- /scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sh scripts/cleanup-actions.sh 4 | rm -f .tflint.hcl 5 | rm -f .tflint_example.hcl 6 | rm -rf "tfmod-scaffold" 7 | rm -rf "scripts" -------------------------------------------------------------------------------- /avm_scripts/gofmt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Fixing source code with gofmt..." 2 | files=$(find . -name '*.go' | grep -v vendor); if [ -n "$files" ]; then echo $files | xargs gofmt -s -w; fi -------------------------------------------------------------------------------- /scripts/deps-ensure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | if [ ! -d "./test" ]; then 3 | echo "No test folder, skip deps-ensure" 4 | exit 0 5 | fi 6 | cd ./test 7 | rm -rf vendor 8 | go mod tidy 9 | go mod vendor -------------------------------------------------------------------------------- /avm_scripts/deps-ensure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | if [ ! -d "./tests/upgrade" ]; then 3 | echo "No tests/upgrade folder, skip deps-ensure" 4 | exit 0 5 | fi 6 | cd ./tests/upgrade || exit 7 | rm -rf vendor 8 | go mod tidy -------------------------------------------------------------------------------- /avm_scripts_canary/deps-ensure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | if [ ! -d "./tests/upgrade" ]; then 3 | echo "No tests/upgrade folder, skip deps-ensure" 4 | exit 0 5 | fi 6 | cd ./tests/upgrade || exit 7 | rm -rf vendor 8 | go mod tidy -------------------------------------------------------------------------------- /avm_scripts_canary/mapotf-precommit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | mapotf transform --mptf-dir git::https://github.com/Azure/tfmod-scaffold.git//avm_mapotf/pre_commit --tf-dir . 5 | avmfix -folder . 6 | mapotf clean-backup --tf-dir . -------------------------------------------------------------------------------- /scripts/post-push-starter.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | REMOTE_SCRIPT="https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/$SCRIPT_FOLDER$AVMSCRIPT_VERSION" 3 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$REMOTE_SCRIPT/post-push.sh" | bash -------------------------------------------------------------------------------- /avm_scripts/gosec.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking go code with gosec..." 3 | if [ ! -d "tests/upgrade" ]; then 4 | echo "No upgrade tests directory yet, skip gosec" 5 | exit 0 6 | fi 7 | set -e 8 | cd ./tests/upgrade 9 | gosec -tests ./... -------------------------------------------------------------------------------- /scripts/autofix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | avmfix -folder "$(pwd)" 3 | 4 | examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 5 | for d in $examples; do 6 | echo "===> Autofix in " $d && cd $d && avmfix -folder "$(pwd)" 7 | done 8 | exit 0 9 | -------------------------------------------------------------------------------- /avm_scripts_canary/gosec.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking go code with gosec..." 3 | if [ ! -d "tests/upgrade" ]; then 4 | echo "No upgrade tests directory yet, skip gosec" 5 | exit 0 6 | fi 7 | set -e 8 | cd ./tests/upgrade 9 | gosec -tests ./... -------------------------------------------------------------------------------- /avm_scripts/grept-apply.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking code repository with grept against git::https://github.com/Azure/Azure-Verified-Modules-Grept.git//terraform ..." 3 | grept apply -a git::https://github.com/Azure/Azure-Verified-Modules-Grept.git//terraform -------------------------------------------------------------------------------- /avm_scripts/mapotf-precommit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | MPTF_DIR=${MPTF_DIR:-git::https://github.com/Azure/tfmod-scaffold.git//avm_mapotf} 5 | 6 | mapotf transform --mptf-dir $MPTF_DIR/pre_commit --tf-dir . 7 | avmfix -folder . 8 | mapotf clean-backup --tf-dir . 9 | -------------------------------------------------------------------------------- /avm_scripts_canary/grept-apply.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking code repository with grept against git::https://github.com/Azure/Azure-Verified-Modules-Grept.git//terraform ..." 3 | grept apply -a git::https://github.com/Azure/Azure-Verified-Modules-Grept.git//terraform -------------------------------------------------------------------------------- /scripts/ci-update-test-record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git config --global --add safe.directory '*' 3 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform sh scripts/update-test-record.sh 4 | 5 | cd .git 6 | sudo chmod -R a+rwX . 7 | sudo find . -type d -exec chmod g+s '{}' + -------------------------------------------------------------------------------- /avm_scripts/ci-update-test-record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git config --global --add safe.directory '*' 3 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform sh scripts/update-test-record.sh 4 | 5 | cd .git 6 | sudo chmod -R a+rwX . 7 | sudo find . -type d -exec chmod g+s '{}' + -------------------------------------------------------------------------------- /avm_scripts_canary/ci-update-test-record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git config --global --add safe.directory '*' 3 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform sh scripts/update-test-record.sh 4 | 5 | cd .git 6 | sudo chmod -R a+rwX . 7 | sudo find . -type d -exec chmod g+s '{}' + -------------------------------------------------------------------------------- /avm_scripts_canary/clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Cleaning terraform directories, state files and lock files..." 3 | find -type d -name .terraform -print0 | xargs -0 rm -rf 4 | find -type f -name .terraform.lock.hcl -print0 | xargs -0 rm -rf 5 | find -type f -name 'terraform.tfstate*' -print0 | xargs -0 rm -rf 6 | exit 0 7 | -------------------------------------------------------------------------------- /scripts/run-e2e-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Running E2E Tests..." 3 | set -e 4 | cd ./test/e2e 5 | go mod tidy 6 | go mod vendor 7 | if [ -z "${TEST_TIMEOUT}" ]; then 8 | export TEST_TIMEOUT=720m 9 | fi 10 | echo "==> go test" 11 | echo $TEST_TIMEOUT 12 | terraform version 13 | go test -v -timeout=$TEST_TIMEOUT ./... -------------------------------------------------------------------------------- /workflows/post-push.yaml: -------------------------------------------------------------------------------- 1 | name: Post Push 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - master 7 | tags: 8 | - '*' 9 | 10 | permissions: write-all 11 | 12 | jobs: 13 | post-push: 14 | if: github.actor != 'github-actions[bot]' 15 | uses: Azure/tfmod-scaffold/.github/workflows/post-push.yaml@main -------------------------------------------------------------------------------- /avm_scripts/run-golangci-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking test go code against linters..." 3 | if [ ! -d "tests/upgrade" ]; then 4 | echo "No upgrade tests directory yet, skip golangci-lint" 5 | exit 0 6 | fi 7 | cd ./tests/upgrade 8 | go mod tidy 9 | echo "run golangci-lint ..." 10 | golangci-lint run --timeout 1h ./... -------------------------------------------------------------------------------- /scripts/run-unit-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Running Unit Tests..." 3 | if [ ! -d "test/unit" ]; then 4 | echo "No unit test directory yet, skip test" 5 | exit 0 6 | fi 7 | set -e 8 | cd ./test/unit 9 | go mod tidy 10 | go mod vendor 11 | echo "==> unit test" 12 | go test -v -timeout=60m ./... 13 | 14 | rm -rf ../../TestRecord -------------------------------------------------------------------------------- /avm_scripts_canary/run-golangci-lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking test go code against linters..." 3 | if [ ! -d "tests/upgrade" ]; then 4 | echo "No upgrade tests directory yet, skip golangci-lint" 5 | exit 0 6 | fi 7 | cd ./tests/upgrade 8 | go mod tidy 9 | echo "run golangci-lint ..." 10 | golangci-lint run --timeout 1h ./... -------------------------------------------------------------------------------- /workflows/breaking-change-detect.yaml: -------------------------------------------------------------------------------- 1 | name: 'Comment on PR' 2 | 3 | permissions: 4 | contents: read 5 | pull-requests: read 6 | 7 | on: 8 | workflow_run: 9 | workflows: ["Pre Pull Request Check"] 10 | types: 11 | - completed 12 | 13 | jobs: 14 | comment: 15 | uses: Azure/tfmod-scaffold/.github/workflows/breaking-change-detect.yaml@main -------------------------------------------------------------------------------- /.github/workflows/breaking-change-detect.yaml: -------------------------------------------------------------------------------- 1 | name: 'Comment on PR' 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | comment: 8 | name: 'breaking change detect' 9 | runs-on: ubuntu-latest 10 | if: ${{ github.event.workflow_run.event == 'pull_request' }} 11 | steps: 12 | - name: 'Bypass detect' 13 | run: | 14 | echo "bypass detect" 15 | -------------------------------------------------------------------------------- /workflows/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Describe your changes 2 | 3 | ## Issue number 4 | 5 | #000 6 | 7 | ## Checklist before requesting a review 8 | - [ ] The pr title can be used to describe what this pr did in `CHANGELOG.md` file 9 | - [ ] I have executed pre-commit on my machine 10 | - [ ] I have passed pr-check on my machine 11 | 12 | Thanks for your cooperation! 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/avm-makefile.yaml: -------------------------------------------------------------------------------- 1 | name: AVM makefile 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | 10 | jobs: 11 | makefile: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: checkout 15 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2 16 | - name: makefile 17 | run: | 18 | make -f avmmakefile help 19 | -------------------------------------------------------------------------------- /workflows/pr-check.yaml: -------------------------------------------------------------------------------- 1 | name: Pre Pull Request Check 2 | on: 3 | pull_request: 4 | types: ['opened', 'synchronize'] 5 | paths: 6 | - '.github/**' 7 | - '**.go' 8 | - '**.tf' 9 | - '.github/workflows/**' 10 | - '**.md' 11 | - '**/go.mod' 12 | 13 | permissions: 14 | contents: read 15 | pull-requests: read 16 | 17 | jobs: 18 | prepr-check: 19 | uses: Azure/tfmod-scaffold/.github/workflows/pr-check.yaml@main -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This code of conduct outlines expectations for participation in Microsoft-managed open source communities, as well as steps for reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all. People violating this code of conduct may be banned from the community. 4 | 5 | Please read the full text at [https://opensource.microsoft.com/codeofconduct/](https://opensource.microsoft.com/codeofconduct/) 6 | -------------------------------------------------------------------------------- /scripts/cleanup-actions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -f .github/workflows/acc-test.yaml 4 | rm -f .github/workflows/pr-check.yaml 5 | rm -f .github/workflows/breaking-change-detect.yaml 6 | rm -f .github/workflows/post-push.yaml 7 | rm -f .github/workflows/weekly-e2e.yaml 8 | rm -f .github/ISSUE_TEMPLATE/Bug_Report.yml 9 | rm -f .github/ISSUE_TEMPLATE/Feature_Request.yml 10 | rm -f .github/ISSUE_TEMPLATE/config.yml 11 | rm -f .github/pull_request_template.md 12 | rm -f .github/dependabot.yml -------------------------------------------------------------------------------- /scripts/gofmtcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Check gofmt 3 | echo "==> Checking that code complies with gofmt requirements..." 4 | # This filter should match the search filter in ../GNUMakefile 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | xargs gofmt -l) 6 | if [ -n "${gofmt_files}" ]; then 7 | echo 'gofmt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fmt\` to reformat code." 10 | exit 1 11 | fi 12 | exit 0 -------------------------------------------------------------------------------- /avm_scripts/gofmtcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Check gofmt 3 | echo "==> Checking that code complies with gofmt requirements..." 4 | # This filter should match the search filter in ../GNUMakefile 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | xargs gofmt -l) 6 | if [ -n "${gofmt_files}" ]; then 7 | echo 'gofmt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fmt\` to reformat code." 10 | exit 1 11 | fi 12 | exit 0 -------------------------------------------------------------------------------- /scripts/fumptcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Check gofmt 3 | echo "==> Checking that code complies with gofumpt requirements..." 4 | # This filter should match the search filter in ../GNUMakefile 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | xargs gofumpt -l) 6 | if [ -n "${gofmt_files}" ]; then 7 | echo 'gofumpt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fumpt\` to reformat code." 10 | exit 1 11 | fi 12 | exit 0 -------------------------------------------------------------------------------- /avm_scripts/ci-e2e.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | az login --identity --username $MSI_ID > /dev/null 3 | export ARM_SUBSCRIPTION_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .id') 4 | export ARM_TENANT_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .tenantId') 5 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e MSI_ID -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_USE_MSI=true mcr.microsoft.com/azterraform:latest make e2e-test 6 | sudo chown -R $USER ./ -------------------------------------------------------------------------------- /avm_scripts/terraform-fmt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking terraform codes are formatted..." 3 | error=false 4 | terraform fmt -check -recursive || error=true 5 | if ${error}; then 6 | echo "------------------------------------------------" 7 | echo "" 8 | echo "The preceding files contain terraform codes that are not correctly formatted or contain errors." 9 | echo "" 10 | echo "to easily fix all terraform codes:" 11 | echo "$ make fmt" 12 | echo "" 13 | exit 1 14 | fi 15 | exit 0 -------------------------------------------------------------------------------- /avm_scripts_canary/gofmtcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Check gofmt 3 | echo "==> Checking that code complies with gofmt requirements..." 4 | # This filter should match the search filter in ../GNUMakefile 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | xargs gofmt -l) 6 | if [ -n "${gofmt_files}" ]; then 7 | echo 'gofmt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fmt\` to reformat code." 10 | exit 1 11 | fi 12 | exit 0 -------------------------------------------------------------------------------- /avm_scripts_canary/ci-e2e.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | az login --identity --username $MSI_ID > /dev/null 3 | export ARM_SUBSCRIPTION_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .id') 4 | export ARM_TENANT_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .tenantId') 5 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e MSI_ID -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_USE_MSI=true mcr.microsoft.com/azterraform:latest make e2e-test 6 | sudo chown -R $USER ./ -------------------------------------------------------------------------------- /avm_scripts_canary/terraform-fmt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking terraform codes are formatted..." 3 | error=false 4 | terraform fmt -check -recursive || error=true 5 | if ${error}; then 6 | echo "------------------------------------------------" 7 | echo "" 8 | echo "The preceding files contain terraform codes that are not correctly formatted or contain errors." 9 | echo "" 10 | echo "to easily fix all terraform codes:" 11 | echo "$ make fmt" 12 | echo "" 13 | exit 1 14 | fi 15 | exit 0 -------------------------------------------------------------------------------- /avm_scripts/autofix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | avmfix -folder "$(pwd)" 3 | 4 | examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 5 | for d in $examples; do 6 | echo "===> Autofix in $d" && avmfix -folder "$d" 7 | done 8 | 9 | 10 | if [ ! -d modules ]; then 11 | echo "==> Warning - no modules directory found" 12 | else 13 | modules=$(find ./modules -maxdepth 1 -mindepth 1 -type d) 14 | for d in $modules; do 15 | echo "===> Autofix in $d" && avmfix -folder "$d" 16 | done 17 | fi 18 | exit 0 19 | -------------------------------------------------------------------------------- /avm_scripts/fumptcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Check gofmt 3 | echo "==> Checking that code complies with gofumpt requirements..." 4 | # This filter should match the search filter in ../GNUMakefile 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | grep -v examples | xargs gofumpt -l) 6 | if [ -n "${gofmt_files}" ]; then 7 | echo 'gofumpt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fumpt\` to reformat code." 10 | exit 1 11 | fi 12 | exit 0 -------------------------------------------------------------------------------- /avm_scripts_canary/autofix.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | avmfix -folder "$(pwd)" 3 | 4 | examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 5 | for d in $examples; do 6 | echo "===> Autofix in $d" && avmfix -folder "$d" 7 | done 8 | 9 | 10 | if [ ! -d modules ]; then 11 | echo "==> Warning - no modules directory found" 12 | else 13 | modules=$(find ./modules -maxdepth 1 -mindepth 1 -type d) 14 | for d in $modules; do 15 | echo "===> Autofix in $d" && avmfix -folder "$d" 16 | done 17 | fi 18 | exit 0 19 | -------------------------------------------------------------------------------- /scripts/generate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | echo "--> Generating doc" 5 | rm -f .terraform.lock.hcl 6 | 7 | if [ -f ".terraform-docs.yml" ]; then 8 | terraform-docs -c .terraform-docs.yml --output-file README.md ./ 9 | elif [ -d ".terraform-docs" ]; then 10 | configs=$(find .terraform-docs -maxdepth 1 -mindepth 1 -type f) 11 | for config in $configs; do 12 | terraform-docs -c $config ./ 13 | done 14 | else 15 | terraform-docs markdown table --output-file README.md --output-mode inject ./ 16 | fi 17 | -------------------------------------------------------------------------------- /avm_scripts_canary/fumptcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Check gofmt 3 | echo "==> Checking that code complies with gofumpt requirements..." 4 | # This filter should match the search filter in ../GNUMakefile 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | grep -v examples | xargs gofumpt -l) 6 | if [ -n "${gofmt_files}" ]; then 7 | echo 'gofumpt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fumpt\` to reformat code." 10 | exit 1 11 | fi 12 | exit 0 -------------------------------------------------------------------------------- /avm_scripts/ci-version-upgrade.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | az login --identity --username $MSI_ID > /dev/null 3 | export ARM_SUBSCRIPTION_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .id') 4 | export ARM_TENANT_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .tenantId') 5 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e GITHUB_TOKEN -e MSI_ID -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_USE_MSI=true mcr.microsoft.com/azterraform:latest make version-upgrade-test 6 | sudo chown -R $USER ./ -------------------------------------------------------------------------------- /avm_scripts_canary/ci-version-upgrade.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | az login --identity --username $MSI_ID > /dev/null 3 | export ARM_SUBSCRIPTION_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .id') 4 | export ARM_TENANT_ID=$(az login --identity --username $MSI_ID | jq -r '.[0] | .tenantId') 5 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e GITHUB_TOKEN -e MSI_ID -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_USE_MSI=true mcr.microsoft.com/azterraform:latest make version-upgrade-test 6 | sudo chown -R $USER ./ -------------------------------------------------------------------------------- /avm_scripts_canary/mapotf-precommit-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Ensure git working directory is clean 5 | if [[ -n $(git status --porcelain) ]]; then 6 | echo "Error: Git working directory must be clean before running this check." 7 | exit 1 8 | fi 9 | 10 | make mapotf-precommit 11 | 12 | # Check if any files changed 13 | if [[ -n $(git status --porcelain) ]]; then 14 | echo "Error: Terraform code has not been transformed by mapotf. Please run 'make pre-commit' and commit the changes." 15 | git --no-pager diff 16 | exit 1 17 | fi -------------------------------------------------------------------------------- /version.env: -------------------------------------------------------------------------------- 1 | AVMFIX_VERSION=dee5c402cc8ffb09cd823d3d845912fbd8739880 2 | GOLANG_IMAGE_TAG=1.24.4 3 | GREPT_VERSION=7b87ef19476690e3cfd2d11bd61acf2033d3475a 4 | HCLEDIT_VERSION=0.2.17 5 | HCLMERGE_VERSION=2dff14bd831a6f696d6572f03a5a61a11e4e3d66 6 | PACKER_VERSION=1.11.1 7 | TERRAFORM_DOCS_VERSION=v0.20.0 8 | TERRAFORM_VERSION=1.12.1 9 | TFENV=v3.0.0 10 | TFLINT_VERSION=v0.58.0 11 | PREVIOUS_TAG_VERSION=ebb715659f6b2eea736e47fcc0eb87e9f71866d4 12 | CONFTEST_VERSION=0.61.2 13 | MAPOTF_VERSION=2dd8efb8d1179c2f722669d1a88d836a284ea605 14 | PORCH_VERSION=0.0.10 15 | -------------------------------------------------------------------------------- /avm_scripts/post-push.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | default_branch=$(curl -s "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.default_branch') 5 | git clone https://avmbot:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git workspace 6 | cd workspace 7 | make yor-tag 8 | make pre-commit 9 | make autofix 10 | make pr-check 11 | 12 | # Check if there are changes 13 | if git diff --exit-code > /dev/null; then 14 | echo "No changes to commit" 15 | exit 0 16 | fi 17 | 18 | git commit -am "Auto update" 19 | git push -u origin $default_branch -------------------------------------------------------------------------------- /avm_scripts_canary/grept-precommit-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Ensure git working directory is clean 5 | if [[ -n $(git status --porcelain) ]]; then 6 | echo "git status shows uncommitted changes. Please commit or stash them before running this script." 7 | exit 1 8 | fi 9 | 10 | make grept-precommit 11 | 12 | # Check if any files changed 13 | if [[ -n $(git status --porcelain) ]]; then 14 | echo "Error: Repository has not been synchronized. Please run 'make pre-commit' and commit the changes." 15 | git --no-pager diff 16 | exit 1 17 | fi -------------------------------------------------------------------------------- /avm_scripts_canary/post-push.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | default_branch=$(curl -s "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.default_branch') 5 | git clone https://avmbot:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY.git workspace 6 | cd workspace 7 | make yor-tag 8 | make pre-commit 9 | make autofix 10 | make pr-check 11 | 12 | # Check if there are changes 13 | if git diff --exit-code > /dev/null; then 14 | echo "No changes to commit" 15 | exit 0 16 | fi 17 | 18 | git commit -am "Auto update" 19 | git push -u origin $default_branch -------------------------------------------------------------------------------- /avm_scripts/mapotf-precommit-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Ensure git working directory is clean 5 | if [[ -n $(git status --porcelain) ]]; then 6 | echo "git status shows uncommitted changes. Please commit or stash them before running this script." 7 | exit 1 8 | fi 9 | 10 | make mapotf-precommit 11 | 12 | # Check if any files changed 13 | if [[ -n $(git status --porcelain) ]]; then 14 | echo "Error: Terraform code has not been transformed by mapotf. Please run 'make pre-commit' and commit the changes." 15 | git --no-pager diff 16 | exit 1 17 | fi -------------------------------------------------------------------------------- /scripts/ci-e2e.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | export ARM_OIDC_REQUEST_TOKEN=$ACTIONS_ID_TOKEN_REQUEST_TOKEN 3 | export ARM_OIDC_REQUEST_URL=$ACTIONS_ID_TOKEN_REQUEST_URL 4 | if [ -n "$ACTIONS_ID_TOKEN_REQUEST_URL" ]; then 5 | export ARM_USE_OIDC=true 6 | fi 7 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_OIDC_REQUEST_TOKEN -e ARM_OIDC_REQUEST_URL -e ARM_USE_OIDC -e TF_IN_AUTOMATION -e TF_VAR_enable_telemetry mcr.microsoft.com/azterraform:latest make e2e-test 8 | sudo chown -R $USER ./ -------------------------------------------------------------------------------- /scripts/terraform-fmt.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking terraform codes are formatted..." 3 | error=false 4 | terraform fmt -check -recursive || error=true 5 | if ${error}; then 6 | echo "------------------------------------------------" 7 | echo "" 8 | echo "The preceding files contain terraform codes that are not correctly formatted or contain errors." 9 | echo "You can fix this by running make tools and then tffmt on them." 10 | echo "" 11 | echo "to easily fix all terraform codes:" 12 | echo "$ make tffmt" 13 | echo "" 14 | exit 1 15 | fi 16 | exit 0 -------------------------------------------------------------------------------- /scripts/checkovcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #if [ ! -z "$SKIP_CHECKOV" ]; then 3 | # echo "Skipping Checkov check." 4 | # exit 0 5 | #fi 6 | # 7 | #echo "==> Checking Terraform code with BridgeCrew Checkov" 8 | #if [ ! -z "$CHECKOV_CONFIG" ]; then 9 | # checkov --config-file $CHECKOV_CONFIG 10 | #elif [ -f ".checkov_config.yaml" ]; then 11 | # checkov --config-file .checkov_config.yaml 12 | #else 13 | # checkov --skip-framework dockerfile kubernetes --skip-path test/vendor --skip-check CKV_GHA_3 --quiet -d ./ 14 | #fi 15 | 16 | echo "We've bypassed checkov check for now" 17 | exit 0 -------------------------------------------------------------------------------- /scripts/terrafmt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Fixing test and document terraform blocks code with terrafmt..." 2 | 3 | files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform") 4 | for f in $files; do 5 | terrafmt fmt -f "$f" 6 | retValue=$? 7 | if [ $retValue -ne 0 ] && [ $retValue -ne 2 ]; then 8 | echo "------------------------------------------------" 9 | echo "" 10 | echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors." 11 | echo "" 12 | exit $retValue 13 | fi 14 | done -------------------------------------------------------------------------------- /avm_scripts_canary/checkovcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #if [ ! -z "$SKIP_CHECKOV" ]; then 3 | # echo "Skipping Checkov check." 4 | # exit 0 5 | #fi 6 | # 7 | #echo "==> Checking Terraform code with BridgeCrew Checkov" 8 | #if [ ! -z "$CHECKOV_CONFIG" ]; then 9 | # checkov --config-file $CHECKOV_CONFIG 10 | #elif [ -f ".checkov_config.yaml" ]; then 11 | # checkov --config-file .checkov_config.yaml 12 | #else 13 | # checkov --skip-framework dockerfile kubernetes --skip-path test/vendor --skip-check CKV_GHA_3 --quiet -d ./ 14 | #fi 15 | 16 | echo "We've bypassed checkov check for now" 17 | exit 0 -------------------------------------------------------------------------------- /scripts/ci-version-upgrade.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | export ARM_OIDC_REQUEST_TOKEN=$ACTIONS_ID_TOKEN_REQUEST_TOKEN 3 | export ARM_OIDC_REQUEST_URL=$ACTIONS_ID_TOKEN_REQUEST_URL 4 | if [ -n "$ACTIONS_ID_TOKEN_REQUEST_URL" ]; then 5 | export ARM_USE_OIDC=true 6 | fi 7 | docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src -w /src --network=host -e GITHUB_TOKEN -e ARM_SUBSCRIPTION_ID -e ARM_TENANT_ID -e ARM_CLIENT_ID -e ARM_OIDC_REQUEST_TOKEN -e ARM_OIDC_REQUEST_URL -e ARM_USE_OIDC -e TF_IN_AUTOMATION -e TF_VAR_enable_telemetry mcr.microsoft.com/azterraform:latest make version-upgrade-test 8 | sudo chown -R $USER ./ -------------------------------------------------------------------------------- /avm_scripts/terrafmt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Fixing test and document terraform blocks code with terrafmt..." 2 | 3 | files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md" -e "README-generated.md") 4 | for f in $files; do 5 | terrafmt fmt -f "$f" 6 | retValue=$? 7 | if [ $retValue -ne 0 ]; then 8 | echo "------------------------------------------------" 9 | echo "" 10 | echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors." 11 | echo "" 12 | exit $retValue 13 | fi 14 | done 15 | -------------------------------------------------------------------------------- /avm_scripts_canary/terrafmt.sh: -------------------------------------------------------------------------------- 1 | echo "==> Fixing test and document terraform blocks code with terrafmt..." 2 | 3 | files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md" -e "README-generated.md") 4 | for f in $files; do 5 | terrafmt fmt -f "$f" 6 | retValue=$? 7 | if [ $retValue -ne 0 ]; then 8 | echo "------------------------------------------------" 9 | echo "" 10 | echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors." 11 | echo "" 12 | exit $retValue 13 | fi 14 | done 15 | -------------------------------------------------------------------------------- /avm_scripts/update-test-record.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git config --global --add safe.directory '/src' 4 | 5 | if [ ! -d "TestRecord" ]; then 6 | echo "No TestRecord found, exit" 7 | exit 0 8 | fi 9 | 10 | cd TestRecord 11 | 12 | folders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 13 | for f in $folders; do 14 | d=${f#"./"} 15 | 16 | if [ ! -f ../examples/$d/TestRecord.md ]; then 17 | touch ../examples/$d/TestRecord.md 18 | fi 19 | 20 | cat ../examples/$d/TestRecord.md >> $d/TestRecord.md.tmp 21 | cat $d/TestRecord.md.tmp > ../examples/$d/TestRecord.md 22 | done 23 | 24 | cd .. 25 | git add **/TestRecord.md -------------------------------------------------------------------------------- /avm_scripts/version-upgrade-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Running Module Version Upgrade Tests..." 3 | set -e 4 | if [ -z "$PREVIOUS_MAJOR_VERSION" ]; then 5 | export PREVIOUS_MAJOR_VERSION=$(ls | grep CHANGELOG | cut -d'-' -f 2 | cut -f 1 -d '.' | grep v | sort -V -r | head -n 1) 6 | fi 7 | if [ ! -d "tests/upgrade" ]; then 8 | echo "No version-upgrade test directory yet, skip test" 9 | exit 0 10 | fi 11 | cd ./tests/upgrade 12 | go mod tidy 13 | go mod vendor 14 | if [ -z "$TEST_TIMEOUT" ]; then 15 | export TEST_TIMEOUT=720m 16 | fi 17 | echo "==> Executing go test" 18 | go test -v -timeout=$TEST_TIMEOUT ./... -------------------------------------------------------------------------------- /scripts/update-test-record.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git config --global --add safe.directory '/src' 4 | 5 | if [ ! -d "TestRecord" ]; then 6 | echo "No TestRecord found, exit" 7 | exit 0 8 | fi 9 | 10 | cd TestRecord 11 | 12 | folders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 13 | for f in $folders; do 14 | d=${f#"./"} 15 | 16 | if [ ! -f ../examples/$d/TestRecord.md ]; then 17 | touch ../examples/$d/TestRecord.md 18 | fi 19 | 20 | cat ../examples/$d/TestRecord.md >> $d/TestRecord.md.tmp 21 | cat $d/TestRecord.md.tmp > ../examples/$d/TestRecord.md 22 | done 23 | 24 | cd .. 25 | git add **/TestRecord.md -------------------------------------------------------------------------------- /scripts/deps-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "Skip deps check for now, we need a better solution in case we've upgrade go version." 3 | exit 0 4 | #if [ ! -d "./test" ]; then 5 | # echo "No test folder, skip deps-ensure" 6 | # exit 0 7 | #fi 8 | #cd ./test 9 | #echo "==> Checking source code with go mod tidy..." 10 | #cp go.mod go_mod 11 | #go mod tidy 12 | #echo "==> Checking source code with go mod vendor..." 13 | #go mod vendor 14 | #diff -q go.mod go_mod || \ 15 | # (echo; echo "Unexpected difference in go.mod. Run 'make depsensure' to update the generated document and commit."; rm go_mod go_sum;exit 1) 16 | # 17 | #rm go_mod -------------------------------------------------------------------------------- /avm_scripts_canary/update-test-record.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git config --global --add safe.directory '/src' 4 | 5 | if [ ! -d "TestRecord" ]; then 6 | echo "No TestRecord found, exit" 7 | exit 0 8 | fi 9 | 10 | cd TestRecord 11 | 12 | folders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 13 | for f in $folders; do 14 | d=${f#"./"} 15 | 16 | if [ ! -f ../examples/$d/TestRecord.md ]; then 17 | touch ../examples/$d/TestRecord.md 18 | fi 19 | 20 | cat ../examples/$d/TestRecord.md >> $d/TestRecord.md.tmp 21 | cat $d/TestRecord.md.tmp > ../examples/$d/TestRecord.md 22 | done 23 | 24 | cd .. 25 | git add **/TestRecord.md -------------------------------------------------------------------------------- /avm_scripts_canary/version-upgrade-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Running Module Version Upgrade Tests..." 3 | set -e 4 | if [ -z "$PREVIOUS_MAJOR_VERSION" ]; then 5 | export PREVIOUS_MAJOR_VERSION=$(ls | grep CHANGELOG | cut -d'-' -f 2 | cut -f 1 -d '.' | grep v | sort -V -r | head -n 1) 6 | fi 7 | if [ ! -d "tests/upgrade" ]; then 8 | echo "No version-upgrade test directory yet, skip test" 9 | exit 0 10 | fi 11 | cd ./tests/upgrade 12 | go mod tidy 13 | go mod vendor 14 | if [ -z "$TEST_TIMEOUT" ]; then 15 | export TEST_TIMEOUT=720m 16 | fi 17 | echo "==> Executing go test" 18 | go test -v -timeout=$TEST_TIMEOUT ./... -------------------------------------------------------------------------------- /scripts/version-upgrade-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | terraform version 3 | echo "==> Running Module Version Upgrade Tests..." 4 | set -e 5 | if [ -z "$PREVIOUS_MAJOR_VERSION" ]; then 6 | export PREVIOUS_MAJOR_VERSION=$(ls | grep CHANGELOG | cut -d'-' -f 2 | cut -f 1 -d '.' | grep v | sort -V -r | head -n 1) 7 | fi 8 | if [ ! -d "test/upgrade" ]; then 9 | echo "No version-upgrade test directory yet, skip test" 10 | exit 0 11 | fi 12 | cd ./test/upgrade 13 | go mod tidy 14 | go mod vendor 15 | if [ -z "$TEST_TIMEOUT" ]; then 16 | export TEST_TIMEOUT=720m 17 | fi 18 | echo "==> Executing go test" 19 | go test -v -timeout=$TEST_TIMEOUT ./... -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export BRANCH=${1:-main} 3 | export GITHUB_REPO="https://github.com/Azure/tfmod-scaffold.git" 4 | if [ -d "tfmod-scaffold" ]; then 5 | echo "Removing existing scaffold" 6 | rm -rf "tfmod-scaffold" 7 | rm -rf "scripts" 8 | fi 9 | echo "Cloning tfmod-scaffold" 10 | git clone -q -c advice.detachedHead=false --depth=1 -b $BRANCH $GITHUB_REPO 11 | ln -s tfmod-scaffold/scripts scripts 12 | cp -r tfmod-scaffold/.tflint.hcl .tflint.hcl 13 | cp -r tfmod-scaffold/.tflint_example.hcl .tflint_example.hcl 14 | 15 | rm -rf .devcontainer 16 | mkdir -p .devcontainer 17 | cp tfmod-scaffold/.devcontainer/devcontainer.json .devcontainer/devcontainer.json 18 | -------------------------------------------------------------------------------- /dockerbuild.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-docker} 6 | 7 | if [ ! "$(command -v "$CONTAINER_RUNTIME")" ]; then 8 | echo "Error: $CONTAINER_RUNTIME is not installed. Please install $CONTAINER_RUNTIME first." 9 | exit 1 10 | fi 11 | 12 | cat Dockerfile.build Dockerfile.azterraform > Dockerfile_azterraform 13 | cat Dockerfile.build Dockerfile.avm > Dockerfile_avm 14 | 15 | $CONTAINER_RUNTIME build $(sh build-arg-helper.sh version.env) --build-arg TARGETARCH=amd64 -f Dockerfile_azterraform -t localrunner . 16 | $CONTAINER_RUNTIME build $(sh build-arg-helper.sh version.env) --build-arg TARGETARCH=amd64 -f Dockerfile_avm -t localrunner_avm . 17 | -------------------------------------------------------------------------------- /avm_mapotf/pre_commit/required_provider_versions.mptf.hcl: -------------------------------------------------------------------------------- 1 | data "terraform" this { 2 | 3 | } 4 | 5 | locals { 6 | azapi_provider_version_valid = try(!semvercheck(data.terraform.this.required_providers.azapi.version, "2.3.999"), false) && try(semvercheck(data.terraform.this.required_providers.azapi.version, "2.999.999"), false) 7 | } 8 | 9 | transform "update_in_place" azapi_provider_version { 10 | for_each = local.avm_headers_for_azapi_enabled && !local.azapi_provider_version_valid ? toset([1]) : toset([]) 11 | target_block_address = "terraform" 12 | asraw { 13 | required_providers { 14 | azapi = { 15 | source = "Azure/azapi" 16 | version = "~> 2.4" 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /scripts/gencheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "==> Generating..." 4 | cp README.md README-generated.md 5 | 6 | if [ -f ".terraform-docs.yml" ]; then 7 | terraform-docs -c .terraform-docs.yml --output-file README.md ./ 8 | elif [ -d ".terraform-docs" ]; then 9 | configs=$(find .terraform-docs -maxdepth 1 -mindepth 1 -type f) 10 | for config in $configs; do 11 | terraform-docs -c $config ./ 12 | done 13 | else 14 | terraform-docs markdown table --output-file README.md --output-mode inject ./ 15 | fi 16 | 17 | echo "==> Comparing generated code to committed code..." 18 | diff -q README.md README-generated.md || \ 19 | (echo; echo "Unexpected difference in generated document. Run 'make pre-commit' to update the generated document and commit."; exit 1) -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/azterraform:latest", 3 | 4 | "runArgs": [ 5 | "--cap-add=SYS_PTRACE", 6 | "--security-opt", 7 | "seccomp=unconfined", 8 | "--init", 9 | "--network=host" 10 | ], 11 | 12 | "mounts": [ 13 | "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", 14 | "source=${localEnv:HOME}${localEnv:USERPROFILE},target=/host-home-folder,type=bind,consistency=cached" 15 | ], 16 | "customizations": { 17 | "vscode": { 18 | "settings": { 19 | "go.toolsManagement.checkForUpdates": "local", 20 | "go.useLanguageServer": true, 21 | "go.goroot": "/usr/local/go" 22 | }, 23 | "extensions": [ 24 | "hashicorp.terraform", 25 | "golang.Go" 26 | ] 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scaffold-ci-scripts/sync-tflint-plugin-version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | export $(grep -v '^#' version.env | xargs) 4 | 5 | cat .tflint.hcl | \ 6 | hcledit attribute set plugin.azurerm.version \"$TFLINT_AZURERM_VERSION\" | \ 7 | hcledit attribute set plugin.basic-ext.version \"$TFLINT_BASIC_EXT_VERSION\" | \ 8 | hcledit attribute set plugin.azurerm-ext.version \"$TFLINT_AZURERM_EXT_VERSION\" \ 9 | > .tflint.hcl.tmp && mv .tflint.hcl.tmp .tflint.hcl 10 | 11 | cat .tflint_example.hcl | \ 12 | hcledit attribute set plugin.azurerm.version \"$TFLINT_AZURERM_VERSION\" | \ 13 | hcledit attribute set plugin.basic-ext.version \"$TFLINT_BASIC_EXT_VERSION\" | \ 14 | hcledit attribute set plugin.azurerm-ext.version \"$TFLINT_AZURERM_EXT_VERSION\" \ 15 | > .tflint_example.hcl.tmp && mv .tflint_example.hcl.tmp .tflint_example.hcl -------------------------------------------------------------------------------- /scripts/checkovplancheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #if [ ! -z "$SKIP_CHECKOV" ]; then 3 | # echo "Skipping Checkov check." 4 | # exit 0 5 | #fi 6 | # 7 | #echo "==> Checking examples terraform plan by checkov..." 8 | #examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 9 | #for d in $examples; do 10 | # echo "===> Check tfplan in " $d 11 | # (cd $d && rm -f .terraform.lock.hcl && terraform init -upgrade && terraform plan --out tfplan.binary && terraform show -json tfplan.binary > tfplan.json && checkov --quiet -f tfplan.json) || error=true 12 | # if ${error}; then 13 | # echo "------------------------------------------------" 14 | # echo "" 15 | # echo "Checkov found issues in " $d 16 | # echo "" 17 | # exit 1 18 | # fi 19 | #done 20 | echo "We've bypassed checkov check for now" 21 | exit 0 -------------------------------------------------------------------------------- /.github/workflows/weekly-codeql.yaml: -------------------------------------------------------------------------------- 1 | name: Weekly CodeQL Check 2 | on: 3 | workflow_call: 4 | 5 | jobs: 6 | codeql: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: checkout 10 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3.6.0 11 | - name: Set up Go 12 | uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 #3.5.0 13 | with: 14 | go-version: 1.22 15 | - name: Initialize CodeQL 16 | uses: github/codeql-action/init@1b1aada464948af03b950897e5eb522f92603cc2 #v3.24.9 17 | with: 18 | languages: go 19 | - name: build-test 20 | run: | 21 | sudo make build-test 22 | - name: Perform CodeQL Analysis 23 | uses: github/codeql-action/analyze@1b1aada464948af03b950897e5eb522f92603cc2 #v3.24.9 24 | -------------------------------------------------------------------------------- /avm_scripts_canary/checkovplancheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #if [ ! -z "$SKIP_CHECKOV" ]; then 3 | # echo "Skipping Checkov check." 4 | # exit 0 5 | #fi 6 | # 7 | #echo "==> Checking examples terraform plan by checkov..." 8 | #examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 9 | #for d in $examples; do 10 | # echo "===> Check tfplan in " $d 11 | # (cd $d && rm -f .terraform.lock.hcl && terraform init -upgrade && terraform plan --out tfplan.binary && terraform show -json tfplan.binary > tfplan.json && checkov --quiet -f tfplan.json) || error=true 12 | # if ${error}; then 13 | # echo "------------------------------------------------" 14 | # echo "" 15 | # echo "Checkov found issues in " $d 16 | # echo "" 17 | # exit 1 18 | # fi 19 | #done 20 | echo "We've bypassed checkov check for now" 21 | exit 0 -------------------------------------------------------------------------------- /scripts/terrafmt-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking documentation terraform blocks are formatted..." 3 | files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform") 4 | error=false 5 | for f in $files; do 6 | terrafmt diff -c -q "$f" 7 | retValue=$? 8 | if [ $retValue -ne 0 ] && [ $retValue -ne 2 ]; then 9 | error=true 10 | fi 11 | done 12 | if ${error}; then 13 | echo "------------------------------------------------" 14 | echo "" 15 | echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors." 16 | echo "You can fix this by running make tools and then terrafmt on them." 17 | echo "" 18 | echo "to easily fix all terraform blocks:" 19 | echo "$ make terrafmt" 20 | echo "" 21 | exit 1 22 | fi 23 | exit 0 -------------------------------------------------------------------------------- /avm_scripts/terrafmt-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking documentation terraform blocks are formatted..." 3 | files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md") 4 | error=false 5 | for f in $files; do 6 | terrafmt diff -c -q "$f" 7 | retValue=$? 8 | if [ $retValue -ne 0 ] && [ $retValue -ne 2 ]; then 9 | error=true 10 | fi 11 | done 12 | if ${error}; then 13 | echo "------------------------------------------------" 14 | echo "" 15 | echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors." 16 | echo "You can fix this by running make tools and then terrafmt on them." 17 | echo "" 18 | echo "to easily fix all terraform blocks:" 19 | echo "$ make terrafmt" 20 | echo "" 21 | exit 1 22 | fi 23 | exit 0 -------------------------------------------------------------------------------- /avm_scripts_canary/terrafmt-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Checking documentation terraform blocks are formatted..." 3 | files=$(find . -type f -name "*.md" -o -name "*.go" | grep -v -e ".github" -e "-terraform" -e "vendor" -e ".terraform" -e "README.md") 4 | error=false 5 | for f in $files; do 6 | terrafmt diff -c -q "$f" 7 | retValue=$? 8 | if [ $retValue -ne 0 ] && [ $retValue -ne 2 ]; then 9 | error=true 10 | fi 11 | done 12 | if ${error}; then 13 | echo "------------------------------------------------" 14 | echo "" 15 | echo "The preceding files contain terraform blocks that are not correctly formatted or contain errors." 16 | echo "You can fix this by running make tools and then terrafmt on them." 17 | echo "" 18 | echo "to easily fix all terraform blocks:" 19 | echo "$ make terrafmt" 20 | echo "" 21 | exit 1 22 | fi 23 | exit 0 -------------------------------------------------------------------------------- /avm_scripts_canary/test-example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export TF_VAR_msi_id=$MSI_ID 4 | 5 | if [ -z "$AVM_EXAMPLE" ]; then 6 | echo "AVM_EXAMPLE is not set" 7 | exit 1 8 | fi 9 | 10 | if [ -z "$AVM_MOD_PATH" ]; then 11 | export AVM_MOD_PATH="$(pwd)" 12 | fi 13 | 14 | if [ -z "${TEST_TIMEOUT}" ]; then 15 | export TEST_TIMEOUT=720m 16 | fi 17 | 18 | # If examples directory does not exist then quit 19 | if [ ! -d "$AVM_MOD_PATH/examples/$AVM_EXAMPLE" ]; then 20 | echo "No $AVM_EXAMPLE directory found in $AVM_MOD_PATH/examples" 21 | exit 0 22 | fi 23 | 24 | echo "==> Running e2e tests for $example" 25 | cd /tmp 26 | testFolder="avmtester$AVM_EXAMPLE$RANDOM" 27 | git clone https://github.com/Azure/avmtester.git $testFolder && cd $testFolder 28 | go mod tidy 29 | echo "==> go test" 30 | echo "$TEST_TIMEOUT" 31 | terraform version 32 | go test -v -timeout="$TEST_TIMEOUT" -run TestExample -- 33 | cd /tmp 34 | rm -rf "$testFolder" 35 | -------------------------------------------------------------------------------- /avm_scripts/docs-gen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | generate_docs () { 5 | local dir=$1 6 | echo "===> Generating documentation in $dir" 7 | rm -f "$dir/.terraform.lock.hcl" 8 | terraform-docs -c ".terraform-docs.yml" "$dir" 9 | } 10 | 11 | echo "==> Generating root module documentation..." 12 | generate_docs . 13 | 14 | echo "==> Generating examples documentation..." 15 | if [ ! -d examples ]; then 16 | echo "==> Error - no examples directory found" 17 | exit 1 18 | fi 19 | cd examples 20 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 21 | for d in $subfolders; do 22 | generate_docs $d 23 | done 24 | cd .. 25 | 26 | echo "==> Generating sub modules documentation..." 27 | if [ ! -d modules ]; then 28 | echo "==> Warning - no modules directory found" 29 | else 30 | cd modules 31 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 32 | for d in $subfolders; do 33 | generate_docs $d 34 | done 35 | cd .. 36 | fi -------------------------------------------------------------------------------- /avm_scripts/run-tftest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | echo "!!! WARNING !!!" 5 | echo "Due to limitations in az cli's implementation on Windows vs Linux," 6 | echo "Terraform tests that require Azure authorization will not work." 7 | echo "Please use Windows Subsystem for Linux (WSL) to run tests." 8 | echo "!!! WARNING !!!" 9 | echo 10 | 11 | run_tests () { 12 | local dir=$1 13 | echo "==> Running tests in $dir" 14 | pushd $dir 15 | if [ ! -d tests ]; then 16 | echo "===> No tests directory found in $dir" 17 | popd 18 | return 0 19 | fi 20 | terraform init 21 | terraform test 22 | popd 23 | } 24 | 25 | run_tests . 26 | 27 | echo "==> Running tests in submodules..." 28 | if [ ! -d modules ]; then 29 | echo "==> No modules directory found - exiting" 30 | exit 0 31 | fi 32 | cd modules 33 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 34 | for d in $subfolders; do 35 | run_tests $d 36 | done 37 | cd .. 38 | -------------------------------------------------------------------------------- /avm_scripts_canary/docs-gen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | generate_docs () { 5 | local dir=$1 6 | echo "===> Generating documentation in $dir" 7 | rm -f "$dir/.terraform.lock.hcl" 8 | terraform-docs -c ".terraform-docs.yml" "$dir" 9 | } 10 | 11 | echo "==> Generating root module documentation..." 12 | generate_docs . 13 | 14 | echo "==> Generating examples documentation..." 15 | if [ ! -d examples ]; then 16 | echo "==> Error - no examples directory found" 17 | exit 1 18 | fi 19 | cd examples 20 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 21 | for d in $subfolders; do 22 | generate_docs $d 23 | done 24 | cd .. 25 | 26 | echo "==> Generating sub modules documentation..." 27 | if [ ! -d modules ]; then 28 | echo "==> Warning - no modules directory found" 29 | else 30 | cd modules 31 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 32 | for d in $subfolders; do 33 | generate_docs $d 34 | done 35 | cd .. 36 | fi -------------------------------------------------------------------------------- /scripts/init-actions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p .github/workflows 4 | cp tfmod-scaffold/workflows/acc-test.yaml .github/workflows/acc-test.yaml 5 | cp tfmod-scaffold/workflows/pr-check.yaml .github/workflows/pr-check.yaml 6 | cp tfmod-scaffold/workflows/breaking-change-detect.yaml .github/workflows/breaking-change-detect.yaml 7 | cp tfmod-scaffold/workflows/post-push.yaml .github/workflows/post-push.yaml 8 | cp tfmod-scaffold/workflows/weekly-e2e.yaml .github/workflows/weekly-e2e.yaml 9 | mkdir -p .github/ISSUE_TEMPLATE 10 | cp tfmod-scaffold/workflows/ISSUE_TEMPLATE/Bug_Report.yml .github/ISSUE_TEMPLATE/Bug_Report.yml 11 | cp tfmod-scaffold/workflows/ISSUE_TEMPLATE/Feature_Request.yml .github/ISSUE_TEMPLATE/Feature_Request.yml 12 | cp tfmod-scaffold/workflows/ISSUE_TEMPLATE/config.yml .github/ISSUE_TEMPLATE/config.yml 13 | 14 | cp tfmod-scaffold/workflows/pull_request_template.md .github/pull_request_template.md 15 | cp tfmod-scaffold/workflows/dependabot.yml .github/dependabot.yml -------------------------------------------------------------------------------- /.github/workflows/pr-check.yaml: -------------------------------------------------------------------------------- 1 | name: Pre Pull Request Check 2 | on: 3 | workflow_call: 4 | 5 | jobs: 6 | prepr-check: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: checkout 10 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3.6.0 11 | - name: pr-check 12 | run: | 13 | docker run --rm -u 0 -v $(pwd):/src -w /src -e SKIP_CHECKOV -e GITHUB_TOKEN mcr.microsoft.com/azterraform:latest make pr-check 14 | - name: Set up Go 15 | uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 #3.5.0 16 | with: 17 | go-version: 1.21.3 18 | - name: Initialize CodeQL 19 | uses: github/codeql-action/init@1b1aada464948af03b950897e5eb522f92603cc2 #v3.24.9 20 | with: 21 | languages: go 22 | - name: build-test 23 | run: | 24 | sudo make build-test 25 | - name: Perform CodeQL Analysis 26 | uses: github/codeql-action/analyze@1b1aada464948af03b950897e5eb522f92603cc2 #v3.24.9 27 | -------------------------------------------------------------------------------- /workflows/weekly-e2e.yaml: -------------------------------------------------------------------------------- 1 | name: Weekly E2E Test Check 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '0 0 * * 0' 6 | 7 | permissions: 8 | contents: write 9 | 10 | jobs: 11 | full-e2e-check: 12 | runs-on: [self-hosted, 1ES.Pool=] 13 | environment: 14 | name: crontests 15 | steps: 16 | - name: checkout 17 | uses: actions/checkout@v3 18 | - name: init 19 | run: | 20 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make generate 21 | - name: e2e test 22 | continue-on-error: true 23 | run: | 24 | sh scripts/ci-e2e.sh 25 | - name: Update 26 | run: | 27 | sh scripts/ci-update-test-record.sh 28 | - name: Commit & Push changes 29 | uses: actions-js/push@master 30 | with: 31 | github_token: ${{ secrets.GITHUB_TOKEN }} 32 | message: 'Update TestVersionSnapshot' 33 | branch: ${{ github.event.repository.default_branch }} -------------------------------------------------------------------------------- /scripts/terraform-validate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Validating module terraform codes..." 3 | error=false 4 | (terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 5 | if ${error}; then 6 | echo "------------------------------------------------" 7 | echo "" 8 | echo "Some Terraform codes contain errors." 9 | echo "$(terraform validate -json)" 10 | echo "" 11 | exit 1 12 | fi 13 | echo "==> Checking examples terraform codes are validate..." 14 | examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 15 | for d in $examples; do 16 | (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 17 | if ${error}; then 18 | echo "------------------------------------------------" 19 | echo "" 20 | echo "Some Terraform codes contain errors." 21 | echo "$(cd $d && terraform validate -json)" 22 | echo "" 23 | exit 1 24 | fi 25 | done 26 | exit 0 27 | -------------------------------------------------------------------------------- /workflows/acc-test.yaml: -------------------------------------------------------------------------------- 1 | name: E2E Test 2 | on: 3 | pull_request: 4 | types: [ 'opened', 'synchronize' ] 5 | paths: 6 | - '.github/**' 7 | - '**.go' 8 | - '**.tf' 9 | - '.github/workflows/**' 10 | - '**.md' 11 | - '**/go.mod' 12 | 13 | permissions: 14 | contents: write 15 | pull-requests: read 16 | 17 | jobs: 18 | acc-tests: 19 | runs-on: [self-hosted, 1ES.Pool=] 20 | environment: 21 | name: acctests 22 | steps: 23 | - uses: actions/checkout@v3 24 | - name: init 25 | run: | 26 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make generate 27 | - name: e2e test 28 | run: | 29 | sh scripts/ci-e2e.sh 30 | - name: upload test version snapshots 31 | uses: actions/upload-artifact@v3 32 | with: 33 | name: TestRecord-${{ github.event.number }} 34 | retention-days: 60 35 | path: | 36 | examples/**/TestRecord.md.tmp 37 | - name: version-upgrade test 38 | env: 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | run: | 41 | sh scripts/ci-version-upgrade.sh 42 | -------------------------------------------------------------------------------- /.github/workflows/tfvm_e2e.yaml: -------------------------------------------------------------------------------- 1 | name: E2E Test 2 | on: 3 | workflow_call: 4 | 5 | jobs: 6 | acc-tests: 7 | runs-on: ubuntu-latest 8 | environment: 9 | name: test 10 | env: 11 | TF_IN_AUTOMATION: 1 12 | TF_VAR_enable_telemetry: false 13 | REMOTE_SCRIPT: "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/scripts" 14 | steps: 15 | - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3.6.0 16 | - name: e2e test 17 | env: 18 | ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} 19 | ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} 20 | ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} 21 | run: | 22 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$REMOTE_SCRIPT/ci-e2e.sh" | bash 23 | - name: version-upgrade test 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} 27 | ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} 28 | ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} 29 | run: | 30 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$REMOTE_SCRIPT/ci-version-upgrade.sh" | bash -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /avm_scripts/test-example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export TF_VAR_msi_id=$MSI_ID 4 | 5 | # if $AVM_MOD_PATH and $AVM_EXAMPLE are not set, exit 6 | if [ -z "$AVM_MOD_PATH" ] || [ -z "$AVM_EXAMPLE" ]; then 7 | echo "AVM_MOD_PATH and AVM_EXAMPLE must be set" 8 | exit 1 9 | fi 10 | 11 | # change dir into $AVM_MOD_PATH/examples/$AVM_EXAMPLE 12 | # then run pre.sh if it exists 13 | cd "$AVM_MOD_PATH/examples/$AVM_EXAMPLE" 14 | if [ -f pre.sh ]; then 15 | echo "==> Running pre.sh" 16 | chmod +x pre.sh 17 | ./pre.sh 18 | fi 19 | 20 | cd /tmp 21 | testFolder="avmtester$AVM_EXAMPLE$RANDOM" 22 | 23 | git clone https://github.com/Azure/avmtester.git $testFolder && cd $testFolder 24 | go mod tidy 25 | if [ -z "${TEST_TIMEOUT}" ]; then 26 | export TEST_TIMEOUT=720m 27 | fi 28 | echo "==> go test" 29 | echo $TEST_TIMEOUT 30 | terraform version 31 | test_failed=false 32 | go test -v -timeout=$TEST_TIMEOUT -run TestExample || test_failed=true 33 | 34 | # change dir back into the example and run post.sh if it exists 35 | cd "$AVM_MOD_PATH/examples/$AVM_EXAMPLE" 36 | if [ -f post.sh ]; then 37 | echo "==> Running post.sh" 38 | chmod +x ./post.sh 39 | ./post.sh 40 | fi 41 | 42 | if [ "$test_failed" = true ]; then 43 | echo "==> Test failed" 44 | exit 1 45 | fi -------------------------------------------------------------------------------- /avm_scripts/docs-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | check_docs () { 4 | local dir=$1 5 | echo "===> Generating documentation in $dir" 6 | cp "$dir/README.md" "$dir/README-generated.md" 7 | rm -f "$dir/.terraform.lock.hcl" 8 | terraform-docs -c ".terraform-docs.yml" "$dir" 9 | echo "===> Comparing documentation in $dir" 10 | if [ ! -z "$(diff -q "$dir/README.md" "$dir/README-generated.md")" ]; then 11 | echo "==> $dir/README.md is out of date. Run 'make pre-commit' to update the generated document and commit." 12 | mv -f "$dir/README-generated.md" "$dir/README.md" 13 | exit 1 14 | fi 15 | rm -f "$dir/README-generated.md" 16 | } 17 | 18 | echo "==> Checking root module documentation..." 19 | check_docs . 20 | 21 | echo "==> Checking examples documentation..." 22 | if [ ! -d examples ]; then 23 | echo "==> Error - no examples directory found" 24 | exit 1 25 | fi 26 | cd examples 27 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 28 | for d in $subfolders; do 29 | check_docs $d 30 | done 31 | cd .. 32 | 33 | echo "==> Checking sub modules documentation..." 34 | if [ ! -d modules ]; then 35 | echo "==> Warning - no modules directory found" 36 | else 37 | cd modules 38 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 39 | for d in $subfolders; do 40 | check_docs $d 41 | done 42 | cd .. 43 | fi -------------------------------------------------------------------------------- /avm_scripts_canary/docs-check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | check_docs () { 4 | local dir=$1 5 | echo "===> Generating documentation in $dir" 6 | cp "$dir/README.md" "$dir/README-generated.md" 7 | rm -f "$dir/.terraform.lock.hcl" 8 | terraform-docs -c ".terraform-docs.yml" "$dir" 9 | echo "===> Comparing documentation in $dir" 10 | if [ ! -z "$(diff -q "$dir/README.md" "$dir/README-generated.md")" ]; then 11 | echo "==> $dir/README.md is out of date. Run 'make pre-commit' to update the generated document and commit." 12 | mv -f "$dir/README-generated.md" "$dir/README.md" 13 | exit 1 14 | fi 15 | rm -f "$dir/README-generated.md" 16 | } 17 | 18 | echo "==> Checking root module documentation..." 19 | check_docs . 20 | 21 | echo "==> Checking examples documentation..." 22 | if [ ! -d examples ]; then 23 | echo "==> Error - no examples directory found" 24 | exit 1 25 | fi 26 | cd examples 27 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 28 | for d in $subfolders; do 29 | check_docs $d 30 | done 31 | cd .. 32 | 33 | echo "==> Checking sub modules documentation..." 34 | if [ ! -d modules ]; then 35 | echo "==> Warning - no modules directory found" 36 | else 37 | cd modules 38 | subfolders=$(find ./ -maxdepth 1 -mindepth 1 -type d) 39 | for d in $subfolders; do 40 | check_docs $d 41 | done 42 | cd .. 43 | fi -------------------------------------------------------------------------------- /test-avm-module.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Script to test an AVM module 5 | # Usage: bash test-avm.sh REPO_URL FOLDER_NAME [DOCKER_IMAGE] 6 | # Example: bash test-avm.sh https://github.com/Azure/terraform-azurerm-avm-res-keyvault-vault.git terraform-azurerm-avm-res-keyvault-vault localrunner_avm 7 | # If DOCKER_IMAGE is not provided, it defaults to localrunner_avm 8 | 9 | # Check if required arguments are provided 10 | if [ $# -lt 2 ]; then 11 | echo "Usage: $0 REPO_URL FOLDER_NAME [DOCKER_IMAGE]" 12 | exit 1 13 | fi 14 | 15 | REPO_URL="$1" 16 | FOLDER_NAME="$2" 17 | DOCKER_IMAGE="${3:-localrunner_avm}" # Use third parameter if provided, otherwise default to localrunner_avm 18 | TEMP_DIR="/tmp/${FOLDER_NAME}" 19 | 20 | echo "===== Testing AVM module: $FOLDER_NAME =====" 21 | echo "Using Docker image: $DOCKER_IMAGE" 22 | 23 | # Remove existing directory if it exists 24 | if [ -d "$TEMP_DIR" ]; then 25 | echo "Removing existing directory: $TEMP_DIR" 26 | rm -rf "$TEMP_DIR" 27 | fi 28 | 29 | # Clone repository 30 | echo "Cloning $REPO_URL to $TEMP_DIR" 31 | git clone "$REPO_URL" "$TEMP_DIR" || { echo "Failed to clone $REPO_URL"; exit 1; } 32 | 33 | # Run pre-commit check 34 | echo "Running pre-commit check" 35 | docker run --rm -v "$(pwd):/scaffold" -e LOCAL_SCRIPT="/scaffold/avm_scripts" -e MPTF_DIR="/scaffold/avm_mapotf" -v "$TEMP_DIR:/src" -w /src "$DOCKER_IMAGE" bash -c 'make pre-commit && git add -A && git commit -am "test" && make pr-check' || { echo "pre-commit failed"; exit 1; } 36 | -------------------------------------------------------------------------------- /avm_scripts/prepare-credential.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | declare -A secrets 5 | eval "$(echo $SECRETS_CONTEXT | jq -r 'to_entries[] | @sh "secrets[\(.key|tostring)]=\(.value|tostring)"')" 6 | 7 | declare -A variables 8 | eval "$(echo $VARS_CONTEXT | jq -r 'to_entries[] | @sh "variables[\(.key|tostring)]=\(.value|tostring)"')" 9 | 10 | for key in "${!secrets[@]}"; do 11 | if [[ $key = \TF_VAR_* ]]; then 12 | lowerKey=$(echo "$key" | tr '[:upper:]' '[:lower:]') 13 | finalKey=${lowerKey/tf_var_/TF_VAR_} 14 | export "$finalKey"="${secrets[$key]}" 15 | fi 16 | done 17 | 18 | for key in "${!variables[@]}"; do 19 | if [[ $key = \TF_VAR_* ]]; then 20 | lowerKey=$(echo "$key" | tr '[:upper:]' '[:lower:]') 21 | finalKey=${lowerKey/tf_var_/TF_VAR_} 22 | export "$finalKey"="${variables[$key]}" 23 | fi 24 | done 25 | 26 | echo -e "Custom environment variables:\n$(env | grep TF_VAR_ | grep -v ' "TF_VAR_')" 27 | 28 | # Set up the Azure Provider Environment Variables 29 | tenantId=$ARM_TENANT_ID_OVERRIDE 30 | if [ -z "$tenantId" ]; then 31 | tenantId=$ARM_TENANT_ID 32 | fi 33 | echo "tenantId: $tenantId" 34 | 35 | subscriptionId=$ARM_SUBSCRIPTION_ID_OVERRIDE 36 | if [ -z "$subscriptionId" ]; then 37 | subscriptionId=$ARM_SUBSCRIPTION_ID 38 | fi 39 | 40 | clientId=$ARM_CLIENT_ID_OVERRIDE 41 | if [ -z "$clientId" ]; then 42 | clientId=$ARM_CLIENT_ID 43 | fi 44 | 45 | export ARM_TENANT_ID=$tenantId 46 | export ARM_SUBSCRIPTION_ID=$subscriptionId 47 | export ARM_CLIENT_ID=$clientId 48 | export ARM_OIDC_REQUEST_TOKEN=$ACTIONS_ID_TOKEN_REQUEST_TOKEN 49 | export ARM_OIDC_REQUEST_URL=$ACTIONS_ID_TOKEN_REQUEST_URL -------------------------------------------------------------------------------- /workflows/ISSUE_TEMPLATE/Feature_Request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: I have a suggestion (and might want to implement myself)! 3 | title: "Support for [thing]" 4 | body: 5 | - type: checkboxes 6 | attributes: 7 | label: Is there an existing issue for this? 8 | description: Please search to see if an issue already exists for the feature you are requesting. 9 | options: 10 | - label: I have searched the existing issues 11 | required: true 12 | - type: textarea 13 | id: description 14 | attributes: 15 | label: Description 16 | description: Please leave a helpful description of the feature request here. 17 | validations: 18 | required: true 19 | - type: input 20 | id: resource 21 | attributes: 22 | label: New or Affected Resource(s)/Data Source(s) 23 | description: Please list the new or affected resources and/or data sources. 24 | placeholder: azurerm_XXXXX 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: config 29 | attributes: 30 | label: Potential Terraform Configuration 31 | description: Please provide an example of what the enhancement could look like on this Terraform module. 32 | render: hcl 33 | - type: textarea 34 | id: references 35 | attributes: 36 | label: References 37 | description: | 38 | Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests 39 | 40 | Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Vendor blog posts or documentation? For example: 41 | 42 | * https://azure.microsoft.com/en-us/roadmap/virtual-network-service-endpoint-for-azure-cosmos-db/ -------------------------------------------------------------------------------- /avm_scripts/terraform-validate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Validating module terraform codes..." 3 | error=false 4 | (terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 5 | if ${error}; then 6 | echo "------------------------------------------------" 7 | echo "" 8 | echo "Some Terraform codes contain errors." 9 | echo "$(terraform validate -json)" 10 | echo "" 11 | exit 1 12 | fi 13 | echo "==> Checking examples terraform codes are validate..." 14 | examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 15 | for d in $examples; do 16 | (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 17 | if ${error}; then 18 | echo "------------------------------------------------" 19 | echo "" 20 | echo "Some Terraform codes contain errors." 21 | pwd 22 | echo "$(cd $d && terraform validate -json)" 23 | echo "" 24 | exit 1 25 | fi 26 | done 27 | 28 | echo "==> Checking module terraform code are validate..." 29 | if [ ! -d modules ]; then 30 | echo "==> Warning - no modules directory found" 31 | else 32 | modules=$(find ./modules -maxdepth 1 -mindepth 1 -type d) 33 | for d in $modules; do 34 | (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 35 | if ${error}; then 36 | echo "------------------------------------------------" 37 | echo "" 38 | echo "Some Terraform codes contain errors." 39 | pwd 40 | echo "$(cd $d && terraform validate -json)" 41 | echo "" 42 | exit 1 43 | fi 44 | done 45 | fi 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /avm_scripts_canary/terraform-validate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "==> Validating module terraform codes..." 3 | error=false 4 | (terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 5 | if ${error}; then 6 | echo "------------------------------------------------" 7 | echo "" 8 | echo "Some Terraform codes contain errors." 9 | echo "$(terraform validate -json)" 10 | echo "" 11 | exit 1 12 | fi 13 | echo "==> Checking examples terraform codes are validate..." 14 | examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d) 15 | for d in $examples; do 16 | (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 17 | if ${error}; then 18 | echo "------------------------------------------------" 19 | echo "" 20 | echo "Some Terraform codes contain errors." 21 | pwd 22 | echo "$(cd $d && terraform validate -json)" 23 | echo "" 24 | exit 1 25 | fi 26 | done 27 | 28 | echo "==> Checking module terraform code are validate..." 29 | if [ ! -d modules ]; then 30 | echo "==> Warning - no modules directory found" 31 | else 32 | modules=$(find ./modules -maxdepth 1 -mindepth 1 -type d) 33 | for d in $modules; do 34 | (echo "===> Terraform validating in " $d && cd $d && rm -f .terraform.lock.hcl && rm -rf .terraform && terraform init -upgrade && terraform validate -json | jq -e .valid) || error=true 35 | if ${error}; then 36 | echo "------------------------------------------------" 37 | echo "" 38 | echo "Some Terraform codes contain errors." 39 | pwd 40 | echo "$(cd $d && terraform validate -json)" 41 | echo "" 42 | exit 1 43 | fi 44 | done 45 | fi 46 | 47 | exit 0 48 | -------------------------------------------------------------------------------- /avm_scripts_canary/yor-tag.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | tracing_tags_enabled=$(hclgrep -x 'variable "tracing_tags_enabled" {@*_}' variables.tf) 5 | tracing_tags_prefix=$(hclgrep -x 'variable "tracing_tags_prefix" {@*_}' variables.tf) 6 | 7 | if [ -z "$tracing_tags_enabled" ] || [ -z "$tracing_tags_prefix" ]; then 8 | echo "==> No tracing_tags_enabled or tracing_tags_prefix variable found, skip tagging" 9 | exit 0 10 | fi 11 | 12 | if [ -f "module_telemetry.tf" ]; then 13 | cat module_telemetry.tf | 14 | hcledit attribute rm resource.modtm_telemetry.this.nonce | 15 | hcledit attribute rm resource.modtm_telemetry.this.ephemeral_number | 16 | hcledit attribute append resource.modtm_telemetry.this.ephemeral_number $RANDOM | 17 | hcledit attribute set resource.modtm_telemetry.this.lifecycle.ignore_changes "[ephemeral_number]" | 18 | tee module_telemetry.tf.bak 19 | cat module_telemetry.tf.bak > module_telemetry.tf 20 | rm module_telemetry.tf.bak 21 | make autofix 22 | git config --global --add safe.directory $(pwd) 23 | git add module_telemetry.tf 24 | git commit -m "Auto update for yor tags" 25 | fi 26 | 27 | error=false 28 | yor tag -d "$(pwd)" --skip-dirs "$(pwd)/examples" --skip-tags git_last_modified_by,git_modifiers --tag-prefix avm_ --parsers Terraform || error=true 29 | if ${error}; then 30 | echo "------------------------------------------------" 31 | echo "" 32 | echo "The preceding files contain terraform blocks that does not complies with yor requirements." 33 | echo "" 34 | exit 1 35 | fi 36 | yorbox -dir "$(pwd)" -tagsPrefix avm_ -toggleName tracing_tags_enabled -ignoreResourceType modtm_telemetry --boxTemplate '/**/ (var.{{ .toggleName }} ? { for k,v in /**/ { yor_trace = 123 } /**/ : replace(k, "avm_", var.tracing_tags_prefix) => v } : {} ) /**/' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### JetBrains template 2 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 3 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 4 | 5 | # User-specific stuff 6 | .idea/**/workspace.xml 7 | .idea/**/tasks.xml 8 | .idea/**/usage.statistics.xml 9 | .idea/**/dictionaries 10 | .idea/**/shelf 11 | 12 | # Generated files 13 | .idea/**/contentModel.xml 14 | 15 | # Sensitive or high-churn files 16 | .idea/**/dataSources/ 17 | .idea/**/dataSources.ids 18 | .idea/**/dataSources.local.xml 19 | .idea/**/sqlDataSources.xml 20 | .idea/**/dynamic.xml 21 | .idea/**/uiDesigner.xml 22 | .idea/**/dbnavigator.xml 23 | 24 | # Gradle 25 | .idea/**/gradle.xml 26 | .idea/**/libraries 27 | 28 | # Gradle and Maven with auto-import 29 | # When using Gradle or Maven with auto-import, you should exclude module files, 30 | # since they will be recreated, and may cause churn. Uncomment if using 31 | # auto-import. 32 | # .idea/artifacts 33 | # .idea/compiler.xml 34 | # .idea/jarRepositories.xml 35 | # .idea/modules.xml 36 | # .idea/*.iml 37 | # .idea/modules 38 | # *.iml 39 | # *.ipr 40 | 41 | # CMake 42 | cmake-build-*/ 43 | 44 | # Mongo Explorer plugin 45 | .idea/**/mongoSettings.xml 46 | 47 | # File-based project format 48 | *.iws 49 | 50 | # IntelliJ 51 | out/ 52 | 53 | # mpeltonen/sbt-idea plugin 54 | .idea_modules/ 55 | 56 | # JIRA plugin 57 | atlassian-ide-plugin.xml 58 | 59 | # Cursive Clojure plugin 60 | .idea/replstate.xml 61 | 62 | # Crashlytics plugin (for Android Studio and IntelliJ) 63 | com_crashlytics_export_strings.xml 64 | crashlytics.properties 65 | crashlytics-build.properties 66 | fabric.properties 67 | 68 | # Editor-based Rest Client 69 | .idea/httpRequests 70 | 71 | # Android studio 3.1+ serialized cache file 72 | .idea/caches/build_file_checksums.ser 73 | 74 | Dockerfile_azterraform 75 | Dockerfile_avm -------------------------------------------------------------------------------- /scripts/run-tflint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set_tflint_config() { 4 | local env_var=$1 5 | local override_file=$2 6 | local default_url=$3 7 | local download_file=$4 8 | local merged_file=$5 9 | 10 | # Always download the file from GitHub 11 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$default_url" -o "$download_file" 12 | 13 | # Check if the override file exists 14 | if [ -f "$override_file" ]; then 15 | # If it does, merge the override file and the downloaded file 16 | hclmerge -1 "$override_file" -2 "$download_file" -d "$merged_file" 17 | # Set the environment variable to the path of the merged file 18 | export $env_var="$merged_file" 19 | else 20 | # If it doesn't, set the environment variable to the path of the downloaded file 21 | export $env_var="$download_file" 22 | fi 23 | } 24 | 25 | set_tflint_config "TFLINT_CONFIG" ".tflint.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/.tflint.hcl" ".tflint.hcl" ".tflint.merged.hcl" 26 | set_tflint_config "TFLINT_EXAMPLE_CONFIG" ".tflint_example.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/.tflint_example.hcl" ".tflint_example.hcl" ".tflint_example.merged.hcl" 27 | 28 | 29 | echo "==> Checking that code complies with tflint requirements..." 30 | tflint --init --config=$TFLINT_CONFIG 31 | error=false 32 | tflint --config=$TFLINT_CONFIG --chdir=$(pwd)/ || error=true 33 | if ${error}; then 34 | echo "------------------------------------------------" 35 | echo "" 36 | echo "The preceding files contain terraform blocks that does not complies with tflint requirements." 37 | echo "" 38 | exit 1 39 | fi 40 | 41 | if [ ! -d "examples" ]; then 42 | echo "===> No examples folder, skip lint example code" 43 | exit 0 44 | fi 45 | 46 | cd examples 47 | dirs=$(find . -maxdepth 1 -mindepth 1 -type d) 48 | has_error=false 49 | tflint --init --config=$(pwd)/../$TFLINT_EXAMPLE_CONFIG 50 | for d in $dirs; do 51 | error=false 52 | tflint --config=$(pwd)/../$TFLINT_EXAMPLE_CONFIG --chdir=$(pwd)/./$d || error=true 53 | if ${error}; then 54 | has_error=true 55 | echo "------------------------------------------------" 56 | echo "" 57 | echo "The $d contain terraform blocks that does not complies with tflint requirements." 58 | echo "" 59 | fi 60 | done 61 | if ${has_error}; then 62 | exit 1 63 | fi 64 | exit 0 -------------------------------------------------------------------------------- /avm_scripts/conftest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | has_error=false 6 | 7 | if [ ! -d "examples" ]; then 8 | echo "No \`examples\` folder found." 9 | exit 0 10 | fi 11 | 12 | cd examples 13 | 14 | for d in $(find . -maxdepth 1 -mindepth 1 -type d); do 15 | if ls "$d"/*.tf > /dev/null 2>&1; then 16 | cd "$d" 17 | echo "==> Checking $d" 18 | 19 | if [ -f ".e2eignore" ]; then 20 | echo "==> Skipping $d due to .e2eignore file" 21 | cd - >/dev/null 2>&1 22 | continue 23 | fi 24 | 25 | # run pre.sh if it exists 26 | if [ -f "./pre.sh" ]; then 27 | echo "==> Running pre.sh" 28 | chmod +x ./pre.sh 29 | ./pre.sh 30 | fi 31 | 32 | echo "==> Initializing Terraform..." 33 | terraform init -input=false 34 | echo "==> Running Terraform plan..." 35 | terraform plan -input=false -out=tfplan.binary 36 | echo "==> Converting Terraform plan to JSON..." 37 | terraform show -json tfplan.binary > tfplan.json 38 | 39 | mkdir -p ./policy/default_exceptions 40 | curl -sS -o ./policy/default_exceptions/avmsec_exceptions.rego https://raw.githubusercontent.com/Azure/policy-library-avm/refs/heads/main/policy/avmsec/avm_exceptions.rego.bak 41 | 42 | if [ -d "exceptions" ]; then 43 | conftest test --all-namespaces --update git::https://github.com/Azure/policy-library-avm.git//policy/Azure-Proactive-Resiliency-Library-v2 -p policy/aprl -p policy/default_exceptions -p exceptions tfplan.json || has_error=true 44 | conftest test --all-namespaces --update git::https://github.com/Azure/policy-library-avm.git//policy/avmsec -p policy/avmsec -p policy/default_exceptions -p exceptions tfplan.json || has_error=true 45 | else 46 | conftest test --all-namespaces --update git::https://github.com/Azure/policy-library-avm.git//policy/Azure-Proactive-Resiliency-Library-v2 -p policy/aprl -p policy/default_exceptions tfplan.json || has_error=true 47 | conftest test --all-namespaces --update git::https://github.com/Azure/policy-library-avm.git//policy/avmsec -p policy/avmsec -p policy/default_exceptions tfplan.json || has_error=true 48 | fi 49 | 50 | # run post.sh if it exists 51 | if [ -f "./post.sh" ]; then 52 | echo "==> Running post.sh" 53 | chmod +x ./post.sh 54 | ./post.sh 55 | fi 56 | 57 | cd - >/dev/null 2>&1 58 | fi 59 | done 60 | 61 | cd .. 62 | 63 | if [ "$has_error" = true ]; then 64 | echo "At least one \`examples\` folder failed." 65 | exit 1 66 | fi 67 | 68 | echo "All \`examples\` folders passed." 69 | exit 0 70 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/post-push.yaml: -------------------------------------------------------------------------------- 1 | name: Post Push Update 2 | on: 3 | workflow_call: 4 | 5 | jobs: 6 | post-push: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: get-default-branch 10 | run: | 11 | branch=$(curl -s "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.default_branch') 12 | echo "default_branch=$branch" >> $GITHUB_ENV 13 | - uses: 8BitJonny/gh-get-current-pr@2215326c76d51bfa3f2af0a470f32677f6c0cae9 # v2.2.0 14 | id: PR 15 | - name: checkout 16 | uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 #v3.6.0 17 | with: 18 | ref: ${{ env.default_branch }} 19 | fetch-depth: 0 20 | - name: init 21 | run: | 22 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make generate 23 | - name: Yor Tag 24 | id: yor-tag 25 | run: | 26 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make yor-tag 27 | - name: update-changelog 28 | run: | 29 | MAJOR_VERSION=$(ls | grep CHANGELOG | cut -d'-' -f 2 | cut -f 1 -d '.' | grep v | sort -V -r | head -n 1) 30 | if [ -z "$MAJOR_VERSION" ]; then 31 | MAJOR_VERSION=0 32 | else 33 | MAJOR_VERSION=${MAJOR_VERSION#"v"} 34 | MAJOR_VERSION=$((MAJOR_VERSION+1)) 35 | fi 36 | 37 | previous_tag=$(docker run -e MAJOR_VERSION=$MAJOR_VERSION --rm mcr.microsoft.com/azterraform:latest previousTag ${{ github.repository_owner }} ${{ github.event.repository.name }} $MAJOR_VERSION.0.0) 38 | if [ -z $previous_tag ]; then 39 | docker run --rm -v $(pwd):/src -w /src githubchangeloggenerator/github-changelog-generator -u ${{ github.repository_owner }} -p ${{ github.event.repository.name }} -t ${{ secrets.GITHUB_TOKEN }} --no-issues --no-compare-link 40 | else 41 | docker run --rm -v $(pwd):/src -w /src githubchangeloggenerator/github-changelog-generator -u ${{ github.repository_owner }} -p ${{ github.event.repository.name }} -t ${{ secrets.GITHUB_TOKEN }} --no-issues --no-compare-link --since-tag=$previous_tag 42 | fi 43 | sudo chmod -R ugo+rwX . 44 | - name: AutoFix 45 | id: autofix 46 | run: | 47 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest make autofix 48 | - name: Terraform Validate 49 | id: terraform-validate 50 | run: | 51 | docker run --rm -v $(pwd):/src -w /src mcr.microsoft.com/azterraform:latest sh -c "make pre-commit && make pr-check" 52 | - name: Commit & Push changes 53 | uses: actions-js/push@156f2b10c3aa000c44dbe75ea7018f32ae999772 # v1.4 54 | if: ${{ github.repository != 'Azure/terraform-verified-module' }} 55 | with: 56 | github_token: ${{ secrets.GITHUB_TOKEN }} 57 | message: 'Auto update' 58 | branch: ${{ env.default_branch }} -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | REMOTE_SCRIPT := "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/scripts" 2 | 3 | fmt: 4 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/fmt.sh" | bash 5 | 6 | fumpt: 7 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/fumpt.sh" | bash 8 | 9 | gosec: 10 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/gosec.sh" | bash 11 | 12 | tffmt: 13 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/tffmt.sh" | bash 14 | 15 | tffmtcheck: 16 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/terraform-fmt.sh" | bash 17 | 18 | tfvalidatecheck: 19 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/terraform-validate.sh" | bash 20 | 21 | terrafmtcheck: 22 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/terrafmt-check.sh" | bash 23 | 24 | gofmtcheck: 25 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/gofmtcheck.sh" | bash 26 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/fumptcheck.sh" | bash 27 | 28 | golint: 29 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/run-golangci-lint.sh" | bash 30 | 31 | tflint: 32 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/run-tflint.sh" | bash 33 | 34 | lint: golint tflint gosec 35 | 36 | checkovcheck: 37 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/checkovcheck.sh" | bash 38 | 39 | checkovplancheck: 40 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/checkovplancheck.sh" | bash 41 | 42 | fmtcheck: gofmtcheck tfvalidatecheck tffmtcheck terrafmtcheck 43 | 44 | pr-check: depscheck fmtcheck lint unit-test checkovcheck 45 | 46 | unit-test: 47 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/run-unit-test.sh" | bash 48 | 49 | e2e-test: 50 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/run-e2e-test.sh" | bash 51 | 52 | version-upgrade-test: 53 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/version-upgrade-test.sh" | bash 54 | 55 | terrafmt: 56 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/terrafmt.sh" | bash 57 | 58 | pre-commit: tffmt terrafmt depsensure fmt fumpt generate 59 | 60 | depsensure: 61 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/deps-ensure.sh" | bash 62 | 63 | depscheck: 64 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/deps-check.sh" | bash 65 | 66 | generate: 67 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/generate.sh" | bash 68 | 69 | gencheck: 70 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/gencheck.sh" | bash 71 | 72 | yor-tag: 73 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/yor-tag.sh" | bash 74 | 75 | autofix: 76 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/autofix.sh" | bash 77 | 78 | test: fmtcheck 79 | @TEST=$(TEST) curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/run-gradually-deprecated.sh" | bash 80 | @TEST=$(TEST) curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/run-test.sh" | bash 81 | 82 | build-test: 83 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/build-test.sh" | bash 84 | 85 | .PHONY: fmt fmtcheck pr-check -------------------------------------------------------------------------------- /avm_scripts_canary/run-tflint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set_tflint_config() { 4 | local env_var=$1 5 | local override_file=$2 6 | local default_url=$3 7 | local download_file=$4 8 | local merged_file=$5 9 | 10 | # Always download the file from GitHub 11 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$default_url" -o "$download_file" 12 | 13 | # Check if the override file exists 14 | if [ -f "$override_file" ]; then 15 | # If it does, merge the override file and the downloaded file 16 | hclmerge -1 "$override_file" -2 "$download_file" -d "$merged_file" 17 | # Set the environment variable to the path of the merged file 18 | export $env_var="$merged_file" 19 | else 20 | # If it doesn't, set the environment variable to the path of the downloaded file 21 | export $env_var="$download_file" 22 | fi 23 | } 24 | 25 | set_tflint_config "TFLINT_CONFIG" "avm.tflint.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm.tflint.hcl" "avm.tflint.hcl" "avm.tflint.merged.hcl" 26 | set_tflint_config "TFLINT_MODULE_CONFIG" "avm.tflint_module.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm.tflint_module.hcl" "avm.tflint_module.hcl" "avm.tflint_module.merged.hcl" 27 | set_tflint_config "TFLINT_EXAMPLE_CONFIG" "avm.tflint_example.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm.tflint_example.hcl" "avm.tflint_example.hcl" "avm.tflint_example.merged.hcl" 28 | 29 | configPathRoot=$(pwd)/$TFLINT_CONFIG 30 | configPathModule=$(pwd)/$TFLINT_MODULE_CONFIG 31 | configPathExample=$(pwd)/$TFLINT_EXAMPLE_CONFIG 32 | 33 | run_tflint () { 34 | local dir=$1 35 | local config=$2 36 | local moduleType=$3 37 | local currentDir=$(pwd) 38 | 39 | cd $dir 40 | 41 | echo "==> Running tflint for $moduleType $dir" 42 | 43 | tflint --init --config=$config 44 | tflint --config=$config --minimum-failure-severity=warning 45 | local result=$? 46 | 47 | cd $currentDir 48 | 49 | if [ $result -ne 0 ]; then 50 | echo "------------------------------------------------" 51 | echo "" 52 | echo "The $moduleType $dir contains terraform blocks that do not comply with tflint requirements." 53 | echo "" 54 | return 1 55 | fi 56 | 57 | return 0 58 | } 59 | 60 | has_error=false 61 | 62 | echo "==> Checking that root module complies with tflint requirements..." 63 | run_tflint . $configPathRoot "root module" 64 | result=$? 65 | if [ $result -ne 0 ]; then 66 | has_error=true 67 | fi 68 | 69 | echo "==> Checking that sub modules comply with tflint requirements..." 70 | if [ ! -d "modules" ]; then 71 | echo "===> No modules folder, skip lint module code" 72 | else 73 | cd modules 74 | dirs=$(find . -maxdepth 1 -mindepth 1 -type d) 75 | 76 | for d in $dirs; do 77 | run_tflint $d $configPathModule "sub module" 78 | result=$? 79 | if [ $result -ne 0 ]; then 80 | has_error=true 81 | fi 82 | done 83 | 84 | cd .. 85 | fi 86 | 87 | echo "==> Checking that examples comply with tflint requirements..." 88 | if [ ! -d "examples" ]; then 89 | echo "===> No examples folder, skip lint example code" 90 | else 91 | cd examples 92 | dirs=$(find . -maxdepth 1 -mindepth 1 -type d) 93 | 94 | for d in $dirs; do 95 | run_tflint $d $configPathExample "example" 96 | result=$? 97 | if [ $result -ne 0 ]; then 98 | has_error=true 99 | fi 100 | done 101 | 102 | cd .. 103 | fi 104 | 105 | if ${has_error}; then 106 | echo "------------------------------------------------" 107 | echo "" 108 | echo "The preceding files contain terraform blocks that do not comply with tflint requirements." 109 | echo "" 110 | exit 1 111 | fi 112 | 113 | exit 0 114 | -------------------------------------------------------------------------------- /avm_scripts/run-tflint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set_tflint_config() { 4 | local env_var=$1 5 | local override_file=$2 6 | local default_url=$3 7 | local download_file=$4 8 | local merged_file=$5 9 | 10 | # Always download the file from GitHub 11 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$default_url" -o "$download_file" 12 | 13 | # Check if the override file exists 14 | if [ -f "$override_file" ]; then 15 | # If it does, merge the override file and the downloaded file 16 | hclmerge -1 "$override_file" -2 "$download_file" -d "$merged_file" 17 | # Set the environment variable to the path of the merged file 18 | export $env_var="$merged_file" 19 | else 20 | # If it doesn't, set the environment variable to the path of the downloaded file 21 | export $env_var="$download_file" 22 | fi 23 | } 24 | 25 | set_tflint_config "TFLINT_CONFIG" "avm.tflint.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm.tflint.hcl" "avm.tflint.hcl" "avm.tflint.merged.hcl" 26 | set_tflint_config "TFLINT_MODULE_CONFIG" "avm.tflint_module.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm.tflint_module.hcl" "avm.tflint_module.hcl" "avm.tflint_module.merged.hcl" 27 | set_tflint_config "TFLINT_EXAMPLE_CONFIG" "avm.tflint_example.override.hcl" "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm.tflint_example.hcl" "avm.tflint_example.hcl" "avm.tflint_example.merged.hcl" 28 | 29 | configPathRoot=$(pwd)/$TFLINT_CONFIG 30 | configPathModule=$(pwd)/$TFLINT_MODULE_CONFIG 31 | configPathExample=$(pwd)/$TFLINT_EXAMPLE_CONFIG 32 | 33 | run_tflint () { 34 | local dir=$1 35 | local config=$2 36 | local moduleType=$3 37 | local currentDir=$(pwd) 38 | 39 | cd $dir 40 | 41 | echo "==> Running tflint for $moduleType $dir" 42 | 43 | tflint --init --config=$config 44 | tflint --config=$config --minimum-failure-severity=warning 45 | local result=$? 46 | 47 | cd $currentDir 48 | 49 | if [ $result -ne 0 ]; then 50 | echo "------------------------------------------------" 51 | echo "" 52 | echo "The $moduleType $dir contains terraform blocks that do not comply with tflint requirements." 53 | echo "" 54 | return 1 55 | fi 56 | 57 | return 0 58 | } 59 | 60 | set -eo pipefail 61 | echo "==> Copy module to temp dir..." 62 | RND="$RANDOM" 63 | TMPDIR="/tmp/avmtester$RND" 64 | cp -r . "$TMPDIR" 65 | cd "$TMPDIR" 66 | 67 | # clean up terraform files 68 | find -type d -name .terraform -print0 | xargs -0 rm -rf 69 | find -type f -name .terraform.lock.hcl -print0 | xargs -0 rm -rf 70 | find -type f -name 'terraform.tfstate*' -print0 | xargs -0 rm -rf 71 | set +eo pipefail 72 | 73 | has_error=false 74 | 75 | echo "==> Checking that root module complies with tflint requirements..." 76 | run_tflint . $configPathRoot "root module" 77 | result=$? 78 | if [ $result -ne 0 ]; then 79 | has_error=true 80 | fi 81 | 82 | echo "==> Checking that sub modules comply with tflint requirements..." 83 | if [ ! -d "modules" ]; then 84 | echo "===> No modules folder, skip lint module code" 85 | else 86 | cd modules 87 | dirs=$(find . -maxdepth 1 -mindepth 1 -type d) 88 | 89 | for d in $dirs; do 90 | run_tflint $d $configPathModule "sub module" 91 | result=$? 92 | if [ $result -ne 0 ]; then 93 | has_error=true 94 | fi 95 | done 96 | 97 | cd .. 98 | fi 99 | 100 | echo "==> Checking that examples comply with tflint requirements..." 101 | if [ ! -d "examples" ]; then 102 | echo "===> No examples folder, skip lint example code" 103 | else 104 | cd examples 105 | dirs=$(find . -maxdepth 1 -mindepth 1 -type d) 106 | 107 | for d in $dirs; do 108 | run_tflint $d $configPathExample "example" 109 | result=$? 110 | if [ $result -ne 0 ]; then 111 | has_error=true 112 | fi 113 | done 114 | 115 | cd .. 116 | fi 117 | 118 | if ${has_error}; then 119 | echo "------------------------------------------------" 120 | echo "" 121 | echo "The preceding files contain terraform blocks that do not comply with tflint requirements." 122 | echo "" 123 | exit 1 124 | fi 125 | 126 | exit 0 127 | -------------------------------------------------------------------------------- /avmmakefile: -------------------------------------------------------------------------------- 1 | REMOTE_SCRIPT := https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/avm_scripts 2 | RUN_SCRIPT = if [ -n "$$LOCAL_SCRIPT" ]; then bash "$$LOCAL_SCRIPT/$1"; else curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/$1" | bash; fi 3 | 4 | .PHONY: help 5 | help: 6 | @echo "please use 'make '" 7 | 8 | .PHONY: conftest 9 | conftest: 10 | @$(call RUN_SCRIPT,conftest.sh) 11 | 12 | .PHONY: docs 13 | docs: 14 | @$(call RUN_SCRIPT,docs-gen.sh) 15 | 16 | .PHONY: docscheck 17 | docscheck: 18 | @$(call RUN_SCRIPT,docs-check.sh) 19 | 20 | .PHONY: fmt 21 | fmt: gofmt terrafmt 22 | @$(call RUN_SCRIPT,terraform-fmt-apply.sh) 23 | 24 | .PHONY: gofmt 25 | gofmt: 26 | @$(call RUN_SCRIPT,gofmt.sh) 27 | 28 | .PHONY: fumpt 29 | fumpt: 30 | @$(call RUN_SCRIPT,go-fumpt.sh) 31 | 32 | .PHONY: gosec 33 | gosec: 34 | @$(call RUN_SCRIPT,gosec.sh) 35 | 36 | .PHONY: tffmtcheck 37 | tffmtcheck: 38 | @$(call RUN_SCRIPT,terraform-fmt.sh) 39 | 40 | .PHONY: tfvalidatecheck 41 | tfvalidatecheck: 42 | @$(call RUN_SCRIPT,terraform-validate.sh) 43 | 44 | .PHONY: terrafmtcheck 45 | terrafmtcheck: 46 | @$(call RUN_SCRIPT,terrafmt-check.sh) 47 | 48 | .PHONY: gofmtcheck 49 | gofmtcheck: 50 | @$(call RUN_SCRIPT,gofmtcheck.sh) 51 | @$(call RUN_SCRIPT,fumptcheck.sh) 52 | 53 | .PHONY: golint 54 | golint: 55 | @$(call RUN_SCRIPT,run-golangci-lint.sh) 56 | 57 | .PHONY: tflint 58 | tflint: 59 | @$(call RUN_SCRIPT,run-tflint.sh) 60 | 61 | .PHONY: lint 62 | lint: golint tflint gosec 63 | 64 | .PHONY: fmtcheck 65 | fmtcheck: gofmtcheck tffmtcheck terrafmtcheck 66 | 67 | .PHONY: pr-check 68 | pr-check: fmtcheck docscheck mapotf-precommit-check grept-precommit-check tfvalidatecheck lint unit-test integration-test 69 | 70 | .PHONY: unit-test 71 | unit-test: 72 | @$(call RUN_SCRIPT,run-terraform-test.sh) 73 | 74 | .PHONY: integration-test 75 | integration-test: 76 | @$(call RUN_SCRIPT,run-terraform-test.sh) 77 | 78 | .PHONY: test-example 79 | test-example: 80 | @$(call RUN_SCRIPT,test-example.sh) 81 | 82 | .PHONY: e2e-test 83 | e2e-test: 84 | @$(call RUN_SCRIPT,run-e2e-test.sh) 85 | 86 | .PHONY: version-upgrade-test 87 | version-upgrade-test: 88 | @$(call RUN_SCRIPT,version-upgrade-test.sh) 89 | 90 | .PHONY: terrafmt 91 | terrafmt: 92 | @$(call RUN_SCRIPT,terrafmt.sh) 93 | 94 | .PHONY: pre-commit 95 | pre-commit: depsensure fmt mapotf-precommit grept-precommit autofix docs 96 | 97 | .PHONY: mapotf-precommit 98 | mapotf-precommit: 99 | @$(call RUN_SCRIPT,mapotf-precommit.sh) 100 | 101 | .PHONY: grept-precommit 102 | grept-precommit: 103 | @$(call RUN_SCRIPT,grept-precommit.sh) 104 | 105 | .PHONY: grept-precommit 106 | grept-precommit: 107 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/grept-precommit.sh" | bash 108 | 109 | .PHONY: mapotf-precommit-check 110 | mapotf-precommit-check: 111 | @$(call RUN_SCRIPT,mapotf-precommit-check.sh) 112 | 113 | .PHONY: grept-precommit-check 114 | grept-precommit-check: 115 | @$(call RUN_SCRIPT,grept-precommit-check.sh) 116 | 117 | .PHONY: grept-precommit-check 118 | grept-precommit-check: 119 | curl -H 'Cache-Control: no-cache, no-store' -sSL "$(REMOTE_SCRIPT)/grept-precommit-check.sh" | bash 120 | 121 | .PHONY: depsensure 122 | depsensure: 123 | @$(call RUN_SCRIPT,deps-ensure.sh) 124 | 125 | .PHONY: autofix 126 | autofix: 127 | @$(call RUN_SCRIPT,autofix.sh) 128 | 129 | .PHONY: grept-apply 130 | grept-apply: 131 | @$(call RUN_SCRIPT,grept-apply.sh) 132 | 133 | .PHONY: migrate 134 | migrate: 135 | @curl -H 'Cache-Control: no-cache, no-store' -sSL https://raw.githubusercontent.com/Azure/avm-terraform-governance/main/managed-files/root/avm -o avm 136 | @curl -H 'Cache-Control: no-cache, no-store' -sSL https://raw.githubusercontent.com/Azure/avm-terraform-governance/main/managed-files/root/avm.ps1 -o avm.ps1 137 | @curl -H 'Cache-Control: no-cache, no-store' -sSL https://raw.githubusercontent.com/Azure/avm-terraform-governance/main/managed-files/root/avm.bat -o avm.bat 138 | @curl -H 'Cache-Control: no-cache, no-store' -sSL https://raw.githubusercontent.com/Azure/avm-terraform-governance/main/managed-files/root/Makefile -o Makefile 139 | @echo "Migration complete. Please run ./avm pre-commit now." 140 | -------------------------------------------------------------------------------- /avm.tflint.hcl: -------------------------------------------------------------------------------- 1 | plugin "terraform" { 2 | enabled = true 3 | version = "0.10.0" 4 | source = "github.com/terraform-linters/tflint-ruleset-terraform" 5 | } 6 | 7 | plugin "avm" { 8 | enabled = true 9 | version = "0.14.1" 10 | source = "github.com/Azure/tflint-ruleset-avm" 11 | signing_key = <<-KEY 12 | -----BEGIN PGP PUBLIC KEY BLOCK----- 13 | Version: BSN Pgp v1.1.0.0 14 | 15 | mQENBF9hII8BCADEOCDl3/1tAZQp/1BCVJN+tqIRCd3ywzhOXTC38XWC0zVbFtiA 16 | vbBFL1e78aoDIyUFDZcphCyYDqBkweXeYyYVCojZFVniyKklc2xZ15LDwlMBhneU 17 | yEPSzDCltFn67wMPQMKa4+TujZJ3TIs1OUnUTsCPrjavGgmrfAdxAF/EjCDrnVp9 18 | XmRWJii/9elAnMqWLDkMDfPaWkv3lWuyYCBHc7avOJE9oWypmWoEPOujwmtika/i 19 | FhmvZbojZN6huf7pykXGRl1wEpu0MMEFvm4UsfEOv8JHVBZEu2w6glQugT6a+IZ6 20 | atH3zyy+i1mmgsJPlMF1soHNEufeK1CabMklABEBAAG0Q1RlcnJhZm9ybSBBRE8g 21 | cHJvdmlkZXIgcmVsZWFzZSA8dGVycmFmb3JtYWRvcHJvdmlkZXJAbWljcm9zb2Z0 22 | LmNvbT6JATgEEwEIACIFAl9hII8CGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA 23 | AAoJEG8Lkb3phHjPT+YH/3aksw2yhoqVl+Dxkrpsq9LIsXBHmHfbk8/nwbZ7F6o6 24 | fZetwozQzS/v5IriE42NFdk2omilDa/Iumk5soPrCamIIToYMbGvZJ9MJzCflXzp 25 | H3crqEgoCwu/93FVot4hhNOGmS2ra538zDQ3JsSbsVSc2TyPeBCF08+qJrr9VSML 26 | LceuEvCKUN8P8LH+PXN4kKM1xNlSVw4RfH6mNJKdUG1Klvh2nbq0kuw8jiHITn2F 27 | ALGvKXPLwggdNA86RIQc9tc3z/uJrBGSA2n6UkJbV1gFZDETjHzVtgDqqEQwap7D 28 | /i9e5KqIAEIf14OPm3h+e6kCdWXRG0RJWWVWeOHIEfQ= 29 | =KwXd 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | KEY 32 | } 33 | 34 | rule "terraform_comment_syntax" { 35 | enabled = true 36 | } 37 | 38 | rule "terraform_deprecated_index" { 39 | enabled = true 40 | } 41 | 42 | rule "terraform_deprecated_interpolation" { 43 | enabled = true 44 | } 45 | 46 | rule "terraform_deprecated_lookup" { 47 | enabled = true 48 | } 49 | 50 | rule "terraform_documented_outputs" { 51 | enabled = true 52 | } 53 | 54 | rule "terraform_documented_variables" { 55 | enabled = true 56 | } 57 | 58 | rule "terraform_empty_list_equality" { 59 | enabled = true 60 | } 61 | 62 | rule "terraform_module_pinned_source" { 63 | enabled = true 64 | } 65 | 66 | rule "terraform_module_version" { 67 | enabled = true 68 | exact = true 69 | } 70 | 71 | rule "terraform_naming_convention" { 72 | enabled = true 73 | } 74 | 75 | rule "terraform_required_providers" { 76 | enabled = true 77 | } 78 | 79 | rule "terraform_required_version" { 80 | enabled = true 81 | } 82 | 83 | rule "terraform_standard_module_structure" { 84 | enabled = false 85 | } 86 | 87 | rule "terraform_typed_variables" { 88 | enabled = true 89 | } 90 | 91 | rule "terraform_unused_declarations" { 92 | enabled = true 93 | } 94 | 95 | rule "terraform_unused_required_providers" { 96 | enabled = true 97 | } 98 | 99 | rule "terraform_workspace_remote" { 100 | enabled = true 101 | } 102 | 103 | rule "terraform_heredoc_usage" { 104 | enabled = true 105 | } 106 | 107 | rule "terraform_module_provider_declaration" { 108 | enabled = true 109 | } 110 | 111 | rule "terraform_output_separate" { 112 | enabled = true 113 | } 114 | 115 | rule "terraform_required_providers_declaration" { 116 | enabled = true 117 | } 118 | 119 | rule "terraform_required_version_declaration" { 120 | enabled = true 121 | } 122 | 123 | rule "terraform_sensitive_variable_no_default" { 124 | enabled = true 125 | } 126 | 127 | rule "terraform_variable_nullable_false" { 128 | enabled = true 129 | } 130 | 131 | rule "terraform_variable_separate" { 132 | enabled = true 133 | } 134 | 135 | rule "azurerm_resource_tag" { 136 | enabled = true 137 | } 138 | 139 | # AVM Provider Rules 140 | 141 | rule "tfnfr26" { 142 | enabled = true 143 | } 144 | 145 | # AVM Module Rules 146 | 147 | rule "required_module_source_tffr1" { 148 | enabled = true 149 | } 150 | 151 | # AVM Output Rules 152 | 153 | rule "required_output_rmfr7" { 154 | enabled = true 155 | } 156 | 157 | # AVM Variable Interface Rules 158 | 159 | rule "customer_managed_key" { 160 | enabled = true 161 | } 162 | 163 | rule "diagnostic_settings" { 164 | enabled = true 165 | } 166 | 167 | rule "location" { 168 | enabled = true 169 | } 170 | 171 | rule "lock" { 172 | enabled = true 173 | } 174 | 175 | rule "managed_identities" { 176 | enabled = true 177 | } 178 | 179 | rule "private_endpoints" { 180 | enabled = true 181 | } 182 | 183 | rule "role_assignments" { 184 | enabled = true 185 | } 186 | 187 | rule "tags" { 188 | enabled = true 189 | } 190 | 191 | rule "provider_modtm_version_constraint" { 192 | enabled = true 193 | } 194 | 195 | rule "valid_template_interpolation" { 196 | enabled = true 197 | } 198 | -------------------------------------------------------------------------------- /avm.tflint_example.hcl: -------------------------------------------------------------------------------- 1 | plugin "terraform" { 2 | enabled = true 3 | version = "0.10.0" 4 | source = "github.com/terraform-linters/tflint-ruleset-terraform" 5 | } 6 | 7 | plugin "avm" { 8 | enabled = true 9 | version = "0.14.1" 10 | source = "github.com/Azure/tflint-ruleset-avm" 11 | signing_key = <<-KEY 12 | -----BEGIN PGP PUBLIC KEY BLOCK----- 13 | Version: BSN Pgp v1.1.0.0 14 | 15 | mQENBF9hII8BCADEOCDl3/1tAZQp/1BCVJN+tqIRCd3ywzhOXTC38XWC0zVbFtiA 16 | vbBFL1e78aoDIyUFDZcphCyYDqBkweXeYyYVCojZFVniyKklc2xZ15LDwlMBhneU 17 | yEPSzDCltFn67wMPQMKa4+TujZJ3TIs1OUnUTsCPrjavGgmrfAdxAF/EjCDrnVp9 18 | XmRWJii/9elAnMqWLDkMDfPaWkv3lWuyYCBHc7avOJE9oWypmWoEPOujwmtika/i 19 | FhmvZbojZN6huf7pykXGRl1wEpu0MMEFvm4UsfEOv8JHVBZEu2w6glQugT6a+IZ6 20 | atH3zyy+i1mmgsJPlMF1soHNEufeK1CabMklABEBAAG0Q1RlcnJhZm9ybSBBRE8g 21 | cHJvdmlkZXIgcmVsZWFzZSA8dGVycmFmb3JtYWRvcHJvdmlkZXJAbWljcm9zb2Z0 22 | LmNvbT6JATgEEwEIACIFAl9hII8CGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA 23 | AAoJEG8Lkb3phHjPT+YH/3aksw2yhoqVl+Dxkrpsq9LIsXBHmHfbk8/nwbZ7F6o6 24 | fZetwozQzS/v5IriE42NFdk2omilDa/Iumk5soPrCamIIToYMbGvZJ9MJzCflXzp 25 | H3crqEgoCwu/93FVot4hhNOGmS2ra538zDQ3JsSbsVSc2TyPeBCF08+qJrr9VSML 26 | LceuEvCKUN8P8LH+PXN4kKM1xNlSVw4RfH6mNJKdUG1Klvh2nbq0kuw8jiHITn2F 27 | ALGvKXPLwggdNA86RIQc9tc3z/uJrBGSA2n6UkJbV1gFZDETjHzVtgDqqEQwap7D 28 | /i9e5KqIAEIf14OPm3h+e6kCdWXRG0RJWWVWeOHIEfQ= 29 | =KwXd 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | KEY 32 | } 33 | 34 | rule "terraform_comment_syntax" { 35 | enabled = true 36 | } 37 | 38 | rule "terraform_deprecated_index" { 39 | enabled = true 40 | } 41 | 42 | rule "terraform_deprecated_interpolation" { 43 | enabled = true 44 | } 45 | 46 | rule "terraform_deprecated_lookup" { 47 | enabled = true 48 | } 49 | 50 | rule "terraform_documented_outputs" { 51 | enabled = false 52 | } 53 | 54 | rule "terraform_documented_variables" { 55 | enabled = false 56 | } 57 | 58 | rule "terraform_empty_list_equality" { 59 | enabled = true 60 | } 61 | 62 | rule "terraform_module_pinned_source" { 63 | enabled = true 64 | } 65 | 66 | rule "terraform_module_version" { 67 | enabled = true 68 | exact = true 69 | } 70 | 71 | rule "terraform_naming_convention" { 72 | enabled = true 73 | } 74 | 75 | rule "terraform_required_providers" { 76 | enabled = true 77 | } 78 | 79 | rule "terraform_required_version" { 80 | enabled = true 81 | } 82 | 83 | rule "terraform_standard_module_structure" { 84 | enabled = false 85 | } 86 | 87 | rule "terraform_typed_variables" { 88 | enabled = false 89 | } 90 | 91 | rule "terraform_unused_declarations" { 92 | enabled = true 93 | } 94 | 95 | rule "terraform_unused_required_providers" { 96 | enabled = true 97 | } 98 | 99 | rule "terraform_workspace_remote" { 100 | enabled = true 101 | } 102 | 103 | rule "terraform_heredoc_usage" { 104 | enabled = false 105 | } 106 | 107 | rule "terraform_module_provider_declaration" { 108 | enabled = false 109 | } 110 | 111 | rule "terraform_output_separate" { 112 | enabled = false 113 | } 114 | 115 | rule "terraform_required_providers_declaration" { 116 | enabled = true 117 | } 118 | 119 | rule "terraform_required_version_declaration" { 120 | enabled = true 121 | } 122 | 123 | rule "terraform_sensitive_variable_no_default" { 124 | enabled = false 125 | } 126 | 127 | rule "terraform_variable_nullable_false" { 128 | enabled = true 129 | } 130 | 131 | rule "terraform_variable_separate" { 132 | enabled = false 133 | } 134 | 135 | rule "azurerm_resource_tag" { 136 | enabled = false 137 | } 138 | 139 | # AVM Provider Rules 140 | 141 | rule "tfnfr26" { 142 | enabled = false 143 | } 144 | 145 | # AVM Module Rules 146 | 147 | rule "required_module_source_tffr1" { 148 | enabled = false 149 | } 150 | 151 | # AVM Output Rules 152 | 153 | rule "required_output_rmfr7" { 154 | enabled = false 155 | } 156 | 157 | # AVM Variable Interface Rules 158 | 159 | rule "customer_managed_key" { 160 | enabled = false 161 | } 162 | 163 | rule "diagnostic_settings" { 164 | enabled = false 165 | } 166 | 167 | rule "location" { 168 | enabled = false 169 | } 170 | 171 | rule "lock" { 172 | enabled = false 173 | } 174 | 175 | rule "managed_identities" { 176 | enabled = false 177 | } 178 | 179 | rule "private_endpoints" { 180 | enabled = false 181 | } 182 | 183 | rule "role_assignments" { 184 | enabled = false 185 | } 186 | 187 | rule "tags" { 188 | enabled = false 189 | } 190 | 191 | rule "provider_modtm_version_constraint" { 192 | enabled = false 193 | } 194 | 195 | rule "valid_template_interpolation" { 196 | enabled = true 197 | } 198 | -------------------------------------------------------------------------------- /avm.tflint_module.hcl: -------------------------------------------------------------------------------- 1 | plugin "terraform" { 2 | enabled = true 3 | version = "0.10.0" 4 | source = "github.com/terraform-linters/tflint-ruleset-terraform" 5 | } 6 | 7 | plugin "avm" { 8 | enabled = true 9 | version = "0.14.1" 10 | source = "github.com/Azure/tflint-ruleset-avm" 11 | signing_key = <<-KEY 12 | -----BEGIN PGP PUBLIC KEY BLOCK----- 13 | Version: BSN Pgp v1.1.0.0 14 | 15 | mQENBF9hII8BCADEOCDl3/1tAZQp/1BCVJN+tqIRCd3ywzhOXTC38XWC0zVbFtiA 16 | vbBFL1e78aoDIyUFDZcphCyYDqBkweXeYyYVCojZFVniyKklc2xZ15LDwlMBhneU 17 | yEPSzDCltFn67wMPQMKa4+TujZJ3TIs1OUnUTsCPrjavGgmrfAdxAF/EjCDrnVp9 18 | XmRWJii/9elAnMqWLDkMDfPaWkv3lWuyYCBHc7avOJE9oWypmWoEPOujwmtika/i 19 | FhmvZbojZN6huf7pykXGRl1wEpu0MMEFvm4UsfEOv8JHVBZEu2w6glQugT6a+IZ6 20 | atH3zyy+i1mmgsJPlMF1soHNEufeK1CabMklABEBAAG0Q1RlcnJhZm9ybSBBRE8g 21 | cHJvdmlkZXIgcmVsZWFzZSA8dGVycmFmb3JtYWRvcHJvdmlkZXJAbWljcm9zb2Z0 22 | LmNvbT6JATgEEwEIACIFAl9hII8CGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA 23 | AAoJEG8Lkb3phHjPT+YH/3aksw2yhoqVl+Dxkrpsq9LIsXBHmHfbk8/nwbZ7F6o6 24 | fZetwozQzS/v5IriE42NFdk2omilDa/Iumk5soPrCamIIToYMbGvZJ9MJzCflXzp 25 | H3crqEgoCwu/93FVot4hhNOGmS2ra538zDQ3JsSbsVSc2TyPeBCF08+qJrr9VSML 26 | LceuEvCKUN8P8LH+PXN4kKM1xNlSVw4RfH6mNJKdUG1Klvh2nbq0kuw8jiHITn2F 27 | ALGvKXPLwggdNA86RIQc9tc3z/uJrBGSA2n6UkJbV1gFZDETjHzVtgDqqEQwap7D 28 | /i9e5KqIAEIf14OPm3h+e6kCdWXRG0RJWWVWeOHIEfQ= 29 | =KwXd 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | KEY 32 | } 33 | 34 | rule "terraform_comment_syntax" { 35 | enabled = true 36 | } 37 | 38 | rule "terraform_deprecated_index" { 39 | enabled = true 40 | } 41 | 42 | rule "terraform_deprecated_interpolation" { 43 | enabled = true 44 | } 45 | 46 | rule "terraform_deprecated_lookup" { 47 | enabled = true 48 | } 49 | 50 | rule "terraform_documented_outputs" { 51 | enabled = true 52 | } 53 | 54 | rule "terraform_documented_variables" { 55 | enabled = true 56 | } 57 | 58 | rule "terraform_empty_list_equality" { 59 | enabled = true 60 | } 61 | 62 | rule "terraform_module_pinned_source" { 63 | enabled = true 64 | } 65 | 66 | rule "terraform_module_version" { 67 | enabled = true 68 | exact = true 69 | } 70 | 71 | rule "terraform_naming_convention" { 72 | enabled = true 73 | } 74 | 75 | rule "terraform_required_providers" { 76 | enabled = true 77 | } 78 | 79 | rule "terraform_required_version" { 80 | enabled = true 81 | } 82 | 83 | rule "terraform_standard_module_structure" { 84 | enabled = false 85 | } 86 | 87 | rule "terraform_typed_variables" { 88 | enabled = true 89 | } 90 | 91 | # disable for `locals.version.tf.json for now 92 | rule "terraform_unused_declarations" { 93 | enabled = true 94 | } 95 | 96 | rule "terraform_unused_required_providers" { 97 | enabled = true 98 | } 99 | 100 | rule "terraform_workspace_remote" { 101 | enabled = true 102 | } 103 | 104 | rule "terraform_heredoc_usage" { 105 | enabled = true 106 | } 107 | 108 | rule "terraform_module_provider_declaration" { 109 | enabled = true 110 | } 111 | 112 | rule "terraform_output_separate" { 113 | enabled = true 114 | } 115 | 116 | rule "terraform_required_providers_declaration" { 117 | enabled = true 118 | } 119 | 120 | rule "terraform_required_version_declaration" { 121 | enabled = true 122 | } 123 | 124 | rule "terraform_sensitive_variable_no_default" { 125 | enabled = true 126 | } 127 | 128 | rule "terraform_variable_nullable_false" { 129 | enabled = true 130 | } 131 | 132 | rule "terraform_variable_separate" { 133 | enabled = true 134 | } 135 | 136 | rule "azurerm_resource_tag" { 137 | enabled = true 138 | } 139 | 140 | # AVM Provider Rules 141 | 142 | rule "tfnfr26" { 143 | enabled = true 144 | } 145 | 146 | # AVM Module Rules 147 | 148 | rule "required_module_source_tffr1" { 149 | enabled = true 150 | } 151 | 152 | # AVM Output Rules 153 | 154 | rule "required_output_rmfr7" { 155 | enabled = true 156 | } 157 | 158 | # AVM Variable Interface Rules 159 | 160 | rule "customer_managed_key" { 161 | enabled = true 162 | } 163 | 164 | rule "diagnostic_settings" { 165 | enabled = true 166 | } 167 | 168 | rule "location" { 169 | enabled = true 170 | } 171 | 172 | rule "lock" { 173 | enabled = true 174 | } 175 | 176 | rule "managed_identities" { 177 | enabled = true 178 | } 179 | 180 | rule "private_endpoints" { 181 | enabled = true 182 | } 183 | 184 | rule "role_assignments" { 185 | enabled = true 186 | } 187 | 188 | rule "tags" { 189 | enabled = true 190 | } 191 | 192 | rule "provider_modtm_version_constraint" { 193 | enabled = false 194 | } 195 | 196 | rule "valid_template_interpolation" { 197 | enabled = true 198 | } 199 | -------------------------------------------------------------------------------- /workflows/ISSUE_TEMPLATE/Bug_Report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: If something isn't working as expected. 3 | labels: [bug] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thank you for taking the time to fill out a bug report. 9 | 10 | If you are not running the latest version of this module, please try to reproduce your bug with the latest version before opening an issue. 11 | - type: checkboxes 12 | attributes: 13 | label: Is there an existing issue for this? 14 | description: Please search to see if an issue already exists for the bug you encountered. 15 | options: 16 | - label: I have searched the existing issues 17 | required: true 18 | - type: dropdown 19 | attributes: 20 | label: Greenfield/Brownfield provisioning 21 | description: Do you reproduce the bug with a new infrastructure provisioning (greenfield) or you need an existing infrastructure with an existing terraform state (brownfield) to reproduce the bug ? 22 | multiple: false 23 | options: 24 | - greenfield 25 | - brownfield 26 | validations: 27 | required: true 28 | - type: input 29 | id: terraform 30 | attributes: 31 | label: Terraform Version 32 | description: Which Terraform version are you using? 33 | placeholder: Example value, 1.2.8 34 | validations: 35 | required: true 36 | - type: input 37 | id: module 38 | attributes: 39 | label: Module Version 40 | description: Which module version are you using? 41 | placeholder: Example value, 6.0.0 42 | validations: 43 | required: true 44 | - type: input 45 | id: azurerm 46 | attributes: 47 | label: AzureRM Provider Version 48 | description: Which AzureRM Provider version are you using? 49 | placeholder: Example value, 3.21.1 50 | validations: 51 | required: true 52 | - type: input 53 | id: resource 54 | attributes: 55 | label: Affected Resource(s)/Data Source(s) 56 | description: Please list the affected resources and/or data sources. 57 | placeholder: azurerm_XXXXX 58 | validations: 59 | required: true 60 | - type: textarea 61 | id: config 62 | attributes: 63 | label: Terraform Configuration Files 64 | description: | 65 | Please provide a minimal Terraform configuration that can reproduce the issue. 66 | render: hcl 67 | validations: 68 | required: true 69 | - type: textarea 70 | id: tfvars 71 | attributes: 72 | label: tfvars variables values 73 | description: | 74 | Please provide the necessary tfvars variables values to reproduce the issue. Do not share secrets or sensitive information. 75 | render: hcl 76 | validations: 77 | required: true 78 | - type: textarea 79 | id: debug 80 | attributes: 81 | label: Debug Output/Panic Output 82 | description: | 83 | For long debug logs please provide a link to a GitHub Gist containing the complete debug output. Please do NOT paste the debug output in the issue; just paste a link to the Gist. 84 | 85 | To obtain the debug output, see the [Terraform documentation on debugging](https://www.terraform.io/docs/internals/debugging.html). 86 | render: shell 87 | validations: 88 | required: true 89 | - type: textarea 90 | id: expected 91 | attributes: 92 | label: Expected Behaviour 93 | description: What should have happened? 94 | - type: textarea 95 | id: actual 96 | attributes: 97 | label: Actual Behaviour 98 | description: What actually happened? 99 | - type: textarea 100 | id: reproduce 101 | attributes: 102 | label: Steps to Reproduce 103 | description: | 104 | Please list the steps required to reproduce the issue, e.g. 105 | 106 | 1. `terraform apply` 107 | - type: input 108 | id: facts 109 | attributes: 110 | label: Important Factoids 111 | description: | 112 | Are there anything atypical about your accounts that we should know? For example: Running in a Azure China/Germany/Government? 113 | - type: textarea 114 | id: references 115 | attributes: 116 | label: References 117 | description: | 118 | Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests 119 | 120 | Are there any other GitHub issues (open or closed) or pull requests that should be linked here? Such as vendor documentation? 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure Verified Terraform Module Scaffold 2 | 3 | ![Image Build & Scan](https://img.shields.io/github/actions/workflow/status/Azure/tfmod-scaffold/check.yml) 4 | 5 | This scaffold is a collection of scripts to facilitate Azure Verified Terraform Module CI pipeline. It's designed to 6 | work with CI such as GitHub Actions, and provides a Dockerfile to run these steps on your local machine. 7 | 8 | ## Dockerfile 9 | 10 | We've provided a docker image at `mcr.microsoft.com/azterraform:latest`. This image is built by 11 | the [Dockerfile in this repo](Dockerfile). We'll build and push a new image when there's a new tag pushed into this 12 | repo. 13 | 14 | We maintain all versions of tools that we used in [version.env](version.env) file, if you'd like to build the docker image on your machine, please use the following command (need Linux and awk): 15 | 16 | ```shell 17 | bash dockerbuild.sh 18 | ``` 19 | 20 | ## Before you commit 21 | 22 | To sync versions between [version.env](version.env) and [.tflint.hcl](.tflint.hcl) and [.tflint_example.hcl](.tflint_example.hcl), we suggest you execute the following command before you commit changes: 23 | 24 | ```shell 25 | docker run --rm -v $(pwd):/src -w /src localrunner sh scaffold-ci-scripts/sync-tflint-plugin-version.sh 26 | ``` 27 | 28 | On Windows: 29 | ```shell 30 | docker run --rm -v ${pwd}:/src -w /src localrunner sh scaffold-ci-scripts/sync-tflint-plugin-version.sh 31 | ``` 32 | 33 | ## Tools We're Using Now 34 | 35 | | Name | Latest Version | 36 | |-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------| 37 | | [Go](https://github.com/golang/go) | ![](https://img.shields.io/github/v/tag/golang/go) | 38 | | [TFLint](https://github.com/terraform-linters/tflint) | ![](https://img.shields.io/github/v/tag/terraform-linters/tflint) | 39 | | [TFLint AzureRM Ruleset](https://github.com/terraform-linters/tflint-ruleset-azurerm) | ![](https://img.shields.io/github/v/tag/terraform-linters/tflint-ruleset-azurerm) | 40 | | [TFLint Basic Ruleset Extension](https://github.com/Azure/tflint-ruleset-basic-ext) | ![](https://img.shields.io/github/v/tag/Azure/tflint-ruleset-basic-ext) | 41 | | [TFLint AzureRM Ruleset Extension](https://github.com/Azure/tflint-ruleset-azurerm-ext) | ![](https://img.shields.io/github/v/tag/Azure/tflint-ruleset-azurerm-ext) | 42 | | [BridgeCrew Checkov](https://github.com/bridgecrewio/checkov) | ![](https://img.shields.io/github/v/tag/bridgecrewio/checkov) | 43 | | [HashiCorp Terraform](https://github.com/hashicorp/terraform) | ![](https://img.shields.io/github/v/tag/hashicorp/terraform) | 44 | | [GruntWork TerraGrunt](https://github.com/gruntwork-io/terragrunt) | ![](https://img.shields.io/github/v/tag/gruntwork-io/terragrunt) | 45 | | [Terraform Docs](https://github.com/terraform-docs/terraform-docs) | ![](https://img.shields.io/github/v/tag/terraform-docs/terraform-docs) | 46 | | [Golangci-lint](https://github.com/golangci/golangci-lint) | ![](https://img.shields.io/github/v/tag/golangci/golangci-lint) | 47 | | [Terraform Module Breaking Detect](https://github.com/Azure/terraform-module-test-helper) | ![](https://img.shields.io/github/v/tag/Azure/terraform-module-test-helper) | 48 | | [HCLEdit](https://github.com/minamijoyo/hcledit) | ![](https://img.shields.io/github/v/tag/minamijoyo/hcledit) | 49 | | [GoSec](https://github.com/securego/gosec) | ![](https://img.shields.io/github/v/tag/securego/gosec) | 50 | | [BridgeCrew Yor](https://github.com/bridgecrewio/yor) | ![](https://img.shields.io/github/v/tag/bridgecrewio/yor) | 51 | | [tfenv](https://github.com/tfutils/tfenv) | ![](https://img.shields.io/github/v/tag/tfutils/tfenv) | 52 | | [hclgrep](https://github.com/magodo/hclgrep) | ![](https://img.shields.io/github/v/tag/magodo/hclgrep) | 53 | | [avmfix](https://github.com/lonegunmanb/avmfix) | ![](https://img.shields.io/github/v/tag/lonegunmanb/avmfix) | 54 | | [hclgrep](https://github.com/lonegunmanb/yorbox) | ![](https://img.shields.io/github/v/tag/lonegunmanb/yorbox) | 55 | | [tfsec](https://github.com/aquasecurity/tfsec) | ![](https://img.shields.io/github/v/tag/aquasecurity/tfsec) | 56 | | [grept](https://github.com/Azure/grept) | ![](https://img.shields.io/github/v/tag/Azure/grept) | 57 | 58 | ## To Add CI Pipeline In New Azure Verified Terraform Module 59 | 60 | Create a new `GNUMakefile` in your module's folder: 61 | 62 | ```makefile 63 | SHELL := /bin/bash 64 | 65 | -include $(shell curl -sSL "https://raw.githubusercontent.com/Azure/tfmod-scaffold/main/scripts/install.sh" | bash -s > /dev/null ; echo tfmod-scaffold/GNUmakefile) 66 | 67 | init: 68 | @sh "$(CURDIR)/scripts/init.sh" 69 | 70 | cleanup: 71 | @sh "$(CURDIR)/scripts/cleanup.sh" 72 | ``` 73 | 74 | To init Github Action CI yaml files in your module, run: 75 | 76 | ```shell 77 | $ make init 78 | ``` 79 | -------------------------------------------------------------------------------- /avm_mapotf/pre_commit/avm_headers_for_azapi.mptf.hcl: -------------------------------------------------------------------------------- 1 | locals { 2 | avm_headers_for_azapi_enabled = strcontains(env("AVMSCRIPT_VERSION"), "canary") 3 | } 4 | 5 | data "variable" enable_telemetry { 6 | name = "enable_telemetry" 7 | } 8 | 9 | locals { 10 | var_dot_enable_telemetry_exists = try(data.variable.enable_telemetry.result["enable_telemetry"] != null, false) 11 | } 12 | 13 | transform "new_block" new_enable_telemetry_variable { 14 | for_each = local.avm_headers_for_azapi_enabled && !local.var_dot_enable_telemetry_exists ? toset([1]) : toset([]) 15 | new_block_type = "variable" 16 | labels = ["enable_telemetry"] 17 | filename = "variables.tf" 18 | asraw { 19 | type = bool 20 | default = true 21 | description = <. 24 | If it is set to false, then no telemetry will be collected. 25 | DESCRIPTION 26 | nullable = false 27 | } 28 | } 29 | 30 | transform "update_in_place" enable_telemetry_variable { 31 | for_each = local.avm_headers_for_azapi_enabled && local.var_dot_enable_telemetry_exists ? toset([1]) : toset([]) 32 | target_block_address = "variable.enable_telemetry" 33 | asraw { 34 | type = bool 35 | default = true 36 | description = <. 39 | If it is set to false, then no telemetry will be collected. 40 | DESCRIPTION 41 | nullable = false 42 | } 43 | depends_on = [ 44 | transform.new_block.new_enable_telemetry_variable 45 | ] 46 | } 47 | 48 | locals { 49 | azapi_resource_with_full_headers_types = toset([ 50 | "azapi_data_plane_resource", 51 | "azapi_resource", 52 | ]) 53 | } 54 | 55 | data "resource" "azapi_resources_with_full_headers" { 56 | for_each = local.azapi_resource_with_full_headers_types 57 | resource_type = each.key 58 | } 59 | 60 | data "resource" "azapi_update_resource" { 61 | resource_type = "azapi_update_resource" 62 | } 63 | 64 | locals { 65 | all_azapi_resources_with_full_headers = flatten([ 66 | for resource in data.resource.azapi_resources_with_full_headers : [ 67 | for result_set in resource.result : flatten([ 68 | for r in result_set : r 69 | ]) 70 | ] if local.avm_headers_for_azapi_enabled 71 | ]) 72 | all_azapi_resources_with_full_headers_map = { 73 | for r in local.all_azapi_resources_with_full_headers : r.mptf.block_address => r 74 | } 75 | azapi_update_resource_addresses = toset(try([ 76 | for _, resource in data.resource.azapi_update_resource.result["azapi_update_resource"] : resource.mptf.block_address 77 | ], [])) 78 | } 79 | 80 | locals { 81 | first_version_of_azapi_user_headers = "{ \"User-Agent\" : local.avm_azapi_header }" 82 | } 83 | 84 | transform "update_in_place" full_headers { 85 | for_each = local.all_azapi_resources_with_full_headers_map 86 | target_block_address = each.key 87 | asstring { 88 | create_headers = try(each.value.create_headers == local.first_version_of_azapi_user_headers, false) ? "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : ( 89 | try(strcontains(each.value.create_headers, "local.avm_azapi_header"), false) ? each.value.create_headers : ( 90 | try(each.value.create_headers == "", true) ? 91 | "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : 92 | "merge(${each.value.create_headers}, (var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : {}))" 93 | ) 94 | ) 95 | delete_headers = try(each.value.delete_headers == local.first_version_of_azapi_user_headers, false) ? "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : ( 96 | try(strcontains(each.value.delete_headers, "local.avm_azapi_header"), false) ? each.value.delete_headers : ( 97 | try(each.value.delete_headers == "", true) ? 98 | "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : 99 | "merge(${each.value.delete_headers}, (var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : {}))" 100 | ) 101 | ) 102 | read_headers = try(each.value.read_headers == local.first_version_of_azapi_user_headers, false) ? "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : ( 103 | try(strcontains(each.value.read_headers, "local.avm_azapi_header"), false) ? each.value.read_headers : ( 104 | try(each.value.read_headers == "", true) ? 105 | "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : 106 | "merge(${each.value.read_headers}, (var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : {}))" 107 | ) 108 | ) 109 | update_headers = try(each.value.update_headers == local.first_version_of_azapi_user_headers, false) ? "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : ( 110 | try(strcontains(each.value.update_headers, "local.avm_azapi_header"), false) ? each.value.update_headers : ( 111 | try(each.value.update_headers == "", true) ? 112 | "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : 113 | "merge(${each.value.update_headers}, (var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : {}))" 114 | ) 115 | ) 116 | } 117 | } 118 | 119 | transform "update_in_place" azapi_update_resource_headers { 120 | for_each = local.avm_headers_for_azapi_enabled ? local.azapi_update_resource_addresses : toset([]) 121 | target_block_address = each.value 122 | asstring { 123 | read_headers = try(each.value.read_headers == local.first_version_of_azapi_user_headers, false) ? "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : ( 124 | try(strcontains(each.value.read_headers, "local.avm_azapi_header"), false) ? each.value.read_headers : ( 125 | try(each.value.read_headers == "", true) ? 126 | "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : 127 | "merge(${each.value.read_headers}, (var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : {}))" 128 | ) 129 | ) 130 | update_headers = try(each.value.update_headers == local.first_version_of_azapi_user_headers, false) ? "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : ( 131 | try(strcontains(each.value.update_headers, "local.avm_azapi_header"), false) ? each.value.update_headers : ( 132 | try(each.value.update_headers == "", true) ? 133 | "var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : null" : 134 | "merge(${each.value.update_headers}, (var.enable_telemetry ? { \"User-Agent\" : local.avm_azapi_header } : {}))" 135 | ) 136 | ) 137 | } 138 | } -------------------------------------------------------------------------------- /avm_mapotf/pre_commit/main_telemetry_tf.mptf.hcl: -------------------------------------------------------------------------------- 1 | locals { 2 | sync_main_telemetry_tf = strcontains(env("AVMSCRIPT_VERSION"), "canary") 3 | } 4 | 5 | data "local" avm_azapi_header { 6 | name = "avm_azapi_header" 7 | } 8 | 9 | locals { 10 | avm_azapi_header_exists = try(data.local.avm_azapi_header.result["avm_azapi_header"] != null, false) 11 | azapi_headers_locals = { 12 | valid_module_source_regex = <<-EOT 13 | [ 14 | "registry.terraform.io/[A|a]zure/.+", 15 | "registry.opentofu.io/[A|a]zure/.+", 16 | "git::https://github\\.com/[A|a]zure/.+", 17 | "git::ssh:://git@github\\.com/[A|a]zure/.+", 18 | ] 19 | EOT 20 | fork_avm = "!anytrue([for r in local.valid_module_source_regex : can(regex(r, one(data.modtm_module_source.telemetry).module_source))])" 21 | avm_azapi_headers = <<-EOT 22 | !var.enable_telemetry ? {} : (local.fork_avm ? { 23 | fork_avm = "true" 24 | random_id = one(random_uuid.telemetry).result 25 | } : { 26 | avm = "true" 27 | random_id = one(random_uuid.telemetry).result 28 | avm_module_source = one(data.modtm_module_source.telemetry).module_source 29 | avm_module_version = one(data.modtm_module_source.telemetry).module_version 30 | }) 31 | EOT 32 | } 33 | avm_azapi_header = "join(\" \", [ for k, v in local.avm_azapi_headers : \"$${k}=$${v}\" ])" 34 | } 35 | 36 | transform "new_block" new_avm_azapi_header_local { 37 | for_each = local.sync_main_telemetry_tf && !local.avm_azapi_header_exists ? toset([1]) : toset([]) 38 | new_block_type = "locals" 39 | filename = "main.telemetry.tf" 40 | body = <<-EOT 41 | # tflint-ignore: terraform_unused_declarations 42 | avm_azapi_header = ${local.avm_azapi_header} 43 | EOT 44 | } 45 | 46 | transform "ensure_local" azapi_headers_helper_local { 47 | for_each = local.sync_main_telemetry_tf ? local.azapi_headers_locals : {} 48 | name = each.key 49 | fallback_file_name = "main.telemetry.tf" 50 | value_as_string = each.value 51 | } 52 | 53 | # We can declare tflint-ignore annotation only by using new_block, so we don't provision ensure_local if local.avm_azapi_headers is absent 54 | transform "ensure_local" azapi_headers_local { 55 | for_each = local.sync_main_telemetry_tf && local.avm_azapi_header_exists ? toset([1]) : toset([]) 56 | name = "avm_azapi_header" 57 | fallback_file_name = "main.telemetry.tf" 58 | value_as_string = local.avm_azapi_header 59 | } 60 | 61 | data "data" "azurerm_client_config" { 62 | data_source_type = "azurerm_client_config" 63 | } 64 | 65 | locals { 66 | data_azurerm_client_config_telemetry_exists = try(data.data.azurerm_client_config.result["azurerm_client_config"].telemetry.mptf != null, false) 67 | } 68 | 69 | transform "remove_block" azurerm_client_config { 70 | for_each = local.sync_main_telemetry_tf && local.data_azurerm_client_config_telemetry_exists ? toset([1]) : toset([]) 71 | target_block_address = "data.azurerm_client_config.telemetry" 72 | } 73 | 74 | data "data" "azapi_client_config" { 75 | data_source_type = "azapi_client_config" 76 | } 77 | 78 | locals { 79 | data_azapi_client_config_telemetry_exists = try(data.data.azapi_client_config.result["azapi_client_config"].telemetry.mptf != null, false) 80 | } 81 | 82 | transform "new_block" azapi_client_config { 83 | for_each = local.sync_main_telemetry_tf && !local.data_azapi_client_config_telemetry_exists ? toset([1]) : toset([]) 84 | new_block_type = "data" 85 | labels = ["azapi_client_config", "telemetry"] 86 | filename = "main.telemetry.tf" 87 | asraw { 88 | count = var.enable_telemetry ? 1 : 0 89 | } 90 | } 91 | 92 | transform "update_in_place" azapi_client_config { 93 | for_each = local.sync_main_telemetry_tf && local.data_azapi_client_config_telemetry_exists ? toset([1]) : toset([]) 94 | target_block_address = "data.azapi_client_config.telemetry" 95 | asraw { 96 | count = var.enable_telemetry ? 1 : 0 97 | } 98 | } 99 | 100 | data "data" modtm_module_source { 101 | data_source_type = "modtm_module_source" 102 | } 103 | 104 | transform "new_block" new_modtm_module_source { 105 | for_each = local.sync_main_telemetry_tf && try(data.data.modtm_module_source.result["modtm_module_source"].telemetry == null, true) ? toset([1]) : toset([]) 106 | new_block_type = "data" 107 | labels = ["modtm_module_source", "telemetry"] 108 | filename = "main.telemetry.tf" 109 | asraw { 110 | count = var.enable_telemetry ? 1 : 0 111 | module_path = path.module 112 | } 113 | } 114 | 115 | transform "update_in_place" modtm_module_source { 116 | for_each = local.sync_main_telemetry_tf && try(data.data.modtm_module_source.result["modtm_module_source"].telemetry != null, false) ? toset([1]) : toset([]) 117 | target_block_address = "data.modtm_module_source.telemetry" 118 | asraw { 119 | count = var.enable_telemetry ? 1 : 0 120 | module_path = path.module 121 | } 122 | depends_on = [ 123 | transform.new_block.new_modtm_module_source 124 | ] 125 | } 126 | 127 | data "resource" "random_uuid" { 128 | resource_type = "random_uuid" 129 | } 130 | 131 | transform "new_block" new_random_uuid { 132 | for_each = local.sync_main_telemetry_tf && try(data.resource.random_uuid.result["random_uuid"].telemetry == null, true) ? toset([1]) : toset([]) 133 | new_block_type = "resource" 134 | labels = ["random_uuid", "telemetry"] 135 | filename = "main.telemetry.tf" 136 | asraw { 137 | count = var.enable_telemetry ? 1 : 0 138 | } 139 | } 140 | 141 | transform "update_in_place" random_uuid { 142 | for_each = local.sync_main_telemetry_tf && try(data.resource.random_uuid.result["random_uuid"].telemetry != null, false) ? toset([1]) : toset([]) 143 | target_block_address = "resource.random_uuid.telemetry" 144 | asraw { 145 | count = var.enable_telemetry ? 1 : 0 146 | } 147 | depends_on = [ 148 | transform.new_block.new_random_uuid 149 | ] 150 | } 151 | 152 | data "resource" "modtm_telemetry_telemetry" { 153 | resource_type = "modtm_telemetry" 154 | } 155 | 156 | data "variable" location { 157 | name = "location" 158 | type = "string" 159 | } 160 | 161 | data "resource" "modtm_telemetry" { 162 | resource_type = "modtm_telemetry" 163 | } 164 | 165 | data "local" "main_location" { 166 | name = "main_location" 167 | } 168 | 169 | locals { 170 | location_variable_exist = length(data.variable.location.result) == 1 171 | local_dot_main_location_exist = length(data.local.main_location.result) == 1 172 | resource_modtm_telemetry_telemetry_exists = try(data.resource.modtm_telemetry_telemetry.result["modtm_telemetry"].telemetry.mptf != null, false) 173 | } 174 | 175 | transform "ensure_local" main_location { 176 | for_each = local.sync_main_telemetry_tf && !local.local_dot_main_location_exist ? toset([1]) : toset([]) 177 | name = "main_location" 178 | fallback_file_name = "main.telemetry.tf" 179 | value_as_string = local.location_variable_exist ? "var.location" : "\"unknown\"" 180 | } 181 | 182 | transform "new_block" new_modtm_telemetry_telemetry { 183 | for_each = local.sync_main_telemetry_tf && !local.resource_modtm_telemetry_telemetry_exists ? toset([1]) : toset([]) 184 | new_block_type = "resource" 185 | labels = ["modtm_telemetry", "telemetry"] 186 | filename = "main.telemetry.tf" 187 | asstring { 188 | count = "var.enable_telemetry ? 1 : 0" 189 | 190 | tags = <<-EOT 191 | merge({ 192 | subscription_id = one(data.azapi_client_config.telemetry).subscription_id 193 | tenant_id = one(data.azapi_client_config.telemetry).tenant_id 194 | module_source = one(data.modtm_module_source.telemetry).module_source 195 | module_version = one(data.modtm_module_source.telemetry).module_version 196 | random_id = one(random_uuid.telemetry).result 197 | }, { location = local.main_location }) 198 | EOT 199 | } 200 | } 201 | 202 | transform "update_in_place" modtm_telemetry_telemetry { 203 | for_each = local.sync_main_telemetry_tf && local.resource_modtm_telemetry_telemetry_exists ? toset([1]) : toset([]) 204 | target_block_address = "resource.modtm_telemetry.telemetry" 205 | asstring { 206 | count = "var.enable_telemetry ? 1 : 0" 207 | 208 | tags = <<-EOT 209 | merge({ 210 | subscription_id = one(data.azapi_client_config.telemetry).subscription_id 211 | tenant_id = one(data.azapi_client_config.telemetry).tenant_id 212 | module_source = one(data.modtm_module_source.telemetry).module_source 213 | module_version = one(data.modtm_module_source.telemetry).module_version 214 | random_id = one(random_uuid.telemetry).result 215 | }, { location = local.main_location }) 216 | EOT 217 | } 218 | } -------------------------------------------------------------------------------- /.tflint.hcl: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS GENERATED BY TFMOD-SCAFFOLD, PLEASE DO NOT MODIFY IT. 3 | IF YOU WANT TO USE A CUSTOMIZED CONFIGURATION, PLEASE CREATE YOUR OWN AND 4 | SET THIS FILE'S PATH TO $TFLINT_CONFIG ENVVIRONMENT VARIABLE. 5 | */ 6 | plugin "basic-ext" { 7 | enabled = true 8 | version = "0.6.0" 9 | source = "github.com/Azure/tflint-ruleset-basic-ext" 10 | signing_key = <<-KEY 11 | -----BEGIN PGP PUBLIC KEY BLOCK----- 12 | 13 | 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 60 | =nfI3 61 | -----END PGP PUBLIC KEY BLOCK----- 62 | KEY 63 | } 64 | 65 | plugin "azurerm-ext" { 66 | enabled = true 67 | version = "0.6.0" 68 | source = "github.com/Azure/tflint-ruleset-azurerm-ext" 69 | signing_key = <<-KEY 70 | -----BEGIN PGP PUBLIC KEY BLOCK----- 71 | 72 | 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 119 | =nfI3 120 | -----END PGP PUBLIC KEY BLOCK----- 121 | KEY 122 | } 123 | 124 | rule "terraform_comment_syntax" { 125 | enabled = true 126 | } 127 | 128 | rule "terraform_deprecated_index" { 129 | enabled = true 130 | } 131 | 132 | rule "terraform_deprecated_interpolation" { 133 | enabled = true 134 | } 135 | 136 | rule "terraform_documented_outputs" { 137 | enabled = true 138 | } 139 | 140 | rule "terraform_documented_variables" { 141 | enabled = true 142 | } 143 | 144 | rule "terraform_empty_list_equality" { 145 | enabled = true 146 | } 147 | 148 | rule "terraform_module_pinned_source" { 149 | enabled = true 150 | } 151 | 152 | rule "terraform_module_version" { 153 | enabled = true 154 | } 155 | 156 | rule "terraform_naming_convention" { 157 | enabled = true 158 | } 159 | 160 | rule "terraform_required_providers" { 161 | enabled = true 162 | } 163 | 164 | rule "terraform_required_version" { 165 | enabled = true 166 | } 167 | 168 | rule "terraform_standard_module_structure" { 169 | enabled = true 170 | } 171 | 172 | rule "terraform_typed_variables" { 173 | enabled = true 174 | } 175 | 176 | rule "terraform_unused_declarations" { 177 | enabled = true 178 | } 179 | 180 | rule "terraform_unused_required_providers" { 181 | enabled = true 182 | } 183 | 184 | rule "terraform_workspace_remote" { 185 | enabled = true 186 | } 187 | 188 | rule "terraform_locals_order" { 189 | enabled = false 190 | } 191 | 192 | rule "terraform_output_order" { 193 | enabled = false 194 | } 195 | 196 | rule "terraform_output_separate" { 197 | enabled = false 198 | } 199 | 200 | rule "terraform_variable_nullable_false" { 201 | enabled = false 202 | } 203 | 204 | rule "terraform_variable_order" { 205 | enabled = false 206 | } 207 | 208 | rule "terraform_variable_separate" { 209 | enabled = false 210 | } 211 | 212 | rule "terraform_resource_data_arg_layout" { 213 | enabled = false 214 | } 215 | 216 | rule "azurerm_arg_order" { 217 | enabled = false 218 | } 219 | 220 | rule "azurerm_resource_tag" { 221 | enabled = true 222 | } 223 | 224 | rule "terraform_count_index_usage" { 225 | enabled = false 226 | } 227 | 228 | rule "terraform_heredoc_usage" { 229 | enabled = true 230 | } 231 | 232 | rule "terraform_module_provider_declaration" { 233 | enabled = true 234 | } 235 | 236 | rule "terraform_required_providers_declaration" { 237 | enabled = true 238 | } 239 | 240 | rule "terraform_required_version_declaration" { 241 | enabled = true 242 | } 243 | 244 | rule "terraform_sensitive_variable_no_default" { 245 | enabled = false 246 | } 247 | 248 | rule "terraform_versions_file" { 249 | enabled = true 250 | } -------------------------------------------------------------------------------- /.tflint_module.hcl: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS GENERATED BY TFMOD-SCAFFOLD, PLEASE DO NOT MODIFY IT. 3 | IF YOU WANT TO USE A CUSTOMIZED CONFIGURATION, PLEASE CREATE YOUR OWN AND 4 | SET THIS FILE'S PATH TO $TFLINT_CONFIG ENVVIRONMENT VARIABLE. 5 | */ 6 | plugin "basic-ext" { 7 | enabled = true 8 | version = "0.6.0" 9 | source = "github.com/Azure/tflint-ruleset-basic-ext" 10 | signing_key = <<-KEY 11 | -----BEGIN PGP PUBLIC KEY BLOCK----- 12 | 13 | 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 60 | =nfI3 61 | -----END PGP PUBLIC KEY BLOCK----- 62 | KEY 63 | } 64 | 65 | plugin "azurerm-ext" { 66 | enabled = true 67 | version = "0.6.0" 68 | source = "github.com/Azure/tflint-ruleset-azurerm-ext" 69 | signing_key = <<-KEY 70 | -----BEGIN PGP PUBLIC KEY BLOCK----- 71 | 72 | mQINBGNjIIoBEACni6mzvCfY14cicqnW+BjFCoTUM95nxUINDFEQ7wkxGWmufAvQ 73 | iEUDrv6iVNCEfk1cU2jGSWUlBu6hTZ9auOy8K2MrMhtdqYVx+mY1SS+fVYHzSQAC 74 | C3qBTBY+TmDHl0QMQjF884AsYE2WTcZI3e1DOXXkVKlOMERzT7IQMVbeuiVklwLj 75 | BA/sQISaZVesaWPWN8WtRb8iOrq4i5HHqnAWRZGtqMEsoNBWqzjqh1aoQ7Ex3ldH 76 | 2Ey1bEIi05PWr67k1QOU9pXhMNuC+NXCQDO1sEq/NG376v2GbgylVapUlWAq35tw 77 | Ut8SFfiDM+GyHN1nNNjBKhOB7774yqh6FrPIfh/2WvN1EhAbPkr9eWfHROyIPWj1 78 | t+IBFlMFbvMHLeMrlSZAkqlLljEZHdfzBfEXGUYKOOz/aeR+XjeMxGX977VoMk/0 79 | uzLQPoVMqjOrAY4Iq+XhW6w4aBihDqkot3TDH6Cyczl+N9We0QatWd5jAG+BTb22 80 | 7AevzSlDKh/+oUAec6iG/WF4MjJB3c1Fdpkw4rtTjha6zKrFHNvpDzuyvJEnO9Pt 81 | eBRAWaQvkqfMccQMYsasHWYkZKH2U8RAsqgW8iF9aRktBdGPao+ztkblbj/c7dUz 82 | L4J28SmivzDJAzoAANjiC2R6xLBOb6b+TyafFmgevepwgN1QG5bPY3MptwARAQAB 83 | tB9oZXppamllIDxoZXppamllQG1pY3Jvc29mdC5jb20+iQJOBBMBCgA4FiEEE0LC 84 | 37JNq10/9GosWbcR7NOMOjwFAmNjIIoCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgEC 85 | F4AACgkQWbcR7NOMOjxtdQ//TUh2/GmF+4TF2qLgRgHKaH8pL8cUaCgYdUNlrK7B 86 | 8OXBKIxrnNs8FXUSsgyKHMjAdg0EdSgJt+w9nOgZEtLPTOE+e3RKgmmsMc9vn/qq 87 | qoOw8B6NxRIJsGp8YbemoDUnmrUK93TSRxINBup4y413ZoON7g8O7I8kQBz4Ra6E 88 | 6U+Yx5rstFeS5D5jzWYeoh9Y6g9zucEDe3qnS8LcPmhj95mrm7A4uNwMDmny/J7B 89 | I3sVILAybp8D8/PSSixjGsCr+81marKlkHxqaSL8dpR2tr2Z1lcm2gS4z81NXlx4 90 | vh79cvpX8hedysssl8FpV3SzxYFlgWNP97vM9AAv00fBOR4lid3ZNoRCQdfw7LeT 91 | GrglCWmMZ3Pm8JClYTbcsQ5wg5JgPFU9Rht+QN/EoNfJ5RipYYYwE9AOSJ6eJxHB 92 | QH9pM1b+dZ6dYLqReeGUlZ0pYBoLC+LpqknxlPQzUuPl5VbbL2TsFIVy5n963gAk 93 | 5vEnRJgUFx+agI6ZPw+SnXRjwgqvuasgE8Z6wwbXWnSZf1kbJr4sv5alN/u1Uyph 94 | CYl3uuHJkm0D/YfH4b83Bq7saTXWmJib7AR4piB8Z81vpO+Nq3zcvX1Z3r0AlF4j 95 | t0KDU/cix305ldEITT7EJAxkxI71XCTgdt78h/e2N1gLatsv8I98ShK/U6Jxb0kx 96 | pLC5Ag0EY2MgigEQAJJgnoe58UiuSFJIxPY6g4djYrWm7R9gw8oCdWJhjT9ou+bD 97 | HYIY0RaaXuUsBaA/logdO87MeiIyPirypPhpSHN1c6CXBfLyspO606su8AKS+DK3 98 | lTzExtU8c5lwP0KnDDugs/qbjpntrXCCUmxTF2RDMFbkbaAt9vl671+kggXvOfe/ 99 | iJFXjWXfBx/nKeMkHmXo6qpizurqe0CYdlOW2w7UXjeX8snuOz7kFK3PhEHJ8CKA 100 | UEwqQaEp8v5zbAWGzRzPbY3Djw1RHw/WT6gEZWPQYK0HP6VdwIVJhpp8RKUe3QHJ 101 | cG/hUJrEdbLOZrBe5NZCP5RStJ3XL4aAVS0nu/18nB1vf7pYq6VaywEM9n5PuLWr 102 | mdtvUMTaDLjLM9H24qU8wHbiy+3jMGIUz5sKKIkBN8VxGacHo7Aadk7npGwiLpPD 103 | VV0L5eapSCgf1Nja7ZDnzgzlcztg7eBV7r+tRBsgtWiFlDu00NZCowGfxeaWc7TZ 104 | 08JweBe4VDpUZZLiA/J2ET0/qAfDtTLtLbMrcgFuIZi0f05FG0qtW5SuVVuYGfdE 105 | F7rUYFC5F39GxiDElR9F4XQcfhhtzAwVe9cYquPEkFBovzwhcVyJ3sfvupbk2nTN 106 | koBjcs0n5C1b3YiaYeGM06hAXD0OTnl0Pbx1qMXTNs3DLCUoraU6tAwSvU4LABEB 107 | AAGJAjYEGAEKACAWIQQTQsLfsk2rXT/0aixZtxHs04w6PAUCY2MgigIbDAAKCRBZ 108 | txHs04w6POmfD/9GJ5sxWnwv8wzU46K4pK/Ie6AVCVIPgtqGIvifHwz4VM9VGIyb 109 | oFTlRjow+i1z/8hb3tqdaJZvHkAv6jTPX6N3UiZ9l81LOqBJsx+vBHOSKAIRlgqX 110 | jZ97N5y2H62BmBLqJxqA+C/8JhgrTiNB6pNAwet2mBgXCt2GDgy9UVgJ0Y/wJ2lk 111 | E5LZOilxqd7P+qCruaCPyjyNkMTU9b3C2qR46Ip1GWc//UWwmLKCYsF+eVUst9Mk 112 | O4QVJTj1B51mCXgrhg0ei8lNzXHw79W2MpEG6+HRUzyJqGylxh8B4BKwvGEr6PkC 113 | QN8QE7kGhxLNXPNjAyM15lWOckR0nPkwV5zV+gpw+R5grOgnBcMIhoMkUKiFqnbd 114 | km5bxwF00OL/QqocAvOUY44G1WtsigAeNu3OM3ki1j6VVAOlwljQ8OSdLuVM3vsU 115 | Q2i0lo99PuDaAjTxCFPx7+/TsL5vL21zGvVpkWvXsfVLFvjo2bTs5Yc78MGF4IZN 116 | o4QUqU7MGkjT7r8rFSPwFkAny0vUkp5iAKKaQFSvi5j1SNExtSeWk+cfjHwrH9l5 117 | U6WDcghw5dibCpCUg5Eh0pbVe/Wdql3Y63Urk35fFAtGGpHozoVpoWFg6+n5HVlo 118 | 1DSrn+zuuxMp02sV+9MfqnT8Gq3fbU1mlTmqALKWa71w1dAv/M1kdjgA5w== 119 | =nfI3 120 | -----END PGP PUBLIC KEY BLOCK----- 121 | KEY 122 | } 123 | 124 | rule "terraform_comment_syntax" { 125 | enabled = true 126 | } 127 | 128 | rule "terraform_deprecated_index" { 129 | enabled = true 130 | } 131 | 132 | rule "terraform_deprecated_interpolation" { 133 | enabled = true 134 | } 135 | 136 | rule "terraform_documented_outputs" { 137 | enabled = true 138 | } 139 | 140 | rule "terraform_documented_variables" { 141 | enabled = true 142 | } 143 | 144 | rule "terraform_empty_list_equality" { 145 | enabled = true 146 | } 147 | 148 | rule "terraform_module_pinned_source" { 149 | enabled = true 150 | } 151 | 152 | rule "terraform_module_version" { 153 | enabled = true 154 | } 155 | 156 | rule "terraform_naming_convention" { 157 | enabled = true 158 | } 159 | 160 | rule "terraform_required_providers" { 161 | enabled = true 162 | } 163 | 164 | rule "terraform_required_version" { 165 | enabled = true 166 | } 167 | 168 | rule "terraform_standard_module_structure" { 169 | enabled = true 170 | } 171 | 172 | rule "terraform_typed_variables" { 173 | enabled = true 174 | } 175 | 176 | rule "terraform_unused_declarations" { 177 | enabled = true 178 | } 179 | 180 | rule "terraform_unused_required_providers" { 181 | enabled = true 182 | } 183 | 184 | rule "terraform_workspace_remote" { 185 | enabled = true 186 | } 187 | 188 | rule "terraform_locals_order" { 189 | enabled = false 190 | } 191 | 192 | rule "terraform_output_order" { 193 | enabled = false 194 | } 195 | 196 | rule "terraform_output_separate" { 197 | enabled = false 198 | } 199 | 200 | rule "terraform_variable_nullable_false" { 201 | enabled = false 202 | } 203 | 204 | rule "terraform_variable_order" { 205 | enabled = false 206 | } 207 | 208 | rule "terraform_variable_separate" { 209 | enabled = false 210 | } 211 | 212 | rule "terraform_resource_data_arg_layout" { 213 | enabled = false 214 | } 215 | 216 | rule "azurerm_arg_order" { 217 | enabled = false 218 | } 219 | 220 | rule "azurerm_resource_tag" { 221 | enabled = true 222 | } 223 | 224 | rule "terraform_count_index_usage" { 225 | enabled = false 226 | } 227 | 228 | rule "terraform_heredoc_usage" { 229 | enabled = true 230 | } 231 | 232 | rule "terraform_module_provider_declaration" { 233 | enabled = true 234 | } 235 | 236 | rule "terraform_required_providers_declaration" { 237 | enabled = true 238 | } 239 | 240 | rule "terraform_required_version_declaration" { 241 | enabled = true 242 | } 243 | 244 | rule "terraform_sensitive_variable_no_default" { 245 | enabled = false 246 | } 247 | 248 | rule "terraform_versions_file" { 249 | enabled = true 250 | } -------------------------------------------------------------------------------- /.tflint_example.hcl: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS GENERATED BY TFMOD-SCAFFOLD, PLEASE DO NOT MODIFY IT. 3 | IF YOU WANT TO USE A CUSTOMIZED CONFIGURATION, PLEASE CREATE YOUR OWN AND 4 | SET THIS FILE'S PATH TO $TFLINT_CONFIG ENVVIRONMENT VARIABLE. 5 | */ 6 | 7 | plugin "basic-ext" { 8 | enabled = true 9 | version = "0.6.0" 10 | source = "github.com/Azure/tflint-ruleset-basic-ext" 11 | signing_key = <<-KEY 12 | -----BEGIN PGP PUBLIC KEY BLOCK----- 13 | 14 | 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 61 | =nfI3 62 | -----END PGP PUBLIC KEY BLOCK----- 63 | KEY 64 | } 65 | 66 | plugin "azurerm-ext" { 67 | enabled = true 68 | version = "0.6.0" 69 | source = "github.com/Azure/tflint-ruleset-azurerm-ext" 70 | signing_key = <<-KEY 71 | -----BEGIN PGP PUBLIC KEY BLOCK----- 72 | 73 | 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 120 | =nfI3 121 | -----END PGP PUBLIC KEY BLOCK----- 122 | KEY 123 | } 124 | 125 | rule "terraform_comment_syntax" { 126 | enabled = true 127 | } 128 | 129 | rule "terraform_deprecated_index" { 130 | enabled = true 131 | } 132 | 133 | rule "terraform_deprecated_interpolation" { 134 | enabled = true 135 | } 136 | 137 | rule "terraform_documented_outputs" { 138 | enabled = false 139 | } 140 | 141 | rule "terraform_documented_variables" { 142 | enabled = false 143 | } 144 | 145 | rule "terraform_empty_list_equality" { 146 | enabled = true 147 | } 148 | 149 | rule "terraform_module_pinned_source" { 150 | enabled = true 151 | } 152 | 153 | rule "terraform_module_version" { 154 | enabled = true 155 | } 156 | 157 | rule "terraform_naming_convention" { 158 | enabled = true 159 | } 160 | 161 | rule "terraform_required_providers" { 162 | enabled = true 163 | } 164 | 165 | rule "terraform_required_version" { 166 | enabled = true 167 | } 168 | 169 | rule "terraform_standard_module_structure" { 170 | enabled = false 171 | } 172 | 173 | rule "terraform_typed_variables" { 174 | enabled = false 175 | } 176 | 177 | rule "terraform_unused_declarations" { 178 | enabled = true 179 | } 180 | 181 | rule "terraform_unused_required_providers" { 182 | enabled = true 183 | } 184 | 185 | rule "terraform_workspace_remote" { 186 | enabled = true 187 | } 188 | 189 | rule "terraform_locals_order" { 190 | enabled = false 191 | } 192 | 193 | rule "terraform_output_order" { 194 | enabled = false 195 | } 196 | 197 | rule "terraform_output_separate" { 198 | enabled = false 199 | } 200 | 201 | rule "terraform_variable_nullable_false" { 202 | enabled = false 203 | } 204 | 205 | rule "terraform_variable_order" { 206 | enabled = false 207 | } 208 | 209 | rule "terraform_variable_separate" { 210 | enabled = false 211 | } 212 | 213 | rule "terraform_resource_data_arg_layout" { 214 | enabled = false 215 | } 216 | 217 | rule "azurerm_arg_order" { 218 | enabled = false 219 | } 220 | 221 | rule "azurerm_resource_tag" { 222 | enabled = false 223 | } 224 | 225 | rule "terraform_count_index_usage" { 226 | enabled = false 227 | } 228 | 229 | rule "terraform_heredoc_usage" { 230 | enabled = true 231 | } 232 | 233 | rule "terraform_module_provider_declaration" { 234 | enabled = false 235 | } 236 | 237 | rule "terraform_required_providers_declaration" { 238 | enabled = true 239 | } 240 | 241 | rule "terraform_required_version_declaration" { 242 | enabled = true 243 | } 244 | 245 | rule "terraform_sensitive_variable_no_default" { 246 | enabled = false 247 | } 248 | 249 | rule "terraform_versions_file" { 250 | enabled = true 251 | } --------------------------------------------------------------------------------