From f68ec906acbe9676caf7ad495efb2a1347fd6ebf Mon Sep 17 00:00:00 2001 From: Francesco Cesareo Date: Wed, 4 Oct 2023 13:22:49 +0200 Subject: [PATCH] gh action --- .devops/deploy-pipelines.yml | 205 --------------- .../workflows/{anchore.yml => 00_anchore.yml} | 0 .../{assignee.yml => 01_assignee.yml} | 0 .github/workflows/02_check_pr.yml | 191 ++++++++++++++ .github/workflows/03_code_review.yml | 83 ++++++ .github/workflows/04_release_deploy.yml | 241 ++++++++++++++++++ .github/workflows/04_self_hosted.yml | 85 ++++++ .github/workflows/check_metadata_pr.yml | 35 --- .github/workflows/deploy.yml | 58 ----- .github/workflows/sonar_analysis.yml | 28 -- .identity/.terraform.lock.hcl | 83 ++++++ .identity/00_data.tf | 42 +++ .identity/02_application_action.tf | 90 +++++++ .identity/03_github_environment.tf | 98 +++++++ .identity/99_main.tf | 32 +++ .identity/99_variables.tf | 56 ++++ .identity/README.md | 59 +++++ .identity/env/dev/backend.ini | 1 + .identity/env/dev/backend.tfvars | 4 + .identity/env/dev/terraform.tfvars | 11 + .identity/env/prod/backend.ini | 1 + .identity/env/prod/backend.tfvars | 4 + .identity/env/prod/terraform.tfvars | 11 + .identity/env/uat/backend.ini | 1 + .identity/env/uat/backend.tfvars | 4 + .identity/env/uat/terraform.tfvars | 11 + .identity/terraform.sh | 69 +++++ 27 files changed, 1177 insertions(+), 326 deletions(-) delete mode 100644 .devops/deploy-pipelines.yml rename .github/workflows/{anchore.yml => 00_anchore.yml} (100%) rename .github/workflows/{assignee.yml => 01_assignee.yml} (100%) create mode 100644 .github/workflows/02_check_pr.yml create mode 100644 .github/workflows/03_code_review.yml create mode 100644 .github/workflows/04_release_deploy.yml create mode 100644 .github/workflows/04_self_hosted.yml delete mode 100644 .github/workflows/check_metadata_pr.yml delete mode 100644 .github/workflows/deploy.yml delete mode 100644 .github/workflows/sonar_analysis.yml create mode 100644 .identity/.terraform.lock.hcl create mode 100644 .identity/00_data.tf create mode 100644 .identity/02_application_action.tf create mode 100644 .identity/03_github_environment.tf create mode 100644 .identity/99_main.tf create mode 100644 .identity/99_variables.tf create mode 100644 .identity/README.md create mode 100644 .identity/env/dev/backend.ini create mode 100644 .identity/env/dev/backend.tfvars create mode 100644 .identity/env/dev/terraform.tfvars create mode 100644 .identity/env/prod/backend.ini create mode 100644 .identity/env/prod/backend.tfvars create mode 100644 .identity/env/prod/terraform.tfvars create mode 100644 .identity/env/uat/backend.ini create mode 100644 .identity/env/uat/backend.tfvars create mode 100644 .identity/env/uat/terraform.tfvars create mode 100755 .identity/terraform.sh diff --git a/.devops/deploy-pipelines.yml b/.devops/deploy-pipelines.yml deleted file mode 100644 index 00d9864..0000000 --- a/.devops/deploy-pipelines.yml +++ /dev/null @@ -1,205 +0,0 @@ -parameters: - - name: ENV - displayName: Target Environment - type: string - default: dev - values: - - dev - - uat - - prod - - name: SEMVER - displayName: "When packing a release, define the version bump to apply. Use only buildNumber or skip for manual deployment" - type: string - values: - - major - - minor - - patch - - buildNumber - - skip - default: skip - - name: TEST - displayName: Run tests - type: boolean - default: false - - name: "FORCE_REPLACE_DOCKER_IMAGE" - displayName: "Force the existing docker image to be replaced" - type: boolean - default: False - values: - - False - - True - -variables: - imageRepository: '$(IMAGE_REPOSITORY_NAME)' - - ${{ if eq(parameters['ENV'], 'dev') }}: - AZURE_SUBSCRIPTION: $(DEV_AZURE_SUBSCRIPTION) - APP_NAME: $(DEV_WEB_APP_NAME) - STAGE: "d" - RESOURCE_GROUP: 'pagopa-d-weu-shared-txnm-rg' - dockerRegistryServiceConnection: $(DEV_CONTAINER_REGISTRY_SERVICE_CONN) - dockerNamespace: $(DEV_CONTAINER_NAMESPACE) - ${{ if eq(parameters['ENV'], 'uat') }}: - AZURE_SUBSCRIPTION: $(UAT_AZURE_SUBSCRIPTION) - APP_NAME: $(UAT_WEB_APP_NAME) - STAGE: "u" - RESOURCE_GROUP: 'pagopa-u-weu-shared-txnm-rg' - dockerRegistryServiceConnection: $(UAT_CONTAINER_REGISTRY_SERVICE_CONN) - dockerNamespace: $(UAT_CONTAINER_NAMESPACE) - ${{ if eq(parameters['ENV'], 'prod') }}: - AZURE_SUBSCRIPTION: $(PROD_AZURE_SUBSCRIPTION) - APP_NAME: $(PROD_WEB_APP_NAME) - STAGE: "p" - RESOURCE_GROUP: 'pagopa-p-weu-shared-txnm-rg' - dockerRegistryServiceConnection: $(PROD_CONTAINER_REGISTRY_SERVICE_CONN) - dockerNamespace: $(PROD_CONTAINER_NAMESPACE) - - ${{ if eq(variables['Build.SourceBranchName'], 'merge') }}: - SOURCE_BRANCH: "main" # force to main branch - ${{ if ne(variables['Build.SourceBranchName'], 'merge') }}: - SOURCE_BRANCH: ${{ variables['Build.SourceBranchName'] }} - - MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository - MAVEN_OPTS: "-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)" - title: "" - sha: "" - tag: "" - -# Only manual triggers -trigger: none -pr: none - -pool: - vmImage: ubuntu-latest - -resources: - repositories: - - repository: pagopaCommons - type: github - name: pagopa/azure-pipeline-templates - ref: refs/tags/v2.10.1 - endpoint: 'io-azure-devops-github-ro' - -stages: - - # Create a release on GitHub - - stage: Release - jobs: - - job: make_release - steps: - - checkout: self - clean: true - persistCredentials: true - - - ${{ if ne(parameters.SEMVER, 'skip') }}: - - template: templates/maven-github-release/template.yaml@pagopaCommons - parameters: - release_branch: $(SOURCE_BRANCH) - gitEmail: $(GIT_EMAIL) - gitUsername: $(GIT_USERNAME) - gitHubConnection: $(GITHUB_CONNECTION) - ${{ if ne(parameters.SEMVER, 'skip') }}: - semver: '${{ parameters.SEMVER }}' - ${{ if eq(parameters.SEMVER, 'skip') }}: - semver: 'buildNumber' # this case is impossible due to main condition, but it is necessary to work property - - - template: templates/maven-github-current-version/template.yaml@pagopaCommons - - # Build and Push Docker Image - - stage: Build - dependsOn: Release - variables: - current_version: $[ stageDependencies.Release.make_release.outputs['current_version.value'] ] - jobs: - - job: "build" - steps: - - checkout: self - persistCredentials: true - - #- script: | - # git checkout $(sourceBranch) - - - task: Maven@3 - inputs: - mavenPomFile: 'pom.xml' - publishJUnitResults: false - javaHomeOption: 'JDKVersion' - jdkVersionOption: '1.11' - mavenVersionOption: 'Default' - mavenOptions: '-Xmx3072m $(MAVEN_OPTS)' - mavenAuthenticateFeed: false - effectivePomSkip: false - sonarQubeRunAnalysis: false - - - template: templates/docker-release/template.yaml@pagopaCommons - parameters: - CONTAINER_REGISTRY_SERVICE_CONN: $(dockerRegistryServiceConnection) - CONTAINER_REGISTRY_FQDN: $(dockerNamespace) - DOCKER_IMAGE_NAME: $(imageRepository) - DOCKER_IMAGE_TAG: $(current_version) - FORCE_REPLACE_DOCKER_IMAGE: ${{ parameters.FORCE_REPLACE_DOCKER_IMAGE }} - - # Deploy on Azure - - stage: deploy - variables: - current_version: $[ stageDependencies.Release.make_release.outputs['current_version.value'] ] - condition: not(failed('releaseService')) - pool: - vmImage: "ubuntu-latest" - jobs: - - job: deployJava - steps: - # deploy fn - - task: AzureFunctionAppContainer@1 - displayName: Deploy Function App [DEV|UAT] - condition: in('${{ parameters.ENV }}', 'dev', 'uat') - inputs: - azureSubscription: $(AZURE_SUBSCRIPTION) - appName: "${{variables.APP_NAME}}-shared-txnm-fn" - imageName: "${{variables.dockerNamespace}}/${{ variables.imageRepository }}:latest" - slotName: production - resourceGroupName: $(RESOURCE_GROUP) - - task: AzureFunctionAppContainer@1 - displayName: Deploy Function App [PROD] staging - condition: eq('${{ parameters.ENV }}', 'prod') - inputs: - azureSubscription: $(AZURE_SUBSCRIPTION) - appName: "${{variables.APP_NAME}}-shared-txnm-fn" - imageName: "${{variables.dockerNamespace}}/${{ variables.imageRepository }}:latest" - deployToSlotOrASE: true - slotName: staging - resourceGroupName: $(RESOURCE_GROUP) - - - script: | - echo "##vso[task.setvariable variable=version;isOutput=true]$(pomversion.next)" - name: dockerTag - - stage: deployApprovalPROD - condition: eq('${{ parameters.ENV }}', 'prod') - dependsOn: deploy - pool: - vmImage: "ubuntu-latest" - jobs: - - job: waitForApprovalPROD - displayName: waiting for approval - pool: server - timeoutInMinutes: 4320 # 3 days - steps: - - task: ManualValidation@0 - displayName: Manual Approval - inputs: - onTimeout: "reject" - - - job: completeProdDeployFn - displayName: complete prod function deploy - dependsOn: waitForApprovalPROD - steps: - # deploy functions - swap - - task: AzureAppServiceManage@0 - displayName: Swapping App Service Deploy - inputs: - ConnectedServiceName: $(AZURE_SUBSCRIPTION) - WebAppName: "${{variables.APP_NAME}}-shared-txnm-fn" - ResourceGroupName: $(RESOURCE_GROUP) - SourceSlot: staging - SwapWithProduction: true - Slot: production diff --git a/.github/workflows/anchore.yml b/.github/workflows/00_anchore.yml similarity index 100% rename from .github/workflows/anchore.yml rename to .github/workflows/00_anchore.yml diff --git a/.github/workflows/assignee.yml b/.github/workflows/01_assignee.yml similarity index 100% rename from .github/workflows/assignee.yml rename to .github/workflows/01_assignee.yml diff --git a/.github/workflows/02_check_pr.yml b/.github/workflows/02_check_pr.yml new file mode 100644 index 0000000..0763155 --- /dev/null +++ b/.github/workflows/02_check_pr.yml @@ -0,0 +1,191 @@ +name: Check PR + +# Controls when the workflow will run +on: + pull_request: + branches: + - main + types: [ opened, synchronize, labeled, unlabeled, reopened, edited ] + + +permissions: + pull-requests: write + + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + auto_assign: + name: Auto Assign + + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: Assign Me + # You may pin to the exact commit or the version. + uses: kentaro-m/auto-assign-action@v1.2.1 + with: + configuration-path: '.github/auto_assign.yml' + + check_format: + name: Check Format + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Formatting + id: format + continue-on-error: true + uses: findologic/intellij-format-action@main + with: + path: . + fail-on-changes: false + + - uses: actions/github-script@v6.3.3 + if: steps.format.outcome != 'success' + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + console.log(context); + var comments = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + for (const comment of comments.data) { + console.log(comment); + if (comment.body.includes('Comment this PR with')){ + github.rest.issues.deleteComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }) + } + } + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'Comment this PR with *update_code* to update `openapi.json` and format the code. Consider to use pre-commit to format the code.' + }) + core.setFailed('Format your code.') + + check_size: + runs-on: ubuntu-latest + name: Check Size + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Check Size + uses: actions/github-script@v6.3.3 + env: + IGNORED_FILES: openapi.json, openapi-node.json + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const additions = context.payload.pull_request.additions || 0 + const deletions = context.payload.pull_request.deletions || 0 + var changes = additions + deletions + console.log('additions: '+additions+' + deletions: '+deletions+ ' = total changes: ' + changes); + + const { IGNORED_FILES } = process.env + const ignored_files = IGNORED_FILES.trim().split(',').filter(word => word.length > 0); + if (ignored_files.length > 0){ + var ignored = 0 + const execSync = require('child_process').execSync; + for (const file of IGNORED_FILES.trim().split(',')) { + + const ignored_additions_str = execSync('git --no-pager diff --numstat origin/main..origin/${{ github.head_ref}} | grep ' + file + ' | cut -f 1', { encoding: 'utf-8' }) + const ignored_deletions_str = execSync('git --no-pager diff --numstat origin/main..origin/${{ github.head_ref}} | grep ' + file + ' | cut -f 2', { encoding: 'utf-8' }) + + const ignored_additions = ignored_additions_str.split('\n').map(elem=> parseInt(elem || 0)).reduce( + (accumulator, currentValue) => accumulator + currentValue, + 0); + const ignored_deletions = ignored_deletions_str.split('\n').map(elem=> parseInt(elem || 0)).reduce( + (accumulator, currentValue) => accumulator + currentValue, + 0); + + ignored += ignored_additions + ignored_deletions; + } + changes -= ignored + console.log('ignored lines: ' + ignored + ' , consider changes: ' + changes); + } + + if (changes < 200){ + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['size/small'] + }) + + + var labels = await github.rest.issues.listLabelsOnIssue({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + + if (labels.data.find(label => label.name == 'size/large')){ + github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'size/large' + }) + } + } + + if (changes > 400){ + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['size/large'] + }) + + var comments = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + for (const comment of comments.data) { + if (comment.body.includes('This PR exceeds the recommended size')){ + github.rest.issues.deleteComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }) + } + } + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: 'This PR exceeds the recommended size of 400 lines. Please make sure you are NOT addressing multiple issues with one PR. _Note this PR might be rejected due to its size._' + }) + + var labels = await github.rest.issues.listLabelsOnIssue({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + + if (labels.data.find(label => label.name == 'size/small')){ + github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'size/small' + }) + } + + } + diff --git a/.github/workflows/03_code_review.yml b/.github/workflows/03_code_review.yml new file mode 100644 index 0000000..eae9e8a --- /dev/null +++ b/.github/workflows/03_code_review.yml @@ -0,0 +1,83 @@ +name: Code Review + +# Controls when the workflow will run +on: + pull_request: + branches: + - main + types: + - opened + - synchronize + - reopened + push: + branches: + - main + + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + PROJECT_KEY: pagopa_pagopa-taxonomy + + +permissions: + id-token: write + contents: read + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + code-review: + name: Code Review + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: Code Review + uses: pagopa/github-actions-template/maven-code-review@v1.4.1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + sonar_token: ${{ secrets.SONAR_TOKEN }} + project_key: ${{env.PROJECT_KEY}} + coverage_exclusions: "**/config/*,**/*Mock*,**/model/**,**/entity/*" + cpd_exclusions: "**/model/**,**/entity/*" + +# smoke-test: +# name: Smoke Test +# runs-on: ubuntu-latest +# environment: +# name: dev +# steps: +# - name: Checkout +# id: checkout +# uses: actions/checkout@1f9a0c22da41e6ebfa534300ef656657ea2c6707 +# +# - name: Login +# id: login +# # from https://github.com/Azure/login/commits/master +# uses: azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 +# with: +# client-id: ${{ secrets.CLIENT_ID }} +# tenant-id: ${{ secrets.TENANT_ID }} +# subscription-id: ${{ secrets.SUBSCRIPTION_ID }} +# +# - name: Run Service on Docker +# shell: bash +# run: | +# cd ./docker +# chmod +x ./run_docker.sh +# ./run_docker.sh local +# +# - name: Run Integration Tests +# shell: bash +# run: | +# export CANARY=${{ inputs.canary }} +# export CUCUMBER_PUBLISH_TOKEN=${{ secrets.CUCUMBER_PUBLISH_TOKEN }} +# export EVENT_HUB_TX_PRIMARY_KEY=${{ secrets.EVENT_HUB_TX_PRIMARY_KEY }} +# export COSMOS_DB_PRIMARY_KEY=${{ secrets.COSMOS_DB_PRIMARY_KEY }} +# export EVENTHUB_CONN_STRING=${{secrets.EVENTHUB_CONN_STRING}} +# +# cd ./integration-test +# chmod +x ./run_integration_test.sh +# ./run_integration_test.sh local diff --git a/.github/workflows/04_release_deploy.yml b/.github/workflows/04_release_deploy.yml new file mode 100644 index 0000000..6673d8a --- /dev/null +++ b/.github/workflows/04_release_deploy.yml @@ -0,0 +1,241 @@ +name: Release And Deploy + +# Controls when the workflow will run +on: + pull_request: + branches: + - main + types: [ closed ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + inputs: + environment: + required: true + type: choice + description: Select the Environment + options: + - dev + - uat + - prod + semver: + required: false + type: choice + description: Select the version + options: + - '' + - skip + - promote + - patch + - new_release + - breaking_change + # promote (skip) + # patch (patch) + # new_release (minor) + # breaking_change (major) + + # if DEV -> skip, patch, new-release (minor) or breaking-change (major) + # if UAT -> promote or patch (patch + branch_name) + # if PROD -> promote or patch (patch + branch_name) + + workflow_call: + inputs: + environment: + required: true + type: string + semver: + required: true + type: string + default: skip + +permissions: + packages: write + contents: write + issues: write + id-token: write + actions: read + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + setup: + name: Setup + runs-on: ubuntu-latest + outputs: + semver: ${{ steps.get_semver.outputs.semver }} + environment: ${{ steps.output.outputs.environment }} + steps: + - name: pull request rejected + if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged != true + run: | + echo "❌ PR was closed without a merge" + exit 1 + + # Set Semver + - run: echo "SEMVER=patch" >> $GITHUB_ENV + + - if: ${{ github.event.pull_request.merged && ( github.event.inputs.environment == 'uat' || github.event.inputs.environment == 'prod') && ( contains(github.event.pull_request.labels.*.name, 'breaking-change') || contains(github.event.pull_request.labels.*.name, 'new-release') || contains(github.event.pull_request.labels.*.name, 'ignore-for-release') ) }} + run: | + echo "❌ UAT and PROD accept only \"patch\" or \"promote\"" + exit 1 + + - if: ${{ github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'ignore-for-release') }} + run: echo "SEMVER=skip" >> $GITHUB_ENV + + - if: ${{ (github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'new-release')) }} + run: echo "SEMVER=minor" >> $GITHUB_ENV + + - if: ${{ (github.event.pull_request.merged && contains(github.event.pull_request.labels.*.name, 'breaking-change')) }} + run: echo "SEMVER=major" >> $GITHUB_ENV + + # force semver if dev, !=main or skip release + - if: ${{ inputs.semver == 'new_release' }} + run: echo "SEMVER=minor" >> $GITHUB_ENV + + - if: ${{ inputs.semver == 'breaking_change' }} + run: echo "SEMVER=major" >> $GITHUB_ENV + + - if: ${{ github.ref_name != 'main' && inputs.semver == '' }} + run: echo "SEMVER=buildNumber" >> $GITHUB_ENV + + - if: ${{ inputs.semver == 'promote' || inputs.semver == 'skip' }} + run: echo "SEMVER=skip" >> $GITHUB_ENV + + - id: get_semver + name: Set Output + run: echo "semver=${{env.SEMVER}}" >> $GITHUB_OUTPUT + + # Set Environment + - if: ${{ github.event.inputs.environment == null || github.event.inputs.environment == 'dev' }} + run: echo "ENVIRONMENT=dev" >> $GITHUB_ENV + + - if: ${{ github.event.inputs.environment == 'uat' }} + run: echo "ENVIRONMENT=uat" >> $GITHUB_ENV + + - if: ${{ github.event.inputs.environment == 'prod' }} + run: echo "ENVIRONMENT=prod" >> $GITHUB_ENV + + - if: ${{ github.event.inputs.environment == 'all' }} + run: echo "ENVIRONMENT=all" >> $GITHUB_ENV + + - id: output + name: Set Output + run: echo "environment=${{env.ENVIRONMENT}}" >> $GITHUB_OUTPUT + + release: + name: Create a New Release + runs-on: ubuntu-latest + needs: [setup] + outputs: + version: ${{ steps.release.outputs.version }} + steps: + - name: Make Release + id: release + uses: pagopa/github-actions-template/maven-release@main + with: + semver: ${{ needs.setup.outputs.semver }} + github_token: ${{ secrets.BOT_TOKEN_GITHUB }} + beta: false + + build-and-push: + needs: [ setup, release ] + name: Build and Push Docker Image + runs-on: ubuntu-latest + if: ${{ needs.setup.outputs.semver != 'skip' }} + environment: ${{ needs.setup.outputs.environment }} + steps: + - name: Build and Push + id: semver + uses: pagopa/github-actions-template/ghcr-build-push@v1.5.4 + with: + branch: ${{ github.ref_name}} + github_token: ${{ secrets.GITHUB_TOKEN }} + tag: ${{ needs.release.outputs.version }} + + deploy_azure_fn: + name: Deploy Azure function + environment: ${{ needs.setup.outputs.environment }} + needs: [ setup, release, build-and-push ] + runs-on: ubuntu-latest + if: ${{ always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }} + steps: + - name: 'Checkout GitHub Action' + uses: actions/checkout@v3 + + - name: 'Login via Azure CLI' + uses: azure/login@v1 + with: + client-id: ${{ secrets.CLIENT_ID }} + tenant-id: ${{ secrets.TENANT_ID }} + subscription-id: ${{ secrets.SUBSCRIPTION_ID }} + + - name: Set env variables + run: | + ENV_SHORT=$(echo ${{needs.setup.outputs.environment}} | cut -c1-1) + echo "RESOURCE_GROUP=pagopa-$ENV_SHORT-weu-shared-txnm-rg" >> $GITHUB_ENV + echo "APP_NAME=pagopa-$ENV_SHORT-weu-shared-txnm-fn" >> $GITHUB_ENV + echo "REGISTRY_IMAGE=ghcr.io/pagopa/pagopa-taxonomy:${{needs.release.outputs.version}}" >> $GITHUB_ENV + + + - name: 'Azure CLI script: start staging slot' + uses: azure/CLI@v1 + if: ${{ needs.setup.outputs.environment == 'prod' }} + with: + inlineScript: | + az functionapp start --name ${{ env.APP_NAME }} --resource-group ${{ env.RESOURCE_GROUP }} --slot staging + + - name: 'Run Azure Functions Container Action: staging slot' + uses: Azure/functions-container-action@v1.2.1 + if: ${{ needs.setup.outputs.environment == 'prod' }} + with: + app-name: ${{ env.APP_NAME }} + image: ${{ env.REGISTRY_IMAGE }} + slot-name: staging + + - name: 'Deploy Approval' + uses: trstringer/manual-approval@v1 + if: ${{ needs.setup.outputs.environment == 'prod' }} + with: + secret: ${{ secrets.BOT_TOKEN_GITHUB }} + approvers: pagopa-team-core + minimum-approvals: 1 + issue-title: "Deploying ${{ env.TAG }} to prod from staging" + issue-body: "Please approve or deny the deployment of version ${{ env.TAG }}." + exclude-workflow-initiator-as-approver: false + timeout-minutes: 360 + + - name: 'Run Azure Functions Container Action' + uses: Azure/functions-container-action@v1.2.1 + with: + app-name: ${{ env.APP_NAME }} + image: ${{ env.REGISTRY_IMAGE }} + slot-name: production + + - name: 'Azure CLI script: end staging slot' + uses: azure/CLI@v1 + if: ${{ needs.setup.outputs.environment == 'prod' }} + with: + inlineScript: | + az functionapp stop --name ${{ env.APP_NAME }} --resource-group ${{ env.RESOURCE_GROUP }} --slot staging + + - name: Azure logout + run: | + az logout + + notify: + needs: [ setup, release, deploy_azure_fn ] + runs-on: ubuntu-latest + name: Notify + if: always() + steps: + - name: Report Status + if: always() + uses: ravsamhq/notify-slack-action@v2 + with: + status: ${{ needs.deploy_azure_fn.result }} + token: ${{ secrets.GITHUB_TOKEN }} + notification_title: 'New Release on ${{ needs.setup.outputs.environment }} ${{ needs.release.outputs.version }} has {status_message}' + message_format: '{emoji} <{run_url}|{workflow}> {status_message} in <{repo_url}|{repo}>' + footer: 'Linked to <{workflow_url}| workflow file>' + icon_success: ':white_check_mark:' + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/04_self_hosted.yml b/.github/workflows/04_self_hosted.yml new file mode 100644 index 0000000..17e4205 --- /dev/null +++ b/.github/workflows/04_self_hosted.yml @@ -0,0 +1,85 @@ +name: Self Hosted Runner + +on: + workflow_call: + inputs: + environment: + required: true + description: The name of the environment where to deploy + type: string + target: + required: true + description: The environment target of the job + type: string + +env: + NAMESPACE: nodo + APP_NAME: pagopanodoretodatastore + +permissions: + id-token: write + contents: read + +jobs: + create_runner: + name: Create Runner + runs-on: ubuntu-22.04 + environment: + name: ${{ inputs.environment }} + if: ${{ inputs.target == inputs.environment || inputs.environment == 'all' }} + outputs: + runner_name: ${{ steps.create_github_runner.outputs.runner_name }} + steps: + - name: Create GitHub Runner + id: create_github_runner + # from https://github.com/pagopa/github-self-hosted-runner-azure-create-action/commits/main + uses: pagopa/github-self-hosted-runner-azure-create-action@v1.1.2 + with: + client_id: ${{ secrets.CLIENT_ID }} + tenant_id: ${{ secrets.TENANT_ID }} + subscription_id: ${{ secrets.SUBSCRIPTION_ID }} + container_app_environment_name: ${{ secrets.CONTAINER_APP_ENVIRONMENT_NAME }} + resource_group_name: ${{ secrets.RUNNER_RESOURCE_GROUP_NAME }} # RG of the runner + pat_token: ${{ secrets.BOT_TOKEN_GITHUB }} + self_hosted_runner_image_tag: "v1.4.0" + + deploy: + needs: [ create_runner ] + runs-on: [ self-hosted, "${{ needs.create_runner.outputs.runner_name }}" ] + if: ${{ inputs.target == inputs.environment || inputs.environment == 'all' }} + name: Deploy + environment: ${{ inputs.environment }} + steps: + - name: Deploy + uses: pagopa/github-actions-template/azure-functions-deploy@az-functions # TODO set tag after PR merge + with: + branch: ${{ github.ref_name }} + client_id: ${{ secrets.CLIENT_ID }} + subscription_id: ${{ secrets.SUBSCRIPTION_ID }} + tenant_id: ${{ secrets.TENANT_ID }} + env: ${{ inputs.environment }} + namespace: ${{ env.NAMESPACE }} + cluster_name: ${{ secrets.CLUSTER_NAME }} + resource_group: ${{ secrets.CLUSTER_RESOURCE_GROUP_NAME }} + app_name: ${{ env.APP_NAME }} + + + + cleanup_runner: + name: Cleanup Runner + needs: [ create_runner, deploy ] + if: ${{ success() || failure() && inputs.target == inputs.environment || inputs.environment == 'all' }} + runs-on: ubuntu-22.04 + environment: ${{ inputs.environment }} + steps: + - name: Cleanup GitHub Runner + id: cleanup_github_runner + # from https://github.com/pagopa/github-self-hosted-runner-azure-cleanup-action/commits/main + uses: pagopa/github-self-hosted-runner-azure-cleanup-action@v1.0.3 + with: + client_id: ${{ secrets.CLIENT_ID }} + tenant_id: ${{ secrets.TENANT_ID }} + subscription_id: ${{ secrets.SUBSCRIPTION_ID }} + resource_group_name: ${{ secrets.RUNNER_RESOURCE_GROUP_NAME }} + runner_name: ${{ needs.create_runner.outputs.runner_name }} + pat_token: ${{ secrets.BOT_TOKEN_GITHUB }} diff --git a/.github/workflows/check_metadata_pr.yml b/.github/workflows/check_metadata_pr.yml deleted file mode 100644 index c687c53..0000000 --- a/.github/workflows/check_metadata_pr.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Check PR - -# Controls when the workflow will run -on: - pull_request_target: - branches: - - main - types: [ opened, labeled, unlabeled, reopened ] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - build: - name: Check Labels - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - - name: Verify PR Labels - uses: jesusvasquez333/verify-pr-label-action@v1.4.0 - with: - github-token: '${{ secrets.GITHUB_TOKEN }}' - valid-labels: 'bug, enhancement, breaking-change, ignore-for-release' - pull-request-number: '${{ github.event.pull_request.number }}' - - - name: Label Check - if: ${{ !contains(github.event.pull_request.labels.*.name, 'breaking-change') && !contains(github.event.pull_request.labels.*.name, 'enhancement') && !contains(github.event.pull_request.labels.*.name, 'bug') && !contains(github.event.pull_request.labels.*.name, 'ignore-for-release') }} - uses: actions/github-script@v3 - with: - script: | - core.setFailed('Missing required labels') diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index 4f4091b..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Auto Deploy - -# Controls when the workflow will run -on: - pull_request: - branches: - - main - types: [ closed ] - - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - build: - if: ${{ github.event.pull_request.merged }} - name: Call Azure Build Pipeline - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - # default skip bump versioning - - name: Set as default skip bump versioning - run: | - echo "SEMVER=skip" >> $GITHUB_ENV - - - name: Set major - run: | - echo "SEMVER=major" >> $GITHUB_ENV - if: ${{ contains(github.event.pull_request.labels.*.name, 'breaking-change') }} - - - name: Set minor - run: | - echo "SEMVER=minor" >> $GITHUB_ENV - if: ${{ contains(github.event.pull_request.labels.*.name, 'enhancement') }} - - - name: Set patch - run: | - echo "SEMVER=patch" >> $GITHUB_ENV - if: ${{ contains(github.event.pull_request.labels.*.name, 'bug') }} - - - name: Set skip - run: | - echo "SEMVER=skip" >> $GITHUB_ENV - if: ${{ contains(github.event.pull_request.labels.*.name, 'ignore-for-release') }} - - - name: Azure Pipelines Action - Jversion - uses: jacopocarlini/azure-pipelines@v1.3 - with: - azure-devops-project-url: https://dev.azure.com/pagopaspa/pagoPA-projects - azure-pipeline-name: 'pagopa-function-template.deploy' - azure-devops-token: ${{ secrets.AZURE_DEVOPS_TOKEN }} - azure-template-parameters: '{"ENV": "dev", "SEMVER": "${{env.SEMVER}}", "TEST": "true"}' - azure-pipeline-variables: '{"system.debug": "true"}' - diff --git a/.github/workflows/sonar_analysis.yml b/.github/workflows/sonar_analysis.yml deleted file mode 100644 index 8003cbf..0000000 --- a/.github/workflows/sonar_analysis.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Sonar Analysis - -# Controls when the workflow will run -on: - push: - branches: - - main - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - build: - name: Call Azure Build Pipeline - # The type of runner that the job will run on - runs-on: ubuntu-latest - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - name: Azure Pipelines Action - Jversion - uses: jacopocarlini/azure-pipelines@v1.3 - with: - azure-devops-project-url: https://dev.azure.com/pagopaspa/pagoPA-projects - azure-pipeline-name: 'pagopa-function-templat.code-review' - azure-devops-token: ${{ secrets.AZURE_DEVOPS_TOKEN }} - azure-pipeline-variables: '{"system.debug": "true"}' - diff --git a/.identity/.terraform.lock.hcl b/.identity/.terraform.lock.hcl new file mode 100644 index 0000000..4d467ca --- /dev/null +++ b/.identity/.terraform.lock.hcl @@ -0,0 +1,83 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azuread" { + version = "2.30.0" + constraints = "2.30.0" + hashes = [ + "h1:WnSPiREAFwnBUKREokMdHQ8Cjs47MzvS9pG8VS1ktec=", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:2e62c193030e04ebb10cc0526119cf69824bf2d7e4ea5a2f45bd5d5fb7221d36", + "zh:2f3c7a35257332d68b778cefc5201a5f044e4914dd03794a4da662ddfe756483", + "zh:35d0d3a1b58fdb8b8c4462d6b7e7016042da43ea9cc734ce897f52a73407d9b0", + "zh:47ede0cd0206ec953d40bf4a80aa6e59af64e26cbbd877614ac424533dbb693b", + "zh:48c190307d4d42ea67c9b8cc544025024753f46cef6ea64db84735e7055a72da", + "zh:6fff9b2c6a962252a70a15b400147789ab369b35a781e9d21cce3804b04d29af", + "zh:7646980cf3438bff29c91ffedb74458febbb00a996638751fbd204ab1c628c9b", + "zh:77aa2fa7ca6d5446afa71d4ff83cb87b70a2f3b72110fc442c339e8e710b2928", + "zh:e20b2b2c37175b89dd0db058a096544d448032e28e3b56e2db368343533a9684", + "zh:eab175b1dfe9865ad9404dccb6d5542899f8c435095aa7c679314b811c717ce7", + "zh:efc862bd78c55d2ff089729e2a34c1831ab4b0644fc11b36ee4ebed00a4797ba", + ] +} + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "3.45.0" + constraints = "3.45.0" + hashes = [ + "h1:gQLNY1I5e9kcle1p/VYEWb0eteQ/t5kUfnqVu2/GBNY=", + "zh:04c5dbb8845366ce5eb0dc2d55e151270cc2c0ace20993867fdae9af43b953ad", + "zh:2589585da615ccae341400d45d672ee3fae413fdd88449b5befeff12a85a44b2", + "zh:603869ed98fff5d9bf841a51afd9e06b628533c59356c8433aef4b15df63f5f7", + "zh:853fecab9c987b6772c8d9aa10362675f6c626b60ebc7118aa33ce91366fcc38", + "zh:979848c45e8e058862c36ba3a661457f7c81ef26ebb6634f479600de9c203d65", + "zh:9b512c8588ecc9c1b803b746a3a8517422561a918f0dfb0faaa707ed53ef1760", + "zh:a9601ffb58043426bcff1220662d6d137f0b2857a24f2dcf180aeac2c9cea688", + "zh:d52d2652328f0ed3ba202561d88cb9f43c174edbfaab1abf69f772125dbfe15e", + "zh:d92d91ca597c47f575bf3ae129f4b723be9b7dcb71b906ec6ec740fac29b1aaa", + "zh:ded73b730e4197b70fda9e83447c119f92f75dc37be3ff2ed45730c8f0348c28", + "zh:ec37ac332d50f8ca5827f97198346b0f8ecbf470e2e3ba1e027bb389d826b902", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/null" { + version = "3.2.1" + hashes = [ + "h1:tSj1mL6OQ8ILGqR2mDu7OYYYWf+hoir0pf9KAQ8IzO8=", + "zh:58ed64389620cc7b82f01332e27723856422820cfd302e304b5f6c3436fb9840", + "zh:62a5cc82c3b2ddef7ef3a6f2fedb7b9b3deff4ab7b414938b08e51d6e8be87cb", + "zh:63cff4de03af983175a7e37e52d4bd89d990be256b16b5c7f919aff5ad485aa5", + "zh:74cb22c6700e48486b7cabefa10b33b801dfcab56f1a6ac9b6624531f3d36ea3", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:79e553aff77f1cfa9012a2218b8238dd672ea5e1b2924775ac9ac24d2a75c238", + "zh:a1e06ddda0b5ac48f7e7c7d59e1ab5a4073bbcf876c73c0299e4610ed53859dc", + "zh:c37a97090f1a82222925d45d84483b2aa702ef7ab66532af6cbcfb567818b970", + "zh:e4453fbebf90c53ca3323a92e7ca0f9961427d2f0ce0d2b65523cc04d5d999c2", + "zh:e80a746921946d8b6761e77305b752ad188da60688cfd2059322875d363be5f5", + "zh:fbdb892d9822ed0e4cb60f2fedbdbb556e4da0d88d3b942ae963ed6ff091e48f", + "zh:fca01a623d90d0cad0843102f9b8b9fe0d3ff8244593bd817f126582b52dd694", + ] +} + +provider "registry.terraform.io/integrations/github" { + version = "5.18.3" + constraints = "5.18.3" + hashes = [ + "h1:rv3mwpUeJ0n13sY+KZMI25WAVCSeipX4n8JMWKD1XcE=", + "zh:050b37d96628cb7451137755929ca8d21ea546bc46d11a715652584070e83ff2", + "zh:053051061f1b7f7673b0ceffac1f239ba28b0e5b375999206fd39976e85d9f2b", + "zh:0c300a977ca66d0347ed62bb116fd8fc9abb376a554d4c192d14f3ea71c83500", + "zh:1d5a1a5243eba78819d2f92ff2d504ebf9a9008a6670fb5f5660f44eb6a156d8", + "zh:a13ac15d251ebf4e7dc40acb0e40df066f443f4c7799186a29e2e44addc7d8e7", + "zh:a316d94b885953c036ebc9fba64a23da93974746bc3ac9d207462a6f02d44540", + "zh:a658a00373bff5979cc227052c693cbde8ca4c8f9fef1bc8094a3516f2e2a96d", + "zh:a7bfc6ad8465d5dc11b6f19d6805364de87fffe27622bb4f37da2319bb1c4956", + "zh:d7379a76861f1a6bfc36eca7a20f1f477711247563b105744d69d7bd1f365fad", + "zh:de1cd959fd4821248e8d21570601193408648474e74f49597f1d0c43185a4ab7", + "zh:e0b281240dd6f2aa405b2d6fe329bc15ab877161affe163fb150d1efca2fccdb", + "zh:e372c171358757a983d7aa878abfd05a84484fb4d22167e45c9c1267e78ed060", + "zh:f6d3116526030b3f6905f530cd6c04b23d42890d973fa2abe10ce9c89cb1db80", + "zh:f99eec731e03cc6a28996c875bd435887cd7ea75ec07cc77b9e768bb12da2227", + ] +} diff --git a/.identity/00_data.tf b/.identity/00_data.tf new file mode 100644 index 0000000..7665c8e --- /dev/null +++ b/.identity/00_data.tf @@ -0,0 +1,42 @@ +data "azurerm_resource_group" "dashboards" { + name = "dashboards" +} + +data "azurerm_kubernetes_cluster" "aks" { + name = local.aks_cluster.name + resource_group_name = local.aks_cluster.resource_group_name +} + +data "github_organization_teams" "all" { + root_teams_only = true + summary_only = true +} + +data "azurerm_key_vault" "key_vault" { + name = "pagopa-${var.env_short}-kv" + resource_group_name = "pagopa-${var.env_short}-sec-rg" +} + +data "azurerm_key_vault" "domain_key_vault" { + name = "pagopa-${var.env_short}-${local.domain}-kv" + resource_group_name = "pagopa-${var.env_short}-${local.domain}-sec-rg" +} + +data "azurerm_key_vault_secret" "key_vault_sonar" { + name = "sonar-token" + key_vault_id = data.azurerm_key_vault.key_vault.id +} + +data "azurerm_key_vault_secret" "key_vault_bot_token" { + name = "bot-token-github" + key_vault_id = data.azurerm_key_vault.key_vault.id +} + +data "azurerm_key_vault_secret" "key_vault_slack_webhook_url" { + name = "nodo5-slack-webhook-url" + key_vault_id = data.azurerm_key_vault.domain_key_vault.id +} + +data "azurerm_resource_group" "app_rg" { + name = "pagopa-${var.env_short}-${local.location_short}-${local.domain}-txnm-rg" +} diff --git a/.identity/02_application_action.tf b/.identity/02_application_action.tf new file mode 100644 index 0000000..9a80143 --- /dev/null +++ b/.identity/02_application_action.tf @@ -0,0 +1,90 @@ +module "github_runner_app" { + source = "git::https://github.com/pagopa/github-actions-tf-modules.git//app-github-runner-creator?ref=main" + + app_name = local.app_name + + subscription_id = data.azurerm_subscription.current.id + + github_org = local.github.org + github_repository = local.github.repository + github_environment_name = var.env + + container_app_github_runner_env_rg = local.container_app_environment.resource_group +} + +resource "null_resource" "github_runner_app_permissions_to_namespace" { + triggers = { + aks_id = data.azurerm_kubernetes_cluster.aks.id + service_principal_id = module.github_runner_app.client_id + namespace = local.domain + version = "v2" + } + + provisioner "local-exec" { + command = < +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >=1.3.0 | +| [azuread](#requirement\_azuread) | 2.30.0 | +| [azurerm](#requirement\_azurerm) | 3.45.0 | +| [github](#requirement\_github) | 5.18.3 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [github\_runner\_app](#module\_github\_runner\_app) | git::https://github.com/pagopa/github-actions-tf-modules.git//app-github-runner-creator | main | + +## Resources + +| Name | Type | +|------|------| +| [azurerm_key_vault_access_policy.ad_kv_domain_group_policy](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/resources/key_vault_access_policy) | resource | +| [azurerm_key_vault_access_policy.ad_kv_group_policy](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/resources/key_vault_access_policy) | resource | +| [azurerm_role_assignment.environment_key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/resources/role_assignment) | resource | +| [azurerm_role_assignment.environment_key_vault_domain](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/resources/role_assignment) | resource | +| [azurerm_role_assignment.environment_terraform_resource_group_dashboards](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/resources/role_assignment) | resource | +| [github_actions_environment_secret.github_environment_runner_secrets](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/resources/actions_environment_secret) | resource | +| [github_actions_environment_variable.github_environment_runner_variables](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/resources/actions_environment_variable) | resource | +| [github_actions_secret.secret_bot_token](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/resources/actions_secret) | resource | +| [github_actions_secret.secret_cucumber_token](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/resources/actions_secret) | resource | +| [github_actions_secret.secret_sonar_token](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/resources/actions_secret) | resource | +| [github_repository_environment.github_repository_environment](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/resources/repository_environment) | resource | +| [null_resource.github_runner_app_permissions_to_namespace](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/client_config) | data source | +| [azurerm_key_vault.domain_key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/key_vault) | data source | +| [azurerm_key_vault.key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/key_vault) | data source | +| [azurerm_key_vault_secret.key_vault_bot_token](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/key_vault_secret) | data source | +| [azurerm_key_vault_secret.key_vault_cucumber_token](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/key_vault_secret) | data source | +| [azurerm_key_vault_secret.key_vault_sa_connection_string](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/key_vault_secret) | data source | +| [azurerm_key_vault_secret.key_vault_sonar](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/key_vault_secret) | data source | +| [azurerm_kubernetes_cluster.aks](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/kubernetes_cluster) | data source | +| [azurerm_resource_group.dashboards](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/resource_group) | data source | +| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/3.45.0/docs/data-sources/subscription) | data source | +| [github_organization_teams.all](https://registry.terraform.io/providers/integrations/github/5.18.3/docs/data-sources/organization_teams) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [env](#input\_env) | n/a | `string` | n/a | yes | +| [env\_short](#input\_env\_short) | n/a | `string` | n/a | yes | +| [github\_repository\_environment](#input\_github\_repository\_environment) | GitHub Continuous Integration roles |
object({
protected_branches = bool
custom_branch_policies = bool
reviewers_teams = list(string)
})
|
{
"custom_branch_policies": true,
"protected_branches": false,
"reviewers_teams": [
"pagopa-team-core"
]
}
| no | +| [prefix](#input\_prefix) | n/a | `string` | `"pagopa"` | no | + +## Outputs + +No outputs. + diff --git a/.identity/env/dev/backend.ini b/.identity/env/dev/backend.ini new file mode 100644 index 0000000..22e6a99 --- /dev/null +++ b/.identity/env/dev/backend.ini @@ -0,0 +1 @@ +subscription=DEV-pagoPA diff --git a/.identity/env/dev/backend.tfvars b/.identity/env/dev/backend.tfvars new file mode 100644 index 0000000..1a29b46 --- /dev/null +++ b/.identity/env/dev/backend.tfvars @@ -0,0 +1,4 @@ +resource_group_name = "io-infra-rg" +storage_account_name = "pagopainfraterraformdev" +container_name = "azurermstate" +key = "pagopa-taxonomy.tfstate" diff --git a/.identity/env/dev/terraform.tfvars b/.identity/env/dev/terraform.tfvars new file mode 100644 index 0000000..d397fdd --- /dev/null +++ b/.identity/env/dev/terraform.tfvars @@ -0,0 +1,11 @@ +prefix = "pagopa" +env_short = "d" +env = "dev" + +tags = { + CreatedBy = "Terraform" + Environment = "Dev" + Owner = "pagoPA" + Source = "https://github.com/pagopa/pagopa-nodo-re-to-datastore" + CostCenter = "TS310 - PAGAMENTI & SERVIZI" +} diff --git a/.identity/env/prod/backend.ini b/.identity/env/prod/backend.ini new file mode 100644 index 0000000..6318425 --- /dev/null +++ b/.identity/env/prod/backend.ini @@ -0,0 +1 @@ +subscription=PROD-pagoPA diff --git a/.identity/env/prod/backend.tfvars b/.identity/env/prod/backend.tfvars new file mode 100644 index 0000000..b44c0c7 --- /dev/null +++ b/.identity/env/prod/backend.tfvars @@ -0,0 +1,4 @@ +resource_group_name = "io-infra-rg" +storage_account_name = "pagopainfraterraformprod" +container_name = "azurermstate" +key = "pagopa-taxonomy.tfstate" diff --git a/.identity/env/prod/terraform.tfvars b/.identity/env/prod/terraform.tfvars new file mode 100644 index 0000000..60adf6b --- /dev/null +++ b/.identity/env/prod/terraform.tfvars @@ -0,0 +1,11 @@ +prefix = "pagopa" +env_short = "p" +env = "prod" + +tags = { + CreatedBy = "Terraform" + Environment = "Prod" + Owner = "pagoPA" + Source = "https://github.com/pagopa/pagopa-nodo-re-to-datastore" + CostCenter = "TS310 - PAGAMENTI & SERVIZI" +} diff --git a/.identity/env/uat/backend.ini b/.identity/env/uat/backend.ini new file mode 100644 index 0000000..1a01415 --- /dev/null +++ b/.identity/env/uat/backend.ini @@ -0,0 +1 @@ +subscription=UAT-pagoPA diff --git a/.identity/env/uat/backend.tfvars b/.identity/env/uat/backend.tfvars new file mode 100644 index 0000000..cc33a47 --- /dev/null +++ b/.identity/env/uat/backend.tfvars @@ -0,0 +1,4 @@ +resource_group_name = "io-infra-rg" +storage_account_name = "pagopainfraterraformuat" +container_name = "azurermstate" +key = "pagopa-taxonomy.tfstate" diff --git a/.identity/env/uat/terraform.tfvars b/.identity/env/uat/terraform.tfvars new file mode 100644 index 0000000..836550b --- /dev/null +++ b/.identity/env/uat/terraform.tfvars @@ -0,0 +1,11 @@ +prefix = "pagopa" +env_short = "u" +env = "uat" + +tags = { + CreatedBy = "Terraform" + Environment = "Uat" + Owner = "pagoPA" + Source = "https://github.com/pagopa/pagopa-nodo-re-to-datastore" + CostCenter = "TS310 - PAGAMENTI & SERVIZI" +} diff --git a/.identity/terraform.sh b/.identity/terraform.sh new file mode 100755 index 0000000..02fc806 --- /dev/null +++ b/.identity/terraform.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -e + +ACTION=$1 +ENV=$2 +shift 2 +other="$@" +# must be subscription in lower case +subscription="" +BACKEND_CONFIG_PATH="./env/${ENV}/backend.tfvars" + +if [ -z "$ACTION" ]; then + echo "[ERROR] Missed ACTION: init, apply, plan" + exit 0 +fi + +if [ -z "$ENV" ]; then + echo "[ERROR] ENV should be: dev, uat or prod." + exit 0 +fi + +# +# 🏁 Source & init shell +# + +# shellcheck source=/dev/null +source "./env/$ENV/backend.ini" + +# Subscription set +az account set -s "${subscription}" + +# if using cygwin, we have to transcode the WORKDIR +if [[ $WORKDIR == /cygdrive/* ]]; then + WORKDIR=$(cygpath -w $WORKDIR) +fi + +# Helm +export HELM_DEBUG=1 +export TF_VAR_github_token="${GITHUB_TOKEN}" +# TODO set your PAT TOKEN as env var +if [ -z "$GITHUB_TOKEN" ]; then + echo "Error: Set an environment variable named GITHUB_TOKEN with your GitHub PAT Token" + exit 1 +fi + +# +# 🌎 Terraform +# +if echo "init plan apply refresh import output state taint destroy" | grep -w "$ACTION" > /dev/null; then + if [ "$ACTION" = "init" ]; then + echo "[INFO] init tf on ENV: ${ENV}" + terraform "$ACTION" -backend-config="${BACKEND_CONFIG_PATH}" $other + elif [ "$ACTION" = "output" ] || [ "$ACTION" = "state" ] || [ "$ACTION" = "taint" ]; then + # init terraform backend + terraform init -reconfigure -backend-config="${BACKEND_CONFIG_PATH}" + terraform "$ACTION" $other + else + # init terraform backend + echo "[INFO] init tf on ENV: ${ENV}" + terraform init -reconfigure -backend-config="${BACKEND_CONFIG_PATH}" + + echo "[INFO] run tf with: ${ACTION} on ENV: ${ENV} and other: >${other}<" + terraform "${ACTION}" -var-file="./env/${ENV}/terraform.tfvars" -compact-warnings $other + fi +else + echo "[ERROR] ACTION not allowed." + exit 1 +fi