| --- |
| name: enos |
| |
| on: |
| # Only trigger this working using workflow_call. This workflow requires many |
| # secrets that must be inherited from the caller workflow. |
| workflow_call: |
| inputs: |
| # The name of the artifact that we're going to use for testing. This should |
| # match exactly to build artifacts uploaded to Github and Artifactory. |
| build-artifact-name: |
| required: true |
| type: string |
| # The maximum number of scenarios to include in the test sample. |
| sample-max: |
| default: 1 |
| type: number |
| # The name of the enos scenario sample that defines compatible scenarios we can |
| # can test with. |
| sample-name: |
| required: true |
| type: string |
| runs-on: |
| # NOTE: The value should be JSON encoded as that's the only way we can |
| # pass arrays with workflow_call. |
| type: string |
| required: false |
| default: '"ubuntu-latest"' |
| ssh-key-name: |
| type: string |
| default: ${{ github.event.repository.name }}-ci-ssh-key |
| vault-edition: |
| required: false |
| type: string |
| default: oss |
| # The Git commit SHA used as the revision when building vault |
| vault-revision: |
| required: true |
| type: string |
| vault-version: |
| required: true |
| type: string |
| |
| jobs: |
| metadata: |
| runs-on: ${{ fromJSON(inputs.runs-on) }} |
| outputs: |
| build-date: ${{ steps.metadata.outputs.build-date }} |
| sample: ${{ steps.metadata.outputs.sample }} |
| vault-version: ${{ steps.metadata.outputs.vault-version }} |
| steps: |
| - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 |
| with: |
| ref: ${{ inputs.vault-revision }} |
| - uses: hashicorp/action-setup-enos@v1 |
| with: |
| github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} |
| - id: metadata |
| run: | |
| echo "build-date=$(make ci-get-date)" >> "$GITHUB_OUTPUT" |
| sample="$(enos scenario sample observe ${{ inputs.sample-name }} --chdir ./enos --min 1 --max ${{ inputs.sample-max }} --seed "$(date +%s%N)" --format json | jq -c ".observation.elements")" |
| echo "sample=$sample" |
| echo "sample=$sample" >> "$GITHUB_OUTPUT" |
| if [[ "${{ inputs.vault-edition }}" == "oss" ]]; then |
| echo "vault-version=${{ inputs.vault-version }}" >> "$GITHUB_OUTPUT" |
| else |
| # shellcheck disable=2001 |
| vault_version="$(sed 's/+ent/+${{ inputs.vault-edition }}/g' <<< '${{ inputs.vault-version }}')" |
| echo "vault-version=$vault_version" |
| echo "vault-version=$vault_version" >> "$GITHUB_OUTPUT" |
| fi |
| |
| # Run the Enos test scenario(s) |
| run: |
| needs: metadata |
| name: run ${{ matrix.scenario.id.filter }} |
| strategy: |
| fail-fast: false # don't fail as that can skip required cleanup steps for jobs |
| matrix: |
| include: ${{ fromJSON(needs.metadata.outputs.sample) }} |
| runs-on: ${{ fromJSON(inputs.runs-on) }} |
| env: |
| GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }} |
| # Pass in enos variables |
| ENOS_VAR_aws_region: ${{ matrix.attributes.aws_region }} |
| ENOS_VAR_aws_ssh_keypair_name: ${{ inputs.ssh-key-name }} |
| ENOS_VAR_aws_ssh_private_key_path: ./support/private_key.pem |
| ENOS_VAR_tfc_api_token: ${{ secrets.TF_API_TOKEN }} |
| ENOS_VAR_artifactory_username: ${{ secrets.ARTIFACTORY_USER }} |
| ENOS_VAR_artifactory_token: ${{ secrets.ARTIFACTORY_TOKEN }} |
| ENOS_VAR_terraform_plugin_cache_dir: ./support/terraform-plugin-cache |
| ENOS_VAR_vault_artifact_path: ./support/downloads/${{ inputs.build-artifact-name }} |
| ENOS_VAR_vault_build_date: ${{ needs.metadata.outputs.build-date }} |
| ENOS_VAR_vault_product_version: ${{ needs.metadata.outputs.vault-version }} |
| ENOS_VAR_vault_revision: ${{ inputs.vault-revision }} |
| ENOS_VAR_vault_license_path: ./support/vault.hclic |
| ENOS_DEBUG_DATA_ROOT_DIR: /tmp/enos-debug-data |
| steps: |
| - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 |
| - uses: hashicorp/setup-terraform@v2 |
| with: |
| # the Terraform wrapper will break Terraform execution in Enos because |
| # it changes the output to text when we expect it to be JSON. |
| terraform_wrapper: false |
| - uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 |
| with: |
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CI }} |
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CI }} |
| aws-region: ${{ matrix.attributes.aws_region }} |
| role-to-assume: ${{ secrets.AWS_ROLE_ARN_CI }} |
| role-skip-session-tagging: true |
| role-duration-seconds: 3600 |
| - uses: hashicorp/action-setup-enos@v1 |
| with: |
| github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} |
| - name: Prepare scenario dependencies |
| id: prepare_scenario |
| run: | |
| mkdir -p "./enos/support/terraform-plugin-cache" |
| echo "${{ secrets.SSH_KEY_PRIVATE_CI }}" > "./enos/support/private_key.pem" |
| chmod 600 "./enos/support/private_key.pem" |
| echo "debug_data_artifact_name=enos-debug-data_$(echo "${{ matrix.scenario }}" | sed -e 's/ /_/g' | sed -e 's/:/=/g')" >> "$GITHUB_OUTPUT" |
| - if: contains(inputs.sample-name, 'build') |
| uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 |
| with: |
| name: ${{ inputs.build-artifact-name }} |
| path: ./enos/support/downloads |
| - if: contains(inputs.sample-name, 'ent') |
| name: Configure Vault license |
| run: echo "${{ secrets.VAULT_LICENSE }}" > ./enos/support/vault.hclic || true |
| - id: launch |
| name: enos scenario launch ${{ matrix.scenario.id.filter }} |
| # Continue once and retry to handle occasional blips when creating infrastructure. |
| continue-on-error: true |
| run: enos scenario launch --timeout 60m0s --chdir ./enos ${{ matrix.scenario.id.filter }} |
| - if: steps.launch.outcome == 'failure' |
| id: launch_retry |
| name: Retry enos scenario launch ${{ matrix.scenario.id.filter }} |
| run: enos scenario launch --timeout 60m0s --chdir ./enos ${{ matrix.scenario.id.filter }} |
| - name: Upload Debug Data |
| if: failure() |
| uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 |
| with: |
| # The name of the artifact is the same as the matrix scenario name with the spaces replaced with underscores and colons replaced by equals. |
| name: ${{ steps.prepare_scenario.outputs.debug_data_artifact_name }} |
| path: ${{ env.ENOS_DEBUG_DATA_ROOT_DIR }} |
| retention-days: 30 |
| continue-on-error: true |
| - if: ${{ always() }} |
| id: destroy |
| name: enos scenario destroy ${{ matrix.scenario.id.filter }} |
| continue-on-error: true |
| run: enos scenario destroy --timeout 60m0s --chdir ./enos ${{ matrix.scenario.id.filter }} |
| - if: steps.destroy.outcome == 'failure' |
| id: destroy_retry |
| name: Retry enos scenario destroy ${{ matrix.scenario.id.filter }} |
| continue-on-error: true |
| run: enos scenario destroy --timeout 60m0s --chdir ./enos ${{ matrix.scenario.id.filter }} |
| - name: Clean up Enos runtime directories |
| id: cleanup |
| if: ${{ always() }} |
| continue-on-error: true |
| run: | |
| rm -rf /tmp/enos* |
| rm -rf ./enos/support |
| rm -rf ./enos/.enos |
| # Send slack notifications to #feed-vault-enos-failures any of our enos scenario commands fail. |
| # There is an incoming webhook set up on the "Enos Vault Failure Bot" Slackbot: |
| # https://api.slack.com/apps/A05E31CH1LG/incoming-webhooks |
| - if: ${{ always() && ! cancelled() }} |
| name: Notify launch failed |
| uses: hashicorp/actions-slack-status@v1 |
| with: |
| failure-message: "enos scenario launch ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`" |
| status: ${{ steps.launch.outcome }} |
| slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} |
| - if: ${{ always() && ! cancelled() }} |
| name: Notify retry launch failed |
| uses: hashicorp/actions-slack-status@v1 |
| with: |
| failure-message: "retry enos scenario launch ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`" |
| status: ${{ steps.launch_retry.outcome }} |
| slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} |
| - if: ${{ always() && ! cancelled() }} |
| name: Notify destroy failed |
| uses: hashicorp/actions-slack-status@v1 |
| with: |
| failure-message: "enos scenario destroy ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`" |
| status: ${{ steps.destroy.outcome }} |
| slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} |
| - if: ${{ always() && ! cancelled() }} |
| name: Notify retry destroy failed |
| uses: hashicorp/actions-slack-status@v1 |
| with: |
| failure-message: "retry enos scenario destroy ${{ matrix.scenario.id.filter}} failed. \nTriggering event: `${{ github.event_name }}` \nActor: `${{ github.actor }}`" |
| status: ${{ steps.destroy_retry.outcome }} |
| slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} |