From 6f66dbd1a0b1d05429074be335d6e590f7c0f4f3 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 4 Jan 2021 16:56:53 +0700 Subject: [PATCH 01/12] Terraform 0.14 upgrade --- .github/CODEOWNERS | 13 ++++-- .github/auto-release.yml | 39 +++++++++------- .github/mergify.yml | 52 +++++++++++++++++++++ .github/workflows/auto-context.yml | 55 +++++++++++++++++++++++ .github/workflows/auto-readme.yml | 41 +++++++++++++++++ .github/workflows/chatops.yml | 4 +- .github/workflows/validate-codeowners.yml | 18 ++++++++ README.md | 17 +++++-- context.tf | 3 +- examples/complete/context.tf | 3 +- examples/complete/versions.tf | 8 ++++ 11 files changed, 226 insertions(+), 27 deletions(-) create mode 100644 .github/mergify.yml create mode 100644 .github/workflows/auto-context.yml create mode 100644 .github/workflows/auto-readme.yml create mode 100644 .github/workflows/validate-codeowners.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 07b38d2..ceb4644 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,7 @@ # Use this file to define individuals or teams that are responsible for code in a repository. # Read more: # -# Order is important: the last matching pattern takes the most precedence +# Order is important: the last matching pattern has the highest precedence # These owners will be the default owners for everything * @cloudposse/engineering @cloudposse/contributors @@ -13,5 +13,12 @@ # Cloud Posse must review any changes to GitHub actions .github/* @cloudposse/engineering -# Cloud Posse must review any changes to standard context definition -**/context.tf @cloudposse/engineering +# Cloud Posse must review any changes to standard context definition, +# but some changes can be rubber-stamped. +**/context.tf @cloudposse/engineering @cloudposse/approvers +README.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers +docs/*.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers + +# Cloud Posse Admins must review all changes to CODEOWNERS or the mergify configuration +.github/mergify.yml @cloudposse/admins +.github/CODEOWNERS @cloudposse/admins diff --git a/.github/auto-release.yml b/.github/auto-release.yml index 2836185..18a1ca6 100644 --- a/.github/auto-release.yml +++ b/.github/auto-release.yml @@ -4,30 +4,35 @@ version-template: '$MAJOR.$MINOR.$PATCH' version-resolver: major: labels: - - 'major' + - 'major' minor: labels: - - 'minor' - - 'enhancement' + - 'minor' + - 'enhancement' patch: labels: - - 'patch' - - 'fix' - - 'bugfix' - - 'bug' - - 'hotfix' + - 'auto-update' + - 'patch' + - 'fix' + - 'bugfix' + - 'bug' + - 'hotfix' default: 'minor' categories: - - title: '๐Ÿš€ Enhancements' - labels: - - 'enhancement' - - title: '๐Ÿ› Bug Fixes' - labels: - - 'fix' - - 'bugfix' - - 'bug' - - 'hotfix' +- title: '๐Ÿš€ Enhancements' + labels: + - 'enhancement' + - 'patch' +- title: '๐Ÿ› Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - 'hotfix' +- title: '๐Ÿค– Automatic Updates' + labels: + - 'auto-update' change-template: |
diff --git a/.github/mergify.yml b/.github/mergify.yml new file mode 100644 index 0000000..485982f --- /dev/null +++ b/.github/mergify.yml @@ -0,0 +1,52 @@ +pull_request_rules: +- name: "approve automated PRs that have passed checks" + conditions: + - "check-success~=test/bats" + - "check-success~=test/readme" + - "check-success~=test/terratest" + - "base=master" + - "author=cloudpossebot" + - "head~=auto-update/.*" + actions: + review: + type: "APPROVE" + bot_account: "cloudposse-mergebot" + message: "We've automatically approved this PR because the checks from the automated Pull Request have passed." + +- name: "merge automated PRs when approved and tests pass" + conditions: + - "check-success~=test/bats" + - "check-success~=test/readme" + - "check-success~=test/terratest" + - "base=master" + - "head~=auto-update/.*" + - "#approved-reviews-by>=1" + - "#changes-requested-reviews-by=0" + - "#commented-reviews-by=0" + - "base=master" + - "author=cloudpossebot" + actions: + merge: + method: "squash" + +- name: "delete the head branch after merge" + conditions: + - "merged" + actions: + delete_head_branch: {} + +- name: "ask to resolve conflict" + conditions: + - "conflict" + actions: + comment: + message: "This pull request is now in conflict. Could you fix it @{{author}}? ๐Ÿ™" + +- name: "remove outdated reviews" + conditions: + - "base=master" + actions: + dismiss_reviews: + changes_requested: true + approved: true + message: "This Pull Request has been updated, so we're dismissing all reviews." diff --git a/.github/workflows/auto-context.yml b/.github/workflows/auto-context.yml new file mode 100644 index 0000000..739a3c9 --- /dev/null +++ b/.github/workflows/auto-context.yml @@ -0,0 +1,55 @@ +name: "auto-context" +on: + schedule: + # Update context.tf nightly + - cron: '0 3 * * *' + +jobs: + update: + if: github.event_name == 'schedule' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update context.tf + shell: bash + id: update + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + run: | + if [[ -f context.tf ]]; then + echo "Discovered existing context.tf! Fetching most recent version to see if there is an update." + curl -o context.tf -fsSL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf + if git diff --no-patch --exit-code context.tf; then + echo "No changes detected! Exiting the job..." + else + echo "context.tf file has changed. Update examples and rebuild README.md." + make init + make github/init/context.tf + make readme/build + echo "::set-output name=create_pull_request=true" + fi + else + echo "This module has not yet been updated to support the context.tf pattern! Please update in order to support automatic updates." + fi + + - name: Create Pull Request + if: {{ steps.update.outputs.create_pull_request == 'true' }} + uses: cloudposse/actions/github/create-pull-request@0.22.0 + with: + token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} + commit-message: Update context.tf from origin source + title: Update context.tf + body: |- + ## what + This is an auto-generated PR that updates the `context.tf` file to the latest version from `cloudposse/terraform-null-label` + + ## why + To support all the features of the `context` interface. + + branch: auto-update/context.tf + base: master + delete-branch: true + labels: | + auto-update + context diff --git a/.github/workflows/auto-readme.yml b/.github/workflows/auto-readme.yml new file mode 100644 index 0000000..6229e60 --- /dev/null +++ b/.github/workflows/auto-readme.yml @@ -0,0 +1,41 @@ +name: "auto-readme" +on: + schedule: + # Update README.md nightly + - cron: '0 4 * * *' + +jobs: + update: + if: github.event_name == 'schedule' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update readme + shell: bash + id: update + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + run: | + make init + make readme/build + + - name: Create Pull Request + uses: cloudposse/actions/github/create-pull-request@0.20.0 + with: + token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} + commit-message: Update README.md and docs + title: Update README.md and docs + body: |- + ## what + This is an auto-generated PR that updates the README.md and docs + + ## why + To have most recent changes of README.md and doc from origin templates + + branch: auto-update/readme + base: master + delete-branch: true + labels: | + auto-update + readme diff --git a/.github/workflows/chatops.yml b/.github/workflows/chatops.yml index 0d94310..4ddc067 100644 --- a/.github/workflows/chatops.yml +++ b/.github/workflows/chatops.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: "Handle common commands" - uses: cloudposse/actions/github/slash-command-dispatch@0.16.0 + uses: cloudposse/actions/github/slash-command-dispatch@0.22.0 with: token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} reaction-token: ${{ secrets.GITHUB_TOKEN }} @@ -24,7 +24,7 @@ jobs: - name: "Checkout commit" uses: actions/checkout@v2 - name: "Run tests" - uses: cloudposse/actions/github/slash-command-dispatch@0.16.0 + uses: cloudposse/actions/github/slash-command-dispatch@0.22.0 with: token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} reaction-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/validate-codeowners.yml b/.github/workflows/validate-codeowners.yml new file mode 100644 index 0000000..8044289 --- /dev/null +++ b/.github/workflows/validate-codeowners.yml @@ -0,0 +1,18 @@ +name: Validate Codeowners +on: + pull_request: + +jobs: + validate-codeowners: + runs-on: ubuntu-latest + steps: + - name: "Checkout source code at current commit" + uses: actions/checkout@v2 + - uses: mszostok/codeowners-validator@v0.5.0 + with: + # For now, remove "files" check to allow CODEOWNERS to specify non-existent + # files so we can use the same CODEOWNERS file for Terraform and non-Terraform repos + # checks: "files,syntax,owners,duppatterns" + checks: "syntax,owners,duppatterns" + # GitHub access token is required only if the `owners` check is enabled + github_access_token: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" diff --git a/README.md b/README.md index 55514f6..19b65c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ + # terraform-tfe-cloud-infrastructure-automation [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-tfe-cloud-infrastructure-automation.svg)](https://github.com/cloudposse/terraform-tfe-cloud-infrastructure-automation/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) [![Discourse Forum](https://img.shields.io/discourse/https/ask.sweetops.com/posts.svg)](https://ask.sweetops.com/) + [![README Header][readme_header_img]][readme_header_link] @@ -66,8 +68,15 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are ## Usage -**IMPORTANT:** The `master` branch is used in `source` just as an example. In your code, do not pin to `master` because there may be breaking changes between releases. -Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-tfe-cloud-infrastructure-automation/releases). +**IMPORTANT:** We do not pin modules to versions in our examples because of the +difficulty of keeping the versions in the documentation in sync with the latest released versions. +We highly recommend that in your code you pin the version to the exact version you are +using so that your infrastructure remains stable, and update versions in a +systematic way so that they do not catch you by surprise. + +Also, because of a bug in the Terraform registry ([hashicorp/terraform#21417](https://github.com/hashicorp/terraform/issues/21417)), +the registry shows many of our inputs as required when in fact they are optional. +The table below correctly indicates which inputs are required. Here's how to invoke this example module in your projects: @@ -310,7 +319,7 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow. ## Copyrights -Copyright ยฉ 2020-2020 [Cloud Posse, LLC](https://cloudposse.com) +Copyright ยฉ 2020-2021 [Cloud Posse, LLC](https://cloudposse.com) @@ -369,8 +378,10 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply ### Contributors + | [![Erik Osterman][osterman_avatar]][osterman_homepage]
[Erik Osterman][osterman_homepage] | [![Dan Meyers][danjbh_avatar]][danjbh_homepage]
[Dan Meyers][danjbh_homepage] | |---|---| + [osterman_homepage]: https://github.com/osterman [osterman_avatar]: https://img.cloudposse.com/150x150/https://github.com/osterman.png diff --git a/context.tf b/context.tf index bae0cf1..f5f2797 100644 --- a/context.tf +++ b/context.tf @@ -19,7 +19,8 @@ # module "this" { - source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.19.2" + source = "cloudposse/label/null" + version = "0.22.1" // requires Terraform >= 0.12.26 enabled = var.enabled namespace = var.namespace diff --git a/examples/complete/context.tf b/examples/complete/context.tf index bae0cf1..f5f2797 100644 --- a/examples/complete/context.tf +++ b/examples/complete/context.tf @@ -19,7 +19,8 @@ # module "this" { - source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.19.2" + source = "cloudposse/label/null" + version = "0.22.1" // requires Terraform >= 0.12.26 enabled = var.enabled namespace = var.namespace diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index e69de29..1f7e46c 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + tfe = { + source = "hashicorp/tfe" + } + } + required_version = "" +} From 0159b0a34965918f68dc25f7e2086f34c6cb9ed4 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Sat, 9 Jan 2021 00:54:50 +0700 Subject: [PATCH 02/12] formatting fixes, workflows updated --- .github/auto-release.yml | 8 ++ .github/mergify.yml | 28 ++-- .github/renovate.json | 12 ++ .github/workflows/auto-context.yml | 6 +- .github/workflows/auto-format.yml | 86 +++++++++++ .github/workflows/auto-release.yml | 2 +- .github/workflows/validate-codeowners.yml | 7 + examples/complete/main.tf | 2 + examples/complete/versions.tf | 3 +- main.tf | 2 + modules/environment/context.tf | 168 ++++++++++++++++++++++ modules/environment/main.tf | 4 +- modules/environment/variables.tf | 2 +- modules/project/context.tf | 168 ++++++++++++++++++++++ modules/project/variables.tf | 15 +- modules/workspaces/variables.tf | 2 +- 16 files changed, 484 insertions(+), 31 deletions(-) create mode 100644 .github/renovate.json create mode 100644 .github/workflows/auto-format.yml create mode 100644 modules/environment/context.tf create mode 100644 modules/project/context.tf diff --git a/.github/auto-release.yml b/.github/auto-release.yml index 18a1ca6..c78a4d8 100644 --- a/.github/auto-release.yml +++ b/.github/auto-release.yml @@ -43,3 +43,11 @@ change-template: | template: | $CHANGES + +replacers: +# Remove irrelevant information from Renovate bot +- search: '/---\s+^#.*Renovate configuration(?:.|\n)*?This PR has been generated .*/gm' + replace: '' +# Remove Renovate bot banner image +- search: '/\[!\[[^\]]*Renovate\][^\]]*\](\([^)]*\))?\s*\n+/gm' + replace: '' diff --git a/.github/mergify.yml b/.github/mergify.yml index 485982f..b010656 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -1,12 +1,16 @@ +# https://docs.mergify.io/conditions.html +# https://docs.mergify.io/actions.html pull_request_rules: - name: "approve automated PRs that have passed checks" conditions: - - "check-success~=test/bats" - - "check-success~=test/readme" - - "check-success~=test/terratest" + - "author~=^(cloudpossebot|renovate\\[bot\\])$" - "base=master" - - "author=cloudpossebot" - - "head~=auto-update/.*" + - "-closed" + - "head~=^(auto-update|renovate)/.*" + - "check-success=test/bats" + - "check-success=test/readme" + - "check-success=test/terratest" + - "check-success=validate-codeowners" actions: review: type: "APPROVE" @@ -15,16 +19,17 @@ pull_request_rules: - name: "merge automated PRs when approved and tests pass" conditions: - - "check-success~=test/bats" - - "check-success~=test/readme" - - "check-success~=test/terratest" + - "author~=^(cloudpossebot|renovate\\[bot\\])$" - "base=master" - - "head~=auto-update/.*" + - "-closed" + - "head~=^(auto-update|renovate)/.*" + - "check-success=test/bats" + - "check-success=test/readme" + - "check-success=test/terratest" + - "check-success=validate-codeowners" - "#approved-reviews-by>=1" - "#changes-requested-reviews-by=0" - "#commented-reviews-by=0" - - "base=master" - - "author=cloudpossebot" actions: merge: method: "squash" @@ -38,6 +43,7 @@ pull_request_rules: - name: "ask to resolve conflict" conditions: - "conflict" + - "-closed" actions: comment: message: "This pull request is now in conflict. Could you fix it @{{author}}? ๐Ÿ™" diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..ae4f0aa --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,12 @@ +{ + "extends": [ + "config:base", + ":preserveSemverRanges" + ], + "labels": ["auto-update"], + "enabledManagers": ["terraform"], + "terraform": { + "ignorePaths": ["**/context.tf", "examples/**"] + } +} + diff --git a/.github/workflows/auto-context.yml b/.github/workflows/auto-context.yml index 739a3c9..ab979e0 100644 --- a/.github/workflows/auto-context.yml +++ b/.github/workflows/auto-context.yml @@ -27,17 +27,19 @@ jobs: make init make github/init/context.tf make readme/build - echo "::set-output name=create_pull_request=true" + echo "::set-output name=create_pull_request::true" fi else echo "This module has not yet been updated to support the context.tf pattern! Please update in order to support automatic updates." fi - name: Create Pull Request - if: {{ steps.update.outputs.create_pull_request == 'true' }} + if: steps.update.outputs.create_pull_request == 'true' uses: cloudposse/actions/github/create-pull-request@0.22.0 with: token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} + committer: 'cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>' + author: 'cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>' commit-message: Update context.tf from origin source title: Update context.tf body: |- diff --git a/.github/workflows/auto-format.yml b/.github/workflows/auto-format.yml new file mode 100644 index 0000000..990abed --- /dev/null +++ b/.github/workflows/auto-format.yml @@ -0,0 +1,86 @@ +name: Auto Format +on: + pull_request_target: + types: [opened, synchronize] + +jobs: + auto-format: + runs-on: ubuntu-latest + container: cloudposse/build-harness:slim-latest + steps: + # Checkout the pull request branch + # "An action in a workflow run canโ€™t trigger a new workflow run. For example, if an action pushes code using + # the repositoryโ€™s GITHUB_TOKEN, a new workflow will not run even when the repository contains + # a workflow configured to run when push events occur." + # However, using a personal access token will cause events to be triggered. + # We need that to ensure a status gets posted after the auto-format commit. + # We also want to trigger tests if the auto-format made no changes. + - uses: actions/checkout@v2 + if: github.event.pull_request.state == 'open' + name: Privileged Checkout + with: + token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + # Check out the PR commit, not the merge commit + # Use `ref` instead of `sha` to enable pushing back to `ref` + ref: ${{ github.event.pull_request.head.ref }} + + # Do all the formatting stuff + - name: Auto Format + if: github.event.pull_request.state == 'open' + shell: bash + run: make BUILD_HARNESS_PATH=/build-harness PACKAGES_PREFER_HOST=true -f /build-harness/templates/Makefile.build-harness pr/auto-format/host + + # Commit changes (if any) to the PR branch + - name: Commit changes to the PR branch + if: github.event.pull_request.state == 'open' + shell: bash + id: commit + env: + SENDER: ${{ github.event.sender.login }} + run: | + set -x + output=$(git diff --name-only) + + if [ -n "$output" ]; then + echo "Changes detected. Pushing to the PR branch" + git config --global user.name 'cloudpossebot' + git config --global user.email '11232728+cloudpossebot@users.noreply.github.com' + git add -A + git commit -m "Auto Format" + # Prevent looping by not pushing changes in response to changes from cloudpossebot + [[ $SENDER == "cloudpossebot" ]] || git push + # Set status to fail, because the push should trigger another status check, + # and we use success to indicate the checks are finished. + printf "::set-output name=%s::%s\n" "changed" "true" + exit 1 + else + printf "::set-output name=%s::%s\n" "changed" "false" + echo "No changes detected" + fi + + - name: Auto Test + uses: cloudposse/actions/github/repository-dispatch@0.22.0 + # match users by ID because logins (user names) are inconsistent, + # for example in the REST API Renovate Bot is `renovate[bot]` but + # in GraphQL it is just `renovate`, plus there is a non-bot + # user `renovate` with ID 1832810. + # Mergify bot: 37929162 + # Renovate bot: 29139614 + # Cloudpossebot: 11232728 + # Need to use space separators to prevent "21" from matching "112144" + if: > + contains(' 37929162 29139614 11232728 ', format(' {0} ', github.event.pull_request.user.id)) + && steps.commit.outputs.changed == 'false' && github.event.pull_request.state == 'open' + with: + token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }} + repository: cloudposse/actions + event-type: test-command + client-payload: |- + { "slash_command":{"args": {"unnamed": {"all": "all", "arg1": "all"}}}, + "pull_request": ${{ toJSON(github.event.pull_request) }}, + "github":{"payload":{"repository": ${{ toJSON(github.event.repository) }}, + "comment": {"id": ""} + } + } + } diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index ccc27be..3f48017 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -6,7 +6,7 @@ on: - master jobs: - semver: + publish: runs-on: ubuntu-latest steps: # Drafts your next Release notes as Pull Requests are merged into "master" diff --git a/.github/workflows/validate-codeowners.yml b/.github/workflows/validate-codeowners.yml index 8044289..386eb28 100644 --- a/.github/workflows/validate-codeowners.yml +++ b/.github/workflows/validate-codeowners.yml @@ -9,6 +9,8 @@ jobs: - name: "Checkout source code at current commit" uses: actions/checkout@v2 - uses: mszostok/codeowners-validator@v0.5.0 + if: github.event.pull_request.head.repo.full_name == github.repository + name: "Full check of CODEOWNERS" with: # For now, remove "files" check to allow CODEOWNERS to specify non-existent # files so we can use the same CODEOWNERS file for Terraform and non-Terraform repos @@ -16,3 +18,8 @@ jobs: checks: "syntax,owners,duppatterns" # GitHub access token is required only if the `owners` check is enabled github_access_token: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}" + - uses: mszostok/codeowners-validator@v0.5.0 + if: github.event.pull_request.head.repo.full_name != github.repository + name: "Syntax check of CODEOWNERS" + with: + checks: "syntax,duppatterns" diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 7adc29a..2c43cfe 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -17,4 +17,6 @@ module "example" { ingress_submodules = var.ingress_submodules oauth_token_id = var.oauth_token_id } + + context = module.this.context } diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf index 1f7e46c..34c7ded 100644 --- a/examples/complete/versions.tf +++ b/examples/complete/versions.tf @@ -1,8 +1,9 @@ terraform { + required_version = ">= 0.13.0" + required_providers { tfe = { source = "hashicorp/tfe" } } - required_version = "" } diff --git a/main.tf b/main.tf index ab9f5f6..8be23d2 100644 --- a/main.tf +++ b/main.tf @@ -63,6 +63,8 @@ module "tfc_environment" { projects_path = var.projects_path organization = var.organization vcs_repo = var.vcs_repo + + context = module.this.context } # Generate our custom triggers based on configuration defined in YAML (at the project level) diff --git a/modules/environment/context.tf b/modules/environment/context.tf new file mode 100644 index 0000000..f5f2797 --- /dev/null +++ b/modules/environment/context.tf @@ -0,0 +1,168 @@ +# +# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label +# All other instances of this file should be a copy of that one +# +# +# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf +# and then place it in your Terraform module to automatically get +# Cloud Posse's standard configuration inputs suitable for passing +# to Cloud Posse modules. +# +# Modules should access the whole context as `module.this.context` +# to get the input variables with nulls for defaults, +# for example `context = module.this.context`, +# and access individual variables as `module.this.`, +# with final values filled in. +# +# For example, when using defaults, `module.this.context.delimiter` +# will be null, and `module.this.delimiter` will be `-` (hyphen). +# + +module "this" { + source = "cloudposse/label/null" + version = "0.22.1" // requires Terraform >= 0.12.26 + + enabled = var.enabled + namespace = var.namespace + environment = var.environment + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags + additional_tag_map = var.additional_tag_map + label_order = var.label_order + regex_replace_chars = var.regex_replace_chars + id_length_limit = var.id_length_limit + + context = var.context +} + +# Copy contents of cloudposse/terraform-null-label/variables.tf here + +variable "context" { + type = object({ + enabled = bool + namespace = string + environment = string + stage = string + name = string + delimiter = string + attributes = list(string) + tags = map(string) + additional_tag_map = map(string) + regex_replace_chars = string + label_order = list(string) + id_length_limit = number + }) + default = { + enabled = true + namespace = null + environment = null + stage = null + name = null + delimiter = null + attributes = [] + tags = {} + additional_tag_map = {} + regex_replace_chars = null + label_order = [] + id_length_limit = null + } + description = <<-EOT + Single object for setting entire context at once. + See description of individual variables for details. + Leave string and numeric variables as `null` to use default value. + Individual variable settings (non-null) override settings in context object, + except for attributes, tags, and additional_tag_map, which are merged. + EOT +} + +variable "enabled" { + type = bool + default = null + description = "Set to false to prevent the module from creating any resources" +} + +variable "namespace" { + type = string + default = null + description = "Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp'" +} + +variable "environment" { + type = string + default = null + description = "Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT'" +} + +variable "stage" { + type = string + default = null + description = "Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release'" +} + +variable "name" { + type = string + default = null + description = "Solution name, e.g. 'app' or 'jenkins'" +} + +variable "delimiter" { + type = string + default = null + description = <<-EOT + Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`. + Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. + EOT +} + +variable "attributes" { + type = list(string) + default = [] + description = "Additional attributes (e.g. `1`)" +} + +variable "tags" { + type = map(string) + default = {} + description = "Additional tags (e.g. `map('BusinessUnit','XYZ')`" +} + +variable "additional_tag_map" { + type = map(string) + default = {} + description = "Additional tags for appending to tags_as_list_of_maps. Not added to `tags`." +} + +variable "label_order" { + type = list(string) + default = null + description = <<-EOT + The naming order of the id output and Name tag. + Defaults to ["namespace", "environment", "stage", "name", "attributes"]. + You can omit any of the 5 elements, but at least one must be present. + EOT +} + +variable "regex_replace_chars" { + type = string + default = null + description = <<-EOT + Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. + If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. + EOT +} + +variable "id_length_limit" { + type = number + default = null + description = <<-EOT + Limit `id` to this many characters. + Set to `0` for unlimited length. + Set to `null` for default, which is `0`. + Does not affect `id_full`. + EOT +} + +#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/modules/environment/main.tf b/modules/environment/main.tf index 0d3b981..4a26d22 100644 --- a/modules/environment/main.tf +++ b/modules/environment/main.tf @@ -35,4 +35,6 @@ module "projects" { parent_workspace_id = module.workspace.workspace.id auto_apply = try(each.value.auto_apply, false) filename_trigger = try(each.value.filename_trigger, "*.tf") -} \ No newline at end of file + + context = module.this.context +} diff --git a/modules/environment/variables.tf b/modules/environment/variables.tf index 1f5625e..a132044 100644 --- a/modules/environment/variables.tf +++ b/modules/environment/variables.tf @@ -10,7 +10,7 @@ variable "config_directory" { } variable "global_values" { - type = map + type = map(any) default = {} description = "The global values applied to all workspaces within the environment." } diff --git a/modules/project/context.tf b/modules/project/context.tf new file mode 100644 index 0000000..f5f2797 --- /dev/null +++ b/modules/project/context.tf @@ -0,0 +1,168 @@ +# +# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label +# All other instances of this file should be a copy of that one +# +# +# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf +# and then place it in your Terraform module to automatically get +# Cloud Posse's standard configuration inputs suitable for passing +# to Cloud Posse modules. +# +# Modules should access the whole context as `module.this.context` +# to get the input variables with nulls for defaults, +# for example `context = module.this.context`, +# and access individual variables as `module.this.`, +# with final values filled in. +# +# For example, when using defaults, `module.this.context.delimiter` +# will be null, and `module.this.delimiter` will be `-` (hyphen). +# + +module "this" { + source = "cloudposse/label/null" + version = "0.22.1" // requires Terraform >= 0.12.26 + + enabled = var.enabled + namespace = var.namespace + environment = var.environment + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags + additional_tag_map = var.additional_tag_map + label_order = var.label_order + regex_replace_chars = var.regex_replace_chars + id_length_limit = var.id_length_limit + + context = var.context +} + +# Copy contents of cloudposse/terraform-null-label/variables.tf here + +variable "context" { + type = object({ + enabled = bool + namespace = string + environment = string + stage = string + name = string + delimiter = string + attributes = list(string) + tags = map(string) + additional_tag_map = map(string) + regex_replace_chars = string + label_order = list(string) + id_length_limit = number + }) + default = { + enabled = true + namespace = null + environment = null + stage = null + name = null + delimiter = null + attributes = [] + tags = {} + additional_tag_map = {} + regex_replace_chars = null + label_order = [] + id_length_limit = null + } + description = <<-EOT + Single object for setting entire context at once. + See description of individual variables for details. + Leave string and numeric variables as `null` to use default value. + Individual variable settings (non-null) override settings in context object, + except for attributes, tags, and additional_tag_map, which are merged. + EOT +} + +variable "enabled" { + type = bool + default = null + description = "Set to false to prevent the module from creating any resources" +} + +variable "namespace" { + type = string + default = null + description = "Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp'" +} + +variable "environment" { + type = string + default = null + description = "Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT'" +} + +variable "stage" { + type = string + default = null + description = "Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release'" +} + +variable "name" { + type = string + default = null + description = "Solution name, e.g. 'app' or 'jenkins'" +} + +variable "delimiter" { + type = string + default = null + description = <<-EOT + Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`. + Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. + EOT +} + +variable "attributes" { + type = list(string) + default = [] + description = "Additional attributes (e.g. `1`)" +} + +variable "tags" { + type = map(string) + default = {} + description = "Additional tags (e.g. `map('BusinessUnit','XYZ')`" +} + +variable "additional_tag_map" { + type = map(string) + default = {} + description = "Additional tags for appending to tags_as_list_of_maps. Not added to `tags`." +} + +variable "label_order" { + type = list(string) + default = null + description = <<-EOT + The naming order of the id output and Name tag. + Defaults to ["namespace", "environment", "stage", "name", "attributes"]. + You can omit any of the 5 elements, but at least one must be present. + EOT +} + +variable "regex_replace_chars" { + type = string + default = null + description = <<-EOT + Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. + If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. + EOT +} + +variable "id_length_limit" { + type = number + default = null + description = <<-EOT + Limit `id` to this many characters. + Set to `0` for unlimited length. + Set to `null` for default, which is `0`. + Does not affect `id_full`. + EOT +} + +#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/modules/project/variables.tf b/modules/project/variables.tf index c08a05a..c98593c 100644 --- a/modules/project/variables.tf +++ b/modules/project/variables.tf @@ -1,32 +1,21 @@ -variable "enabled" { - description = "Controls creation fo all resources in this module." - default = false - type = bool -} - variable "parent_workspace_id" { description = "Parent workspace ID for run triggers." default = null type = string } -variable "environment" { - description = "Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT'" - type = string -} - variable "project_name" { type = string description = "Name of the project" } variable "project_values" { - type = map + type = map(any) description = "Map of project-level environment variables" } variable "global_values" { - type = map + type = map(any) description = "Map of project-level Terraform variables" } diff --git a/modules/workspaces/variables.tf b/modules/workspaces/variables.tf index cdb923d..c018276 100644 --- a/modules/workspaces/variables.tf +++ b/modules/workspaces/variables.tf @@ -55,7 +55,7 @@ variable "terraform_version" { variable "trigger_prefixes" { description = "List of paths relative to the repository root which describe all locations to be tracked for changes in the workspace." default = null - type = list + type = list(any) } variable "variables" { From 19f3d95e8c3459b0795097ecfc90421143cb473e Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Sat, 9 Jan 2021 00:59:46 +0700 Subject: [PATCH 03/12] fixtures renamed --- examples/complete/{fixtures.tfvars => fixtures.us-east-2.tfvars} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/complete/{fixtures.tfvars => fixtures.us-east-2.tfvars} (100%) diff --git a/examples/complete/fixtures.tfvars b/examples/complete/fixtures.us-east-2.tfvars similarity index 100% rename from examples/complete/fixtures.tfvars rename to examples/complete/fixtures.us-east-2.tfvars From b930ca6ec399495109ddaccf43248aa6318c6f51 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 15:54:01 +0700 Subject: [PATCH 04/12] tests triage --- .gitignore | 1 + test/src/examples_complete_test.go | 46 ++++-------------------------- 2 files changed, 7 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index 5051e6c..237418a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.tfstate.* .terraform .terraform.tfstate.lock.info +**/.terraform.lock.hcl **/.idea **/*.iml diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index d14510d..e58a878 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -16,8 +16,6 @@ func TestExamplesComplete(t *testing.T) { randId := strconv.Itoa(rand.Intn(100000)) attributes := []string{randId} - exampleInput := "Hello, world!" - terraformOptions := &terraform.Options{ // The path to where our Terraform code is located TerraformDir: "../../examples/complete", @@ -28,7 +26,6 @@ func TestExamplesComplete(t *testing.T) { // and AWS resources do not interfere with each other Vars: map[string]interface{}{ "attributes": attributes, - "example": exampleInput, }, } // At the end of the test, run `terraform destroy` to clean up any resources that were created @@ -38,44 +35,13 @@ func TestExamplesComplete(t *testing.T) { terraform.InitAndApply(t, terraformOptions) // Run `terraform output` to get the value of an output variable - id := terraform.Output(t, terraformOptions, "id") - example := terraform.Output(t, terraformOptions, "example") - random := terraform.Output(t, terraformOptions, "random") + globalWorkspace := terraform.Output(t, terraformOptions, "global_workspace") + environmentWorkspaces := terraform.Output(t, terraformOptions, "environment_workspaces") + projectWorkspaces := terraform.Output(t, terraformOptions, "project_workspaces") // Verify we're getting back the outputs we expect // Ensure we get a random number appended - assert.Equal(t, exampleInput+" "+random, example) - // Ensure we get the attribute included in the ID - assert.Equal(t, "eg-ue2-test-example-"+randId, id) - - // ************************************************************************ - // This steps below are unusual, not generally part of the testing - // but included here as an example of testing this specific module. - // This module has a random number that is supposed to change - // only when the example changes. So we run it again to ensure - // it does not change. - - // This will run `terraform apply` a second time and fail the test if there are any errors - terraform.Apply(t, terraformOptions) - - id2 := terraform.Output(t, terraformOptions, "id") - example2 := terraform.Output(t, terraformOptions, "example") - random2 := terraform.Output(t, terraformOptions, "random") - - assert.Equal(t, id, id2, "Expected `id` to be stable") - assert.Equal(t, example, example2, "Expected `example` to be stable") - assert.Equal(t, random, random2, "Expected `random` to be stable") - - // Then we run change the example and run it a third time and - // verify that the random number changed - newExample := "Goodbye" - terraformOptions.Vars["example"] = newExample - terraform.Apply(t, terraformOptions) - - example3 := terraform.Output(t, terraformOptions, "example") - random3 := terraform.Output(t, terraformOptions, "random") - - assert.NotEqual(t, random, random3, "Expected `random` to change when `example` changed") - assert.Equal(t, newExample+" "+random3, example3, "Expected `example` to use new random number") - + assert.Equal(t, "eg-ue2-test-example-"+randId, globalWorkspace) + assert.Equal(t, "eg-ue2-test-example-"+randId, environmentWorkspaces) + assert.Equal(t, "eg-ue2-test-example-"+randId, projectWorkspaces) } From 45d321a61b452d11f1537f112cb31147a9eb1891 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 16:19:44 +0700 Subject: [PATCH 05/12] tests triage --- test/src/examples_complete_test.go | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index e58a878..f853557 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -1,8 +1,6 @@ package test import ( - "math/rand" - "strconv" "testing" "github.com/gruntwork-io/terratest/modules/terraform" @@ -13,20 +11,12 @@ import ( func TestExamplesComplete(t *testing.T) { t.Parallel() - randId := strconv.Itoa(rand.Intn(100000)) - attributes := []string{randId} - terraformOptions := &terraform.Options{ // The path to where our Terraform code is located TerraformDir: "../../examples/complete", Upgrade: true, // Variables to pass to our Terraform code using -var-file options VarFiles: []string{"fixtures.us-east-2.tfvars"}, - // We always include a random attribute so that parallel tests - // and AWS resources do not interfere with each other - Vars: map[string]interface{}{ - "attributes": attributes, - }, } // At the end of the test, run `terraform destroy` to clean up any resources that were created defer terraform.Destroy(t, terraformOptions) @@ -35,13 +25,13 @@ func TestExamplesComplete(t *testing.T) { terraform.InitAndApply(t, terraformOptions) // Run `terraform output` to get the value of an output variable - globalWorkspace := terraform.Output(t, terraformOptions, "global_workspace") - environmentWorkspaces := terraform.Output(t, terraformOptions, "environment_workspaces") - projectWorkspaces := terraform.Output(t, terraformOptions, "project_workspaces") + example := terraform.OutputMapOfObjects(t, terraformOptions, "example") // Verify we're getting back the outputs we expect // Ensure we get a random number appended - assert.Equal(t, "eg-ue2-test-example-"+randId, globalWorkspace) - assert.Equal(t, "eg-ue2-test-example-"+randId, environmentWorkspaces) - assert.Equal(t, "eg-ue2-test-example-"+randId, projectWorkspaces) + if assert.NotEmpty(t, example) { + assert.NotEmpty(t, example["global_workspace"]) + assert.NotEmpty(t, example["environment_workspaces"]) + assert.NotEmpty(t, example["project_workspaces"]) + } } From 412ebec9b4a85c940a3aa8ffe117c5c971b06a81 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 17:34:01 +0700 Subject: [PATCH 06/12] tests triage --- examples/complete/outputs.tf | 14 ++++++++++++++ test/src/examples_complete_test.go | 21 +++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index e3a7c30..58c9186 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -3,3 +3,17 @@ output "example" { value = module.example } +output "global_workspace_id" { + description = "Environment workspaces ids" + value = module.example.global_workspace.id +} + +output "environment_workspaces_ids" { + description = "Environment workspaces ids" + value = module.example.environment_workspaces[*].workspace.id +} + +output "project_workspaces_ids" { + description = "Environment workspaces ids" + value = module.example.project_workspaces[*].workspace.id +} diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index f853557..74d8259 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -25,13 +25,22 @@ func TestExamplesComplete(t *testing.T) { terraform.InitAndApply(t, terraformOptions) // Run `terraform output` to get the value of an output variable - example := terraform.OutputMapOfObjects(t, terraformOptions, "example") + environmentWorkspacesIds := terraform.OutputList(t, terraformOptions, "environment_workspaces_ids") + globalWorkspaceId := terraform.Output(t, terraformOptions, "global_workspace_id") + projectWorkspacesIds := terraform.OutputList(t, terraformOptions, "project_workspaces_ids") // Verify we're getting back the outputs we expect // Ensure we get a random number appended - if assert.NotEmpty(t, example) { - assert.NotEmpty(t, example["global_workspace"]) - assert.NotEmpty(t, example["environment_workspaces"]) - assert.NotEmpty(t, example["project_workspaces"]) - } + + assert.Regexp(t, "^ws-\\w{16}$", globalWorkspaceId) + if assert.NotEmpty(t, environmentWorkspacesIds) { + for _, item := range environmentWorkspacesIds { + assert.Regexp(t, "^ws-\\w{16}$", item) + } + } + if assert.NotEmpty(t, projectWorkspacesIds) { + for _, item := range projectWorkspacesIds { + assert.Regexp(t, "^ws-\\w{16}$", item) + } + } } From 6a9f11e2363fbafb4063028fc8ef8523f0eabdab Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 17:56:19 +0700 Subject: [PATCH 07/12] tests triage --- examples/complete/outputs.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 58c9186..47e7b1f 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -10,10 +10,10 @@ output "global_workspace_id" { output "environment_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.environment_workspaces[*].workspace.id + value = module.example.environment_workspaces } output "project_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.project_workspaces[*].workspace.id + value = module.example.project_workspaces } From ea0f876d6a77b020b846c97e2c0c15aa3043c999 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 18:08:11 +0700 Subject: [PATCH 08/12] tests triage --- test/src/examples_complete_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 74d8259..5e7c8c8 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -25,18 +25,20 @@ func TestExamplesComplete(t *testing.T) { terraform.InitAndApply(t, terraformOptions) // Run `terraform output` to get the value of an output variable - environmentWorkspacesIds := terraform.OutputList(t, terraformOptions, "environment_workspaces_ids") + environmentWorkspacesIds := terraform.OutputMapOfObjects(t, terraformOptions, "environment_workspaces_ids") globalWorkspaceId := terraform.Output(t, terraformOptions, "global_workspace_id") - projectWorkspacesIds := terraform.OutputList(t, terraformOptions, "project_workspaces_ids") + projectWorkspacesIds := terraform.OutputMapOfObjects(t, terraformOptions, "project_workspaces_ids") // Verify we're getting back the outputs we expect // Ensure we get a random number appended assert.Regexp(t, "^ws-\\w{16}$", globalWorkspaceId) if assert.NotEmpty(t, environmentWorkspacesIds) { - for _, item := range environmentWorkspacesIds { - assert.Regexp(t, "^ws-\\w{16}$", item) - } + assert.Regexp(t, "^ws-\\w{16}$", environmentWorkspacesIds["id"]) + +// for _, item := range environmentWorkspacesIds { +// assert.Regexp(t, "^ws-\\w{16}$", item) +// } } if assert.NotEmpty(t, projectWorkspacesIds) { for _, item := range projectWorkspacesIds { From 12199a51be8706d7008ffbaefcec63659ee8de25 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 18:30:26 +0700 Subject: [PATCH 09/12] tests triage --- examples/complete/outputs.tf | 4 ++-- test/src/examples_complete_test.go | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 47e7b1f..5c6243d 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -10,10 +10,10 @@ output "global_workspace_id" { output "environment_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.environment_workspaces + value = module.example.environment_workspaces.*.workspace.id } output "project_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.project_workspaces + value = module.example.project_workspaces.*.workspace.id } diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 5e7c8c8..74d8259 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -25,20 +25,18 @@ func TestExamplesComplete(t *testing.T) { terraform.InitAndApply(t, terraformOptions) // Run `terraform output` to get the value of an output variable - environmentWorkspacesIds := terraform.OutputMapOfObjects(t, terraformOptions, "environment_workspaces_ids") + environmentWorkspacesIds := terraform.OutputList(t, terraformOptions, "environment_workspaces_ids") globalWorkspaceId := terraform.Output(t, terraformOptions, "global_workspace_id") - projectWorkspacesIds := terraform.OutputMapOfObjects(t, terraformOptions, "project_workspaces_ids") + projectWorkspacesIds := terraform.OutputList(t, terraformOptions, "project_workspaces_ids") // Verify we're getting back the outputs we expect // Ensure we get a random number appended assert.Regexp(t, "^ws-\\w{16}$", globalWorkspaceId) if assert.NotEmpty(t, environmentWorkspacesIds) { - assert.Regexp(t, "^ws-\\w{16}$", environmentWorkspacesIds["id"]) - -// for _, item := range environmentWorkspacesIds { -// assert.Regexp(t, "^ws-\\w{16}$", item) -// } + for _, item := range environmentWorkspacesIds { + assert.Regexp(t, "^ws-\\w{16}$", item) + } } if assert.NotEmpty(t, projectWorkspacesIds) { for _, item := range projectWorkspacesIds { From f456ae73905c353e38058df12b84b329e2555f8c Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 18:47:50 +0700 Subject: [PATCH 10/12] tests triage --- examples/complete/outputs.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 5c6243d..54ab2b2 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -10,10 +10,10 @@ output "global_workspace_id" { output "environment_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.environment_workspaces.*.workspace.id + value = module.example.environment_workspaces[*].id } output "project_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.project_workspaces.*.workspace.id + value = module.example.project_workspaces[*].id } From 01ca558c2451d484d962bd72b46deebbc2f11ed0 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 19:24:48 +0700 Subject: [PATCH 11/12] tests triage --- examples/complete/outputs.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 54ab2b2..0a8d363 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -10,10 +10,10 @@ output "global_workspace_id" { output "environment_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.environment_workspaces[*].id + value = values(module.example.environment_workspaces)[*].id } output "project_workspaces_ids" { description = "Environment workspaces ids" - value = module.example.project_workspaces[*].id + value = values(module.example.project_workspaces)[*].id } From e6101833f5d31bd878577071abe23a986ee5b5a4 Mon Sep 17 00:00:00 2001 From: Maxim Mironenko Date: Mon, 11 Jan 2021 19:31:41 +0700 Subject: [PATCH 12/12] tests triage --- examples/complete/outputs.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 0a8d363..7b577ef 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -10,10 +10,10 @@ output "global_workspace_id" { output "environment_workspaces_ids" { description = "Environment workspaces ids" - value = values(module.example.environment_workspaces)[*].id + value = values(module.example.environment_workspaces)[*].workspace.id } output "project_workspaces_ids" { description = "Environment workspaces ids" - value = values(module.example.project_workspaces)[*].id + value = values(module.example.project_workspaces)[*].workspace.id }