├── .editorconfig
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── bug_report.yml
│ ├── config.yml
│ ├── feature_request.md
│ ├── feature_request.yml
│ └── question.md
├── PULL_REQUEST_TEMPLATE.md
├── banner.png
├── mergify.yml
├── renovate.json
├── settings.yml
└── workflows
│ ├── branch.yml
│ ├── chatops.yml
│ ├── release.yml
│ └── scheduled.yml
├── .gitignore
├── LICENSE
├── README.md
├── README.yaml
├── atmos.yaml
├── context.tf
├── examples
├── backend
│ ├── atmos.yaml
│ ├── context.tf
│ ├── fixtures.tfvars
│ ├── main.tf
│ ├── outputs.tf
│ ├── stacks
│ │ ├── catalog
│ │ │ ├── helmfile
│ │ │ │ ├── echo-server.yaml
│ │ │ │ └── infra-server.yaml
│ │ │ └── terraform
│ │ │ │ ├── services
│ │ │ │ ├── service-1-override.yaml
│ │ │ │ ├── service-1.yaml
│ │ │ │ ├── service-2-override.yaml
│ │ │ │ ├── service-2.yaml
│ │ │ │ ├── top-level-service-1.yaml
│ │ │ │ └── top-level-service-2.yaml
│ │ │ │ ├── tenant1-ue2-dev.yaml
│ │ │ │ ├── test-component-override.yaml
│ │ │ │ ├── test-component.yaml
│ │ │ │ ├── top-level-component1.yaml
│ │ │ │ └── vpc.yaml
│ │ ├── globals
│ │ │ ├── globals.yaml
│ │ │ ├── tenant1-globals.yaml
│ │ │ ├── tenant2-globals.yaml
│ │ │ └── ue2-globals.yaml
│ │ ├── tenant1
│ │ │ └── ue2
│ │ │ │ ├── dev.yaml
│ │ │ │ ├── prod.yaml
│ │ │ │ └── staging.yaml
│ │ └── tenant2
│ │ │ └── ue2
│ │ │ ├── dev.yaml
│ │ │ ├── prod.yaml
│ │ │ └── staging.yaml
│ ├── variables.tf
│ └── versions.tf
├── complete
│ ├── atmos.yaml
│ ├── context.tf
│ ├── fixtures.tfvars
│ ├── main.tf
│ ├── outputs.tf
│ ├── stacks
│ │ ├── imports-level-2.yaml
│ │ ├── imports-level-3.yaml
│ │ ├── imports-level-3a.yaml
│ │ ├── imports-level-4.yaml
│ │ └── my-stack.yaml
│ ├── variables.tf
│ └── versions.tf
├── remote-state
│ ├── atmos.yaml
│ ├── context.tf
│ ├── fixtures.tfvars
│ ├── main.tf
│ ├── outputs.tf
│ ├── stacks
│ │ ├── catalog
│ │ │ ├── helmfile
│ │ │ │ ├── echo-server.yaml
│ │ │ │ └── infra-server.yaml
│ │ │ └── terraform
│ │ │ │ ├── services
│ │ │ │ ├── service-1-override.yaml
│ │ │ │ ├── service-1.yaml
│ │ │ │ ├── service-2-override.yaml
│ │ │ │ ├── service-2.yaml
│ │ │ │ ├── top-level-service-1.yaml
│ │ │ │ └── top-level-service-2.yaml
│ │ │ │ ├── tenant1-ue2-dev.yaml
│ │ │ │ ├── test-component-override.yaml
│ │ │ │ ├── test-component.yaml
│ │ │ │ ├── top-level-component1.yaml
│ │ │ │ └── vpc.yaml
│ │ ├── globals
│ │ │ ├── globals.yaml
│ │ │ ├── tenant1-globals.yaml
│ │ │ ├── tenant2-globals.yaml
│ │ │ └── ue2-globals.yaml
│ │ ├── tenant1
│ │ │ └── ue2
│ │ │ │ ├── dev.yaml
│ │ │ │ ├── prod.yaml
│ │ │ │ └── staging.yaml
│ │ └── tenant2
│ │ │ └── ue2
│ │ │ ├── dev.yaml
│ │ │ ├── prod.yaml
│ │ │ └── staging.yaml
│ ├── variables.tf
│ └── versions.tf
├── spacelift
│ ├── atmos.yaml
│ ├── context.tf
│ ├── fixtures.tfvars
│ ├── main.tf
│ ├── outputs.tf
│ ├── stacks
│ │ ├── catalog
│ │ │ ├── helmfile
│ │ │ │ ├── echo-server.yaml
│ │ │ │ ├── infra-server-override.yaml
│ │ │ │ └── infra-server.yaml
│ │ │ └── terraform
│ │ │ │ ├── mixins
│ │ │ │ ├── test-1.yaml
│ │ │ │ └── test-2.yaml
│ │ │ │ ├── services
│ │ │ │ ├── service-1-override-2.yaml
│ │ │ │ ├── service-1-override.yaml
│ │ │ │ ├── service-1.yaml
│ │ │ │ ├── service-2-override-2.yaml
│ │ │ │ ├── service-2-override.yaml
│ │ │ │ ├── service-2.yaml
│ │ │ │ ├── top-level-service-1.yaml
│ │ │ │ └── top-level-service-2.yaml
│ │ │ │ ├── tenant1-ue2-dev.yaml
│ │ │ │ ├── test-component-override-2.yaml
│ │ │ │ ├── test-component-override-3.yaml
│ │ │ │ ├── test-component-override.yaml
│ │ │ │ ├── test-component.yaml
│ │ │ │ ├── top-level-component1.yaml
│ │ │ │ └── vpc.yaml
│ │ ├── globals
│ │ │ ├── globals.yaml
│ │ │ ├── tenant1-globals.yaml
│ │ │ ├── tenant2-globals.yaml
│ │ │ └── ue2-globals.yaml
│ │ ├── tenant1
│ │ │ └── ue2
│ │ │ │ ├── dev.yaml
│ │ │ │ ├── prod.yaml
│ │ │ │ └── staging.yaml
│ │ └── tenant2
│ │ │ └── ue2
│ │ │ ├── dev.yaml
│ │ │ ├── prod.yaml
│ │ │ └── staging.yaml
│ ├── variables.tf
│ └── versions.tf
├── stack
│ ├── context.tf
│ ├── fixtures.tfvars
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
└── stacks
│ ├── README.md
│ ├── atmos.yaml
│ ├── context.tf
│ ├── fixtures.tfvars
│ ├── main.tf
│ ├── outputs.tf
│ ├── stacks
│ ├── eks
│ │ └── eks-defaults.yaml
│ ├── globals.yaml
│ ├── uw2-dev.yaml
│ ├── uw2-globals.yaml
│ ├── uw2-prod.yaml
│ ├── uw2-staging.yaml
│ └── uw2-uat.yaml
│ ├── variables.tf
│ └── versions.tf
├── main.tf
├── modules
├── backend
│ ├── README.md
│ ├── context-always.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
├── env
│ ├── README.md
│ ├── context-always.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
├── remote-state
│ ├── README.md
│ ├── context-always.tf
│ ├── data-source.tf
│ ├── dummy-remote-state.json
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
├── settings
│ ├── README.md
│ ├── context-always.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
├── spacelift
│ ├── README.md
│ ├── context-always.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
├── stack
│ ├── README.md
│ ├── context-always.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
└── vars
│ ├── README.md
│ ├── context-always.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── versions.tf
├── outputs.tf
├── test
├── .gitignore
├── Makefile
├── Makefile.alpine
└── src
│ ├── .gitignore
│ ├── Makefile
│ ├── examples_backend_test.go
│ ├── examples_complete_test.go
│ ├── examples_remote_state_test.go
│ ├── examples_spacelift_test.go
│ ├── examples_stack_test.go
│ ├── examples_stacks_test.go
│ ├── go.mod
│ └── go.sum
├── variables.tf
└── versions.tf
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Unix-style newlines with a newline ending every file
2 | [*]
3 | charset = utf-8
4 | end_of_line = lf
5 | indent_size = 2
6 | indent_style = space
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | [*.{tf,tfvars}]
11 | indent_size = 2
12 | indent_style = space
13 |
14 | [*.md]
15 | max_line_length = 0
16 | trim_trailing_whitespace = false
17 |
18 | # Override for Makefile
19 | [{Makefile, makefile, GNUmakefile, Makefile.*}]
20 | tab_width = 2
21 | indent_style = tab
22 | indent_size = 4
23 |
24 | [COMMIT_EDITMSG]
25 | max_line_length = 0
26 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # Use this file to define individuals or teams that are responsible for code in a repository.
2 | # Read more:
3 | #
4 | # Order is important: the last matching pattern has the highest precedence
5 |
6 | # These owners will be the default owners for everything
7 | * @cloudposse/engineering @cloudposse/contributors
8 |
9 | # Cloud Posse must review any changes to Makefiles
10 | **/Makefile @cloudposse/engineering
11 | **/Makefile.* @cloudposse/engineering
12 |
13 | # Cloud Posse must review any changes to GitHub actions
14 | .github/* @cloudposse/engineering
15 |
16 | # Cloud Posse must review any changes to standard context definition,
17 | # but some changes can be rubber-stamped.
18 | **/*.tf @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
19 | README.yaml @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
20 | README.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
21 | docs/*.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
22 |
23 | # Cloud Posse Admins must review all changes to CODEOWNERS or the mergify configuration
24 | .github/mergify.yml @cloudposse/admins
25 | .github/CODEOWNERS @cloudposse/admins
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: 'bug'
6 | assignees: ''
7 |
8 | ---
9 |
10 | Found a bug? Maybe our [Slack Community](https://slack.cloudposse.com) can help.
11 |
12 | [](https://slack.cloudposse.com)
13 |
14 | ## Describe the Bug
15 | A clear and concise description of what the bug is.
16 |
17 | ## Expected Behavior
18 | A clear and concise description of what you expected to happen.
19 |
20 | ## Steps to Reproduce
21 | Steps to reproduce the behavior:
22 | 1. Go to '...'
23 | 2. Run '....'
24 | 3. Enter '....'
25 | 4. See error
26 |
27 | ## Screenshots
28 | If applicable, add screenshots or logs to help explain your problem.
29 |
30 | ## Environment (please complete the following information):
31 |
32 | Anything that will help us triage the bug will help. Here are some ideas:
33 | - OS: [e.g. Linux, OSX, WSL, etc]
34 | - Version [e.g. 10.15]
35 |
36 | ## Additional Context
37 | Add any other context about the problem here.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | description: Create a report to help us improve
4 | labels: ["bug"]
5 | assignees: [""]
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Found a bug?
11 |
12 | Please checkout our [Slack Community](https://slack.cloudposse.com)
13 | or visit our [Slack Archive](https://archive.sweetops.com/).
14 |
15 | [](https://slack.cloudposse.com)
16 |
17 | - type: textarea
18 | id: concise-description
19 | attributes:
20 | label: Describe the Bug
21 | description: A clear and concise description of what the bug is.
22 | placeholder: What is the bug about?
23 | validations:
24 | required: true
25 |
26 | - type: textarea
27 | id: expected
28 | attributes:
29 | label: Expected Behavior
30 | description: A clear and concise description of what you expected.
31 | placeholder: What happened?
32 | validations:
33 | required: true
34 |
35 | - type: textarea
36 | id: reproduction-steps
37 | attributes:
38 | label: Steps to Reproduce
39 | description: Steps to reproduce the behavior.
40 | placeholder: How do we reproduce it?
41 | validations:
42 | required: true
43 |
44 | - type: textarea
45 | id: screenshots
46 | attributes:
47 | label: Screenshots
48 | description: If applicable, add screenshots or logs to help explain.
49 | validations:
50 | required: false
51 |
52 | - type: textarea
53 | id: environment
54 | attributes:
55 | label: Environment
56 | description: Anything that will help us triage the bug.
57 | placeholder: |
58 | - OS: [e.g. Linux, OSX, WSL, etc]
59 | - Version [e.g. 10.15]
60 | - Module version
61 | - Terraform version
62 | validations:
63 | required: false
64 |
65 | - type: textarea
66 | id: additional
67 | attributes:
68 | label: Additional Context
69 | description: |
70 | Add any other context about the problem here.
71 | validations:
72 | required: false
73 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
3 | contact_links:
4 |
5 | - name: Community Slack Team
6 | url: https://cloudposse.com/slack/
7 | about: |-
8 | Please ask and answer questions here.
9 |
10 | - name: Office Hours
11 | url: https://cloudposse.com/office-hours/
12 | about: |-
13 | Join us every Wednesday for FREE Office Hours (lunch & learn).
14 |
15 | - name: DevOps Accelerator Program
16 | url: https://cloudposse.com/accelerate/
17 | about: |-
18 | Own your infrastructure in record time. We build it. You drive it.
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: 'feature request'
6 | assignees: ''
7 |
8 | ---
9 |
10 | Have a question? Please checkout our [Slack Community](https://slack.cloudposse.com) or visit our [Slack Archive](https://archive.sweetops.com/).
11 |
12 | [](https://slack.cloudposse.com)
13 |
14 | ## Describe the Feature
15 |
16 | A clear and concise description of what the bug is.
17 |
18 | ## Expected Behavior
19 |
20 | A clear and concise description of what you expected to happen.
21 |
22 | ## Use Case
23 |
24 | Is your feature request related to a problem/challenge you are trying to solve? Please provide some additional context of why this feature or capability will be valuable.
25 |
26 | ## Describe Ideal Solution
27 |
28 | A clear and concise description of what you want to happen. If you don't know, that's okay.
29 |
30 | ## Alternatives Considered
31 |
32 | Explain what alternative solutions or features you've considered.
33 |
34 | ## Additional Context
35 |
36 | Add any other context or screenshots about the feature request here.
37 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | description: Suggest an idea for this project
4 | labels: ["feature request"]
5 | assignees: [""]
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Have a question?
11 |
12 | Please checkout our [Slack Community](https://slack.cloudposse.com)
13 | or visit our [Slack Archive](https://archive.sweetops.com/).
14 |
15 | [](https://slack.cloudposse.com)
16 |
17 | - type: textarea
18 | id: concise-description
19 | attributes:
20 | label: Describe the Feature
21 | description: A clear and concise description of what the feature is.
22 | placeholder: What is the feature about?
23 | validations:
24 | required: true
25 |
26 | - type: textarea
27 | id: expected
28 | attributes:
29 | label: Expected Behavior
30 | description: A clear and concise description of what you expected.
31 | placeholder: What happened?
32 | validations:
33 | required: true
34 |
35 | - type: textarea
36 | id: use-case
37 | attributes:
38 | label: Use Case
39 | description: |
40 | Is your feature request related to a problem/challenge you are trying
41 | to solve?
42 |
43 | Please provide some additional context of why this feature or
44 | capability will be valuable.
45 | validations:
46 | required: true
47 |
48 | - type: textarea
49 | id: ideal-solution
50 | attributes:
51 | label: Describe Ideal Solution
52 | description: A clear and concise description of what you want to happen.
53 | validations:
54 | required: true
55 |
56 | - type: textarea
57 | id: alternatives-considered
58 | attributes:
59 | label: Alternatives Considered
60 | description: Explain alternative solutions or features considered.
61 | validations:
62 | required: false
63 |
64 | - type: textarea
65 | id: additional
66 | attributes:
67 | label: Additional Context
68 | description: |
69 | Add any other context about the problem here.
70 | validations:
71 | required: false
72 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/question.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudposse/terraform-yaml-stack-config/d5c8b4ab026c86825c07a115fbb537092443ace1/.github/ISSUE_TEMPLATE/question.md
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## what
2 |
3 |
7 |
8 | ## why
9 |
10 |
15 |
16 | ## references
17 |
18 |
22 |
--------------------------------------------------------------------------------
/.github/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cloudposse/terraform-yaml-stack-config/d5c8b4ab026c86825c07a115fbb537092443ace1/.github/banner.png
--------------------------------------------------------------------------------
/.github/mergify.yml:
--------------------------------------------------------------------------------
1 | extends: .github
2 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base",
4 | ":preserveSemverRanges"
5 | ],
6 | "baseBranches": ["main", "master", "/^release\\/v\\d{1,2}$/"],
7 | "labels": ["auto-update"],
8 | "dependencyDashboardAutoclose": true,
9 | "enabledManagers": ["terraform"],
10 | "terraform": {
11 | "ignorePaths": ["**/context.tf", "examples/**"]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.github/settings.yml:
--------------------------------------------------------------------------------
1 | # Upstream changes from _extends are only recognized when modifications are made to this file in the default branch.
2 | _extends: .github
3 | repository:
4 | name: terraform-yaml-stack-config
5 | description: Terraform module that loads an opinionated 'stack' configuration from local or remote YAML sources. It supports deep-merged variables, settings, ENV variables, backend config, and remote state outputs for Terraform and helmfile components.
6 | homepage: https://cloudposse.com/accelerate
7 | topics: yaml, configuration, config, configuration-management, terraform, terraform-module, helm, helmfile, configuration-files, configs, yaml-configuration, stack, stacks
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.github/workflows/branch.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Branch
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | - release/**
8 | types: [opened, synchronize, reopened, labeled, unlabeled]
9 | push:
10 | branches:
11 | - main
12 | - release/v*
13 | paths-ignore:
14 | - '.github/**'
15 | - 'docs/**'
16 | - 'examples/**'
17 | - 'test/**'
18 | - 'README.md'
19 |
20 | permissions: {}
21 |
22 | jobs:
23 | terraform-module:
24 | uses: cloudposse/.github/.github/workflows/shared-terraform-module.yml@main
25 | secrets: inherit
26 |
--------------------------------------------------------------------------------
/.github/workflows/chatops.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: chatops
3 | on:
4 | issue_comment:
5 | types: [created]
6 |
7 | permissions:
8 | pull-requests: write
9 | id-token: write
10 | contents: write
11 | statuses: write
12 |
13 | jobs:
14 | test:
15 | uses: cloudposse/.github/.github/workflows/shared-terraform-chatops.yml@main
16 | if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/terratest') }}
17 | secrets: inherit
18 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: release
3 | on:
4 | release:
5 | types:
6 | - published
7 |
8 | permissions:
9 | id-token: write
10 | contents: write
11 | pull-requests: write
12 |
13 | jobs:
14 | terraform-module:
15 | uses: cloudposse/.github/.github/workflows/shared-release-branches.yml@main
16 | secrets: inherit
17 |
--------------------------------------------------------------------------------
/.github/workflows/scheduled.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: scheduled
3 | on:
4 | workflow_dispatch: { } # Allows manually trigger this workflow
5 | schedule:
6 | - cron: "0 3 * * *"
7 |
8 | permissions:
9 | pull-requests: write
10 | id-token: write
11 | contents: write
12 |
13 | jobs:
14 | scheduled:
15 | uses: cloudposse/.github/.github/workflows/shared-terraform-scheduled.yml@main
16 | secrets: inherit
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 |
4 | # .tfstate files
5 | *.tfstate
6 | *.tfstate.*
7 | .terraform
8 | .terraform.tfstate.lock.info
9 | **/.terraform.lock.hcl
10 |
11 | **/.idea
12 | **/*.iml
13 |
14 | # Cloud Posse Build Harness https://github.com/cloudposse/build-harness
15 | **/.build-harness
16 | **/build-harness
17 |
18 | # Crash log files
19 | crash.log
20 | test.log
21 |
--------------------------------------------------------------------------------
/atmos.yaml:
--------------------------------------------------------------------------------
1 | # Atmos Configuration — powered by https://atmos.tools
2 | #
3 | # This configuration enables centralized, DRY, and consistent project scaffolding using Atmos.
4 | #
5 | # Included features:
6 | # - Organizational custom commands: https://atmos.tools/core-concepts/custom-commands
7 | # - Automated README generation: https://atmos.tools/cli/commands/docs/generate
8 | #
9 |
10 | # Import shared configuration used by all modules
11 | import:
12 | - https://raw.githubusercontent.com/cloudposse/.github/refs/heads/main/.github/atmos/terraform-module.yaml
13 |
--------------------------------------------------------------------------------
/context.tf:
--------------------------------------------------------------------------------
1 | #
2 | # ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label
3 | # All other instances of this file should be a copy of that one
4 | #
5 | #
6 | # Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf
7 | # and then place it in your Terraform module to automatically get
8 | # Cloud Posse's standard configuration inputs suitable for passing
9 | # to Cloud Posse modules.
10 | #
11 | # curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf
12 | #
13 | # Modules should access the whole context as `module.this.context`
14 | # to get the input variables with nulls for defaults,
15 | # for example `context = module.this.context`,
16 | # and access individual variables as `module.this.`,
17 | # with final values filled in.
18 | #
19 | # For example, when using defaults, `module.this.context.delimiter`
20 | # will be null, and `module.this.delimiter` will be `-` (hyphen).
21 | #
22 |
23 | module "this" {
24 | source = "cloudposse/label/null"
25 | version = "0.25.0" # requires Terraform >= 0.13.0
26 |
27 | enabled = var.enabled
28 | namespace = var.namespace
29 | tenant = var.tenant
30 | environment = var.environment
31 | stage = var.stage
32 | name = var.name
33 | delimiter = var.delimiter
34 | attributes = var.attributes
35 | tags = var.tags
36 | additional_tag_map = var.additional_tag_map
37 | label_order = var.label_order
38 | regex_replace_chars = var.regex_replace_chars
39 | id_length_limit = var.id_length_limit
40 | label_key_case = var.label_key_case
41 | label_value_case = var.label_value_case
42 | descriptor_formats = var.descriptor_formats
43 | labels_as_tags = var.labels_as_tags
44 |
45 | context = var.context
46 | }
47 |
48 | # Copy contents of cloudposse/terraform-null-label/variables.tf here
49 |
50 | variable "context" {
51 | type = any
52 | default = {
53 | enabled = true
54 | namespace = null
55 | tenant = null
56 | environment = null
57 | stage = null
58 | name = null
59 | delimiter = null
60 | attributes = []
61 | tags = {}
62 | additional_tag_map = {}
63 | regex_replace_chars = null
64 | label_order = []
65 | id_length_limit = null
66 | label_key_case = null
67 | label_value_case = null
68 | descriptor_formats = {}
69 | # Note: we have to use [] instead of null for unset lists due to
70 | # https://github.com/hashicorp/terraform/issues/28137
71 | # which was not fixed until Terraform 1.0.0,
72 | # but we want the default to be all the labels in `label_order`
73 | # and we want users to be able to prevent all tag generation
74 | # by setting `labels_as_tags` to `[]`, so we need
75 | # a different sentinel to indicate "default"
76 | labels_as_tags = ["unset"]
77 | }
78 | description = <<-EOT
79 | Single object for setting entire context at once.
80 | See description of individual variables for details.
81 | Leave string and numeric variables as `null` to use default value.
82 | Individual variable settings (non-null) override settings in context object,
83 | except for attributes, tags, and additional_tag_map, which are merged.
84 | EOT
85 |
86 | validation {
87 | condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"])
88 | error_message = "Allowed values: `lower`, `title`, `upper`."
89 | }
90 |
91 | validation {
92 | condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"])
93 | error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
94 | }
95 | }
96 |
97 | variable "enabled" {
98 | type = bool
99 | default = null
100 | description = "Set to false to prevent the module from creating any resources"
101 | }
102 |
103 | variable "namespace" {
104 | type = string
105 | default = null
106 | description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique"
107 | }
108 |
109 | variable "tenant" {
110 | type = string
111 | default = null
112 | description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for"
113 | }
114 |
115 | variable "environment" {
116 | type = string
117 | default = null
118 | description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'"
119 | }
120 |
121 | variable "stage" {
122 | type = string
123 | default = null
124 | description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'"
125 | }
126 |
127 | variable "name" {
128 | type = string
129 | default = null
130 | description = <<-EOT
131 | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
132 | This is the only ID element not also included as a `tag`.
133 | The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input.
134 | EOT
135 | }
136 |
137 | variable "delimiter" {
138 | type = string
139 | default = null
140 | description = <<-EOT
141 | Delimiter to be used between ID elements.
142 | Defaults to `-` (hyphen). Set to `""` to use no delimiter at all.
143 | EOT
144 | }
145 |
146 | variable "attributes" {
147 | type = list(string)
148 | default = []
149 | description = <<-EOT
150 | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
151 | in the order they appear in the list. New attributes are appended to the
152 | end of the list. The elements of the list are joined by the `delimiter`
153 | and treated as a single ID element.
154 | EOT
155 | }
156 |
157 | variable "labels_as_tags" {
158 | type = set(string)
159 | default = ["default"]
160 | description = <<-EOT
161 | Set of labels (ID elements) to include as tags in the `tags` output.
162 | Default is to include all labels.
163 | Tags with empty values will not be included in the `tags` output.
164 | Set to `[]` to suppress all generated tags.
165 | **Notes:**
166 | The value of the `name` tag, if included, will be the `id`, not the `name`.
167 | Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
168 | changed in later chained modules. Attempts to change it will be silently ignored.
169 | EOT
170 | }
171 |
172 | variable "tags" {
173 | type = map(string)
174 | default = {}
175 | description = <<-EOT
176 | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
177 | Neither the tag keys nor the tag values will be modified by this module.
178 | EOT
179 | }
180 |
181 | variable "additional_tag_map" {
182 | type = map(string)
183 | default = {}
184 | description = <<-EOT
185 | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
186 | This is for some rare cases where resources want additional configuration of tags
187 | and therefore take a list of maps with tag key, value, and additional configuration.
188 | EOT
189 | }
190 |
191 | variable "label_order" {
192 | type = list(string)
193 | default = null
194 | description = <<-EOT
195 | The order in which the labels (ID elements) appear in the `id`.
196 | Defaults to ["namespace", "environment", "stage", "name", "attributes"].
197 | You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present.
198 | EOT
199 | }
200 |
201 | variable "regex_replace_chars" {
202 | type = string
203 | default = null
204 | description = <<-EOT
205 | Terraform regular expression (regex) string.
206 | Characters matching the regex will be removed from the ID elements.
207 | If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits.
208 | EOT
209 | }
210 |
211 | variable "id_length_limit" {
212 | type = number
213 | default = null
214 | description = <<-EOT
215 | Limit `id` to this many characters (minimum 6).
216 | Set to `0` for unlimited length.
217 | Set to `null` for keep the existing setting, which defaults to `0`.
218 | Does not affect `id_full`.
219 | EOT
220 | validation {
221 | condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0
222 | error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length."
223 | }
224 | }
225 |
226 | variable "label_key_case" {
227 | type = string
228 | default = null
229 | description = <<-EOT
230 | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
231 | Does not affect keys of tags passed in via the `tags` input.
232 | Possible values: `lower`, `title`, `upper`.
233 | Default value: `title`.
234 | EOT
235 |
236 | validation {
237 | condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case)
238 | error_message = "Allowed values: `lower`, `title`, `upper`."
239 | }
240 | }
241 |
242 | variable "label_value_case" {
243 | type = string
244 | default = null
245 | description = <<-EOT
246 | Controls the letter case of ID elements (labels) as included in `id`,
247 | set as tag values, and output by this module individually.
248 | Does not affect values of tags passed in via the `tags` input.
249 | Possible values: `lower`, `title`, `upper` and `none` (no transformation).
250 | Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
251 | Default value: `lower`.
252 | EOT
253 |
254 | validation {
255 | condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case)
256 | error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
257 | }
258 | }
259 |
260 | variable "descriptor_formats" {
261 | type = any
262 | default = {}
263 | description = <<-EOT
264 | Describe additional descriptors to be output in the `descriptors` output map.
265 | Map of maps. Keys are names of descriptors. Values are maps of the form
266 | `{
267 | format = string
268 | labels = list(string)
269 | }`
270 | (Type is `any` so the map values can later be enhanced to provide additional options.)
271 | `format` is a Terraform format string to be passed to the `format()` function.
272 | `labels` is a list of labels, in order, to pass to `format()` function.
273 | Label values will be normalized before being passed to `format()` so they will be
274 | identical to how they appear in `id`.
275 | Default is `{}` (`descriptors` output will be empty).
276 | EOT
277 | }
278 |
279 | #### End of copy of cloudposse/terraform-null-label/variables.tf
280 |
--------------------------------------------------------------------------------
/examples/backend/atmos.yaml:
--------------------------------------------------------------------------------
1 | # CLI config is loaded from the following locations (from lowest to highest priority):
2 | # system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
3 | # home dir (~/.atmos)
4 | # current directory
5 | # ENV vars
6 | # Command-line arguments
7 | #
8 | # It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
9 | # https://en.wikipedia.org/wiki/Glob_(programming)
10 |
11 | # Base path for components, stacks and workflows configurations.
12 | # Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
13 | # Supports both absolute and relative paths.
14 | # If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
15 | # are independent settings (supporting both absolute and relative paths).
16 | # If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
17 | # are considered paths relative to `base_path`.
18 | base_path: "."
19 |
20 | components:
21 | terraform:
22 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
23 | # Supports both absolute and relative paths
24 | base_path: "components/terraform"
25 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
26 | apply_auto_approve: false
27 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
28 | deploy_run_init: true
29 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
30 | init_run_reconfigure: true
31 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
32 | auto_generate_backend_file: false
33 | helmfile:
34 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_BASE_PATH` ENV var, or `--helmfile-dir` command-line argument
35 | # Supports both absolute and relative paths
36 | base_path: "components/helmfile"
37 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH` ENV var
38 | kubeconfig_path: "/dev/shm"
39 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN` ENV var
40 | helm_aws_profile_pattern: "{namespace}-{tenant}-gbl-{stage}-helm"
41 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN` ENV var
42 | cluster_name_pattern: "{namespace}-{tenant}-{environment}-{stage}-eks-cluster"
43 |
44 | stacks:
45 | # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
46 | # Supports both absolute and relative paths
47 | base_path: "stacks"
48 | # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
49 | included_paths:
50 | - "**/*"
51 | # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
52 | excluded_paths:
53 | - "globals/**/*"
54 | - "catalog/**/*"
55 | - "**/*globals*"
56 | # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
57 | name_pattern: "{tenant}-{environment}-{stage}"
58 |
59 | workflows:
60 | # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
61 | # Supports both absolute and relative paths
62 | base_path: "workflows"
63 |
64 | logs:
65 | file: "/dev/stdout"
66 | # Supported log levels: Trace, Debug, Info, Warning, Off
67 | level: Info
68 |
--------------------------------------------------------------------------------
/examples/backend/fixtures.tfvars:
--------------------------------------------------------------------------------
1 | enabled = true
2 |
3 | component = "test/test-component-override"
4 |
5 | tenant = "tenant1"
6 |
7 | environment = "ue2"
8 |
9 | stage = "dev"
10 |
--------------------------------------------------------------------------------
/examples/backend/main.tf:
--------------------------------------------------------------------------------
1 | module "backend" {
2 | source = "../../modules/backend"
3 |
4 | stack = var.stack
5 | component = var.component
6 | ignore_errors = var.ignore_errors
7 | env = var.env
8 | atmos_cli_config_path = var.atmos_cli_config_path
9 | atmos_base_path = var.atmos_base_path
10 |
11 | context = module.this.context
12 | }
13 |
--------------------------------------------------------------------------------
/examples/backend/outputs.tf:
--------------------------------------------------------------------------------
1 | output "backend_type" {
2 | value = module.backend.backend_type
3 | description = "Backend type"
4 | }
5 |
6 | output "backend" {
7 | value = module.backend.backend
8 | description = "Backend configuration for the component"
9 | }
10 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/helmfile/echo-server.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | echo-server:
4 | vars:
5 | installed: true
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/helmfile/infra-server.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | "infra/infra-server":
4 | vars:
5 | installed: true
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/services/service-1-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_1_name: "service-1-override"
6 | service_1_map:
7 | a: 1
8 | b: 2
9 | c: 3
10 | service_1_list:
11 | - 1
12 | - 2
13 | - 3
14 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/services/service-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component":
4 | vars:
5 | service_1_name: "service-1"
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/services/service-2-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_2_name: "service-2-override"
6 | service_2_map:
7 | a: 1
8 | b: 2
9 | c: 3
10 | service_2_list:
11 | - 1
12 | - 2
13 | - 3
14 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/services/service-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component":
4 | vars:
5 | service_2_name: "service-2"
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/services/top-level-service-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | top-level-component1:
4 | vars:
5 | service_1_name: "top-level-service-1"
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/services/top-level-service-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | top-level-component1:
4 | vars:
5 | service_2_name: "top-level-service-2"
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/tenant1-ue2-dev.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_1_name: "service-1-override-2"
6 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/test-component-override.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?-override.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component-override":
12 | # Specify terraform binary to run
13 | command: "/usr/local/bin/terraform"
14 | # By using `component` attribute, `test-component-override` inherits from `test-component` and can override its variables
15 | # In this example, variables for each service are overridden in `catalog/services/service-?-override.*`
16 | component: "test/test-component"
17 | # Other variables can be overridden here
18 | vars: {}
19 | env:
20 | TEST_ENV_VAR1: "val1-override"
21 | TEST_ENV_VAR3: "val3-override"
22 | TEST_ENV_VAR4: "val4"
23 | # Override remote state backend for this component
24 | remote_state_backend_type: static # s3, remote, vault, static, etc.
25 | remote_state_backend:
26 | static:
27 | val1: true
28 | val2: "2"
29 | val3: 3
30 | val4: null
31 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/test-component.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component":
12 | settings:
13 | spacelift:
14 | workspace_enabled: true
15 | vars:
16 | enabled: true
17 | env:
18 | TEST_ENV_VAR1: "val1"
19 | TEST_ENV_VAR2: "val2"
20 | TEST_ENV_VAR3: "val3"
21 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/top-level-component1.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/top-level-service-?.*
8 |
9 | components:
10 | terraform:
11 | top-level-component1:
12 | settings:
13 | spacelift:
14 | workspace_enabled: true
15 | vars:
16 | enabled: true
17 |
--------------------------------------------------------------------------------
/examples/backend/stacks/catalog/terraform/vpc.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "infra/vpc":
4 | backend:
5 | s3:
6 | workspace_key_prefix: infra-vpc
7 | settings:
8 | spacelift:
9 | workspace_enabled: true
10 | vars:
11 | enabled: true
12 | name: "common"
13 | subnet_type_tag_key: eg.io/subnet/type
14 | nat_gateway_enabled: true
15 | nat_instance_enabled: false
16 | max_subnet_count: 3
17 |
--------------------------------------------------------------------------------
/examples/backend/stacks/globals/globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | namespace: eg
3 |
4 | terraform:
5 | vars: {}
6 |
7 | backend_type: s3 # s3, remote, vault, static, etc.
8 | backend:
9 | s3:
10 | encrypt: true
11 | bucket: "eg-ue2-root-tfstate"
12 | key: "terraform.tfstate"
13 | dynamodb_table: "eg-ue2-root-tfstate-lock"
14 | acl: "bucket-owner-full-control"
15 | region: "us-east-2"
16 | role_arn: null
17 | remote:
18 | vault:
19 |
20 | remote_state_backend:
21 | s3:
22 | role_arn: "arn:aws:iam::123456789012:role/eg-gbl-root-terraform"
23 |
24 | helmfile:
25 | vars: {}
26 |
27 | components:
28 | terraform: {}
29 | helmfile: {}
30 |
--------------------------------------------------------------------------------
/examples/backend/stacks/globals/tenant1-globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | tenant: tenant1
3 |
--------------------------------------------------------------------------------
/examples/backend/stacks/globals/tenant2-globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | tenant: tenant2
3 |
--------------------------------------------------------------------------------
/examples/backend/stacks/globals/ue2-globals.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/globals
3 |
4 | vars:
5 | region: us-east-2
6 | environment: ue2
7 |
8 | helmfile:
9 | vars: {}
10 |
11 | components:
12 | terraform:
13 | "infra/vpc":
14 | vars:
15 | availability_zones: ["us-east-2a", "us-east-2b", "us-east-2c"]
16 |
--------------------------------------------------------------------------------
/examples/backend/stacks/tenant1/ue2/dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/terraform/tenant1-ue2-dev
9 | - catalog/helmfile/echo-server
10 | - catalog/helmfile/infra-server
11 |
12 | vars:
13 | stage: dev
14 |
15 | terraform:
16 | vars: {}
17 |
18 | helmfile:
19 | vars: {}
20 |
21 | components:
22 | terraform:
23 | "infra/vpc":
24 | vars:
25 | cidr_block: 10.10.0.0/18
26 |
--------------------------------------------------------------------------------
/examples/backend/stacks/tenant1/ue2/prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: prod
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.8.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/backend/stacks/tenant1/ue2/staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: staging
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.9.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/backend/stacks/tenant2/ue2/dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: dev
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.10.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/backend/stacks/tenant2/ue2/prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: prod
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.8.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/backend/stacks/tenant2/ue2/staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: staging
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.9.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/backend/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack" {
2 | type = string
3 | description = "Stack name"
4 | default = null
5 | }
6 |
7 | variable "component" {
8 | type = string
9 | description = "Component"
10 | }
11 |
12 | variable "ignore_errors" {
13 | type = bool
14 | description = "Set to true to ignore errors from the 'utils' provider (if the component is not found in the stack)"
15 | default = false
16 | }
17 |
18 | variable "env" {
19 | type = map(string)
20 | description = "Map of ENV vars in the format `key=value`. These ENV vars will be set in the `utils` provider before executing the data source"
21 | default = null
22 | }
23 |
24 | variable "atmos_cli_config_path" {
25 | type = string
26 | description = "atmos CLI config path"
27 | default = null
28 | }
29 |
30 | variable "atmos_base_path" {
31 | type = string
32 | description = "atmos base path to components and stacks"
33 | default = null
34 | }
35 |
--------------------------------------------------------------------------------
/examples/backend/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.8.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/complete/atmos.yaml:
--------------------------------------------------------------------------------
1 | # CLI config is loaded from the following locations (from lowest to highest priority):
2 | # system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
3 | # home dir (~/.atmos)
4 | # current directory
5 | # ENV vars
6 | # Command-line arguments
7 | #
8 | # It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
9 | # https://en.wikipedia.org/wiki/Glob_(programming)
10 |
11 | # Base path for components, stacks and workflows configurations.
12 | # Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
13 | # Supports both absolute and relative paths.
14 | # If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
15 | # are independent settings (supporting both absolute and relative paths).
16 | # If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
17 | # are considered paths relative to `base_path`.
18 | base_path: "."
19 |
20 | components:
21 | terraform:
22 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
23 | # Supports both absolute and relative paths
24 | base_path: "components/terraform"
25 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
26 | apply_auto_approve: false
27 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
28 | deploy_run_init: true
29 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
30 | init_run_reconfigure: true
31 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
32 | auto_generate_backend_file: false
33 | helmfile:
34 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_BASE_PATH` ENV var, or `--helmfile-dir` command-line argument
35 | # Supports both absolute and relative paths
36 | base_path: "components/helmfile"
37 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH` ENV var
38 | kubeconfig_path: "/dev/shm"
39 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN` ENV var
40 | helm_aws_profile_pattern: "{namespace}-{tenant}-gbl-{stage}-helm"
41 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN` ENV var
42 | cluster_name_pattern: "{namespace}-{tenant}-{environment}-{stage}-eks-cluster"
43 |
44 | stacks:
45 | # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
46 | # Supports both absolute and relative paths
47 | base_path: "stacks"
48 | # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
49 | included_paths:
50 | - "**/*"
51 | # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
52 | excluded_paths:
53 | - "globals/**/*"
54 | - "catalog/**/*"
55 | - "**/*globals*"
56 | # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
57 | name_pattern: "{tenant}-{environment}-{stage}"
58 |
59 | workflows:
60 | # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
61 | # Supports both absolute and relative paths
62 | base_path: "workflows"
63 |
64 | logs:
65 | file: "/dev/stdout"
66 | # Supported log levels: Trace, Debug, Info, Warning, Off
67 | level: Info
68 |
--------------------------------------------------------------------------------
/examples/complete/fixtures.tfvars:
--------------------------------------------------------------------------------
1 | enabled = true
2 |
3 | stack_config_local_path = "./stacks"
4 |
5 | stack = "my-stack"
6 |
7 | component_type = "terraform"
8 |
9 | component = "my-vpc"
10 |
--------------------------------------------------------------------------------
/examples/complete/main.tf:
--------------------------------------------------------------------------------
1 | module "vars" {
2 | source = "../../modules/vars"
3 |
4 | stack_config_local_path = var.stack_config_local_path
5 | stack = var.stack
6 | component_type = var.component_type
7 | component = var.component
8 |
9 | context = module.this.context
10 | }
11 |
12 | module "settings" {
13 | source = "../../modules/settings"
14 |
15 | stack_config_local_path = var.stack_config_local_path
16 | stack = var.stack
17 | component_type = var.component_type
18 | component = var.component
19 |
20 | context = module.this.context
21 | }
22 |
23 | module "env" {
24 | source = "../../modules/env"
25 |
26 | stack_config_local_path = var.stack_config_local_path
27 | stack = var.stack
28 | component_type = var.component_type
29 | component = var.component
30 |
31 | context = module.this.context
32 | }
33 |
34 | module "stack" {
35 | source = "../../modules/stack"
36 |
37 | stack = var.stack
38 | context = module.this.context
39 | }
40 |
--------------------------------------------------------------------------------
/examples/complete/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vars" {
2 | value = module.vars.vars
3 | description = "vars for the component"
4 | }
5 |
6 | output "settings" {
7 | value = module.settings.settings
8 | description = "Settings for the component"
9 | }
10 |
11 | output "env" {
12 | value = module.env.env
13 | description = "ENV variables for the component"
14 | }
15 |
16 | output "stack_name" {
17 | value = module.stack.stack_name
18 | description = "Stack name"
19 | }
20 |
--------------------------------------------------------------------------------
/examples/complete/stacks/imports-level-2.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - imports-level-3
3 | - imports-level-3a
4 |
5 | vars:
6 | region: us-east-2
7 | environment: ue2
8 |
9 | terraform:
10 | vars:
11 | var_1: 1_override
12 | var_2: 2_override
13 |
14 | helmfile:
15 | vars:
16 | var_1: 1
17 | var_2: 2
18 |
--------------------------------------------------------------------------------
/examples/complete/stacks/imports-level-3.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - imports-level-4
3 |
4 | vars:
5 | namespace: eg
6 |
7 | terraform:
8 | vars:
9 | var_1: 1
10 | var_3: 3
11 | settings:
12 | version: 1
13 | spacelift:
14 | workspace_enabled: false
15 | autodeploy: false
16 | env:
17 | ENV_TEST_1: test1
18 | ENV_TEST_2: test2
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | vpc:
26 | vars:
27 | test_map:
28 | a: a
29 | b: b
30 | c:
31 | - 5
32 | - 6
33 | - 7
34 | backend:
35 | s3:
36 | workspace_key_prefix: "vpc"
37 | eks:
38 | backend:
39 | s3:
40 | workspace_key_prefix: "eks"
41 | vars:
42 | cluster_kubernetes_version: "1.18"
43 |
--------------------------------------------------------------------------------
/examples/complete/stacks/imports-level-3a.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | level: 3
3 |
4 | terraform:
5 | vars:
6 | var_1: 1a
7 | var_2: 2a
8 | var_3: 3a
9 |
10 | backend_type: s3 # s3, remote, vault, etc.
11 |
12 | backend:
13 | s3:
14 | encrypt: true
15 | dynamodb_table: "eg-ue2-root-tfstate-lock"
16 | role_arn: "arn:aws:iam::xxxxxxxxxxxx:role/eg-gbl-root-terraform"
17 | acl: "bucket-owner-full-control"
18 | bucket: "eg-ue2-root-tfstate"
19 | key: "terraform.tfstate"
20 | region: "us-east-2"
21 | remote:
22 | organization: company
23 | workspace: ws1
24 | vault: {}
25 |
26 | components:
27 | terraform:
28 | vpc:
29 | vars:
30 | availability_zones: ["us-east-2a", "us-east-2b", "us-east-2c"]
31 |
32 | helmfile:
33 | vars: {}
34 |
--------------------------------------------------------------------------------
/examples/complete/stacks/imports-level-4.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | level: 4
3 | param: param4
4 |
5 | terraform:
6 | vars: {}
7 |
8 | helmfile:
9 | vars: {}
10 |
11 | components:
12 | terraform:
13 | vpc:
14 | vars:
15 | subnet_type_tag_key: "example/subnet/type"
16 | backend:
17 | s3:
18 | workspace_key_prefix: "vpc"
19 |
--------------------------------------------------------------------------------
/examples/complete/stacks/my-stack.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - imports-level-2
3 |
4 | vars:
5 | stage: prod
6 |
7 | terraform:
8 | vars: {}
9 |
10 | helmfile:
11 | vars: {}
12 |
13 | components:
14 | terraform:
15 | my-vpc:
16 | component: vpc
17 | vars:
18 | cidr_block: "10.132.0.0/18"
19 | test_map:
20 | a: a_override_2
21 | map2:
22 | atr1: 1
23 | atr2: 2
24 | atr3:
25 | - 3a
26 | - 3b
27 | - 3c
28 | settings:
29 | spacelift:
30 | workspace_enabled: true
31 | autodeploy: true
32 | branch: "test"
33 | triggers: ["1", "2"]
34 | env:
35 | ENV_TEST_1: test1_override
36 | ENV_TEST_2: test2_override
37 | ENV_TEST_4: test4
38 |
39 | vpc:
40 | vars:
41 | cidr_block: "10.102.0.0/18"
42 | test_map:
43 | a: a_override
44 | b: b_override
45 | c:
46 | - 1
47 | - 2
48 | - 3
49 | env:
50 | ENV_TEST_3: test3
51 |
52 | eks:
53 | vars: {}
54 |
55 | helmfile:
56 | nginx-ingress:
57 | vars:
58 | installed: true
59 |
--------------------------------------------------------------------------------
/examples/complete/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_config_local_path" {
2 | type = string
3 | description = "Path to local stack configs"
4 | }
5 |
6 | variable "stack" {
7 | type = string
8 | description = "Stack name"
9 | }
10 |
11 | variable "component_type" {
12 | type = string
13 | description = "Component type"
14 | }
15 |
16 | variable "component" {
17 | type = string
18 | description = "Component"
19 | }
20 |
--------------------------------------------------------------------------------
/examples/complete/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.1.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.8.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/remote-state/atmos.yaml:
--------------------------------------------------------------------------------
1 | # CLI config is loaded from the following locations (from lowest to highest priority):
2 | # system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
3 | # home dir (~/.atmos)
4 | # current directory
5 | # ENV vars
6 | # Command-line arguments
7 | #
8 | # It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
9 | # https://en.wikipedia.org/wiki/Glob_(programming)
10 |
11 | # Base path for components, stacks and workflows configurations.
12 | # Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
13 | # Supports both absolute and relative paths.
14 | # If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
15 | # are independent settings (supporting both absolute and relative paths).
16 | # If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
17 | # are considered paths relative to `base_path`.
18 | base_path: "."
19 |
20 | components:
21 | terraform:
22 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
23 | # Supports both absolute and relative paths
24 | base_path: "components/terraform"
25 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
26 | apply_auto_approve: false
27 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
28 | deploy_run_init: true
29 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
30 | init_run_reconfigure: true
31 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
32 | auto_generate_backend_file: false
33 | helmfile:
34 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_BASE_PATH` ENV var, or `--helmfile-dir` command-line argument
35 | # Supports both absolute and relative paths
36 | base_path: "components/helmfile"
37 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH` ENV var
38 | kubeconfig_path: "/dev/shm"
39 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN` ENV var
40 | helm_aws_profile_pattern: "{namespace}-{tenant}-gbl-{stage}-helm"
41 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN` ENV var
42 | cluster_name_pattern: "{namespace}-{tenant}-{environment}-{stage}-eks-cluster"
43 |
44 | stacks:
45 | # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
46 | # Supports both absolute and relative paths
47 | base_path: "stacks"
48 | # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
49 | included_paths:
50 | - "**/*"
51 | # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
52 | excluded_paths:
53 | - "globals/**/*"
54 | - "catalog/**/*"
55 | - "**/*globals*"
56 | # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
57 | name_pattern: "{tenant}-{environment}-{stage}"
58 |
59 | workflows:
60 | # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
61 | # Supports both absolute and relative paths
62 | base_path: "workflows"
63 |
64 | logs:
65 | file: "/dev/stdout"
66 | # Supported log levels: Trace, Debug, Info, Warning, Off
67 | level: Info
68 |
--------------------------------------------------------------------------------
/examples/remote-state/fixtures.tfvars:
--------------------------------------------------------------------------------
1 | enabled = true
2 |
--------------------------------------------------------------------------------
/examples/remote-state/main.tf:
--------------------------------------------------------------------------------
1 | module "remote_state_using_stack" {
2 | source = "../../modules/remote-state"
3 |
4 | component = "test/test-component-override"
5 | stack = "tenant1-ue2-dev"
6 |
7 | # Verify that a default output not matching the real output does not cause a Terraform error
8 | defaults = {
9 | val1 = ["default-list"]
10 | val2 = "default-value"
11 | }
12 |
13 | env = {
14 | ATMOS_CLI_CONFIG_PATH = path.module
15 | }
16 |
17 | atmos_cli_config_path = var.atmos_cli_config_path
18 | atmos_base_path = var.atmos_base_path
19 |
20 | context = module.this.context
21 | }
22 |
23 | module "remote_state_using_context" {
24 | source = "../../modules/remote-state"
25 |
26 | component = "test/test-component-override"
27 | namespace = ""
28 | tenant = "tenant1"
29 | environment = "ue2"
30 | stage = "dev"
31 |
32 | env = {
33 | ATMOS_CLI_CONFIG_PATH = path.module
34 | }
35 |
36 | atmos_cli_config_path = var.atmos_cli_config_path
37 | atmos_base_path = var.atmos_base_path
38 |
39 | context = module.this.context
40 | }
41 |
42 | module "remote_state_using_context_ignore_errors" {
43 | source = "../../modules/remote-state"
44 |
45 | # Use a wrong component for testing
46 | # If `ignore_errors = false`, the `utils` provider will throw the error: Could not find config for the component 'test/test-component-override-wrong' in the stack 'tenant1-ue2-dev'
47 | # Note that terraform `try()` does not catch errors from providers, so `try(module.remote_state_using_context_ignore_errors.outputs, {})` will not work
48 | ignore_errors = true
49 | component = "test/test-component-override-wrong"
50 | namespace = ""
51 | tenant = "tenant1"
52 | environment = "ue2"
53 | stage = "dev"
54 |
55 | defaults = {
56 | default_output = "default-value"
57 | }
58 |
59 | env = {
60 | ATMOS_CLI_CONFIG_PATH = path.module
61 | }
62 |
63 | atmos_cli_config_path = var.atmos_cli_config_path
64 | atmos_base_path = var.atmos_base_path
65 |
66 | context = module.this.context
67 | }
68 |
69 | module "remote_state_with_bypass" {
70 | source = "../../modules/remote-state"
71 |
72 | bypass = true
73 |
74 | defaults = {
75 | default_output = "default-value"
76 | }
77 |
78 | component = "test/test-component-override"
79 | namespace = ""
80 | tenant = "tenant1"
81 | environment = "ue2"
82 | stage = "dev"
83 |
84 | atmos_cli_config_path = var.atmos_cli_config_path
85 | atmos_base_path = var.atmos_base_path
86 |
87 | context = module.this.context
88 | }
89 |
--------------------------------------------------------------------------------
/examples/remote-state/outputs.tf:
--------------------------------------------------------------------------------
1 | output "remote_state_using_stack" {
2 | value = module.remote_state_using_stack.outputs
3 | description = "Component remote state using the provided stack name"
4 | }
5 |
6 | output "remote_state_using_context" {
7 | value = module.remote_state_using_context.outputs
8 | description = "Component remote state using the provided context"
9 | }
10 |
11 | output "remote_state_using_context_ignore_errors" {
12 | value = module.remote_state_using_context_ignore_errors.outputs
13 | description = "Component remote state using wrong component. Errors are ignored in the 'utils' provider"
14 | }
15 |
16 | output "remote_state_with_bypass" {
17 | value = module.remote_state_with_bypass.outputs
18 | description = "Component remote state with 'bypass' set to 'true'"
19 | }
20 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/helmfile/echo-server.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | echo-server:
4 | vars:
5 | installed: true
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/helmfile/infra-server.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | "infra/infra-server":
4 | vars:
5 | installed: true
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/services/service-1-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_1_name: "service-1-override"
6 | service_1_map:
7 | a: 1
8 | b: 2
9 | c: 3
10 | service_1_list:
11 | - 1
12 | - 2
13 | - 3
14 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/services/service-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component":
4 | vars:
5 | service_1_name: "service-1"
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/services/service-2-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_2_name: "service-2-override"
6 | service_2_map:
7 | a: 1
8 | b: 2
9 | c: 3
10 | service_2_list:
11 | - 1
12 | - 2
13 | - 3
14 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/services/service-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component":
4 | vars:
5 | service_2_name: "service-2"
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/services/top-level-service-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | top-level-component1:
4 | vars:
5 | service_1_name: "top-level-service-1"
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/services/top-level-service-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | top-level-component1:
4 | vars:
5 | service_2_name: "top-level-service-2"
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/tenant1-ue2-dev.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_1_name: "service-1-override-2"
6 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/test-component-override.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?-override.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component-override":
12 | # Specify terraform binary to run
13 | command: "/usr/local/bin/terraform"
14 | # By using `component` attribute, `test-component-override` inherits from `test-component` and can override its variables
15 | # In this example, variables for each service are overridden in `catalog/services/service-?-override.*`
16 | component: "test/test-component"
17 | # Other variables can be overridden here
18 | vars: {}
19 | env:
20 | TEST_ENV_VAR1: "val1-override"
21 | TEST_ENV_VAR3: "val3-override"
22 | TEST_ENV_VAR4: "val4"
23 | # Override remote state backend for this component
24 | remote_state_backend_type: static # s3, remote, vault, static, etc.
25 | remote_state_backend:
26 | static:
27 | val1: true
28 | val2: "2"
29 | val3: 3
30 | val4: null
31 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/test-component.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component":
12 | settings:
13 | spacelift:
14 | workspace_enabled: true
15 | vars:
16 | enabled: true
17 | env:
18 | TEST_ENV_VAR1: "val1"
19 | TEST_ENV_VAR2: "val2"
20 | TEST_ENV_VAR3: "val3"
21 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/top-level-component1.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/top-level-service-?.*
8 |
9 | components:
10 | terraform:
11 | top-level-component1:
12 | settings:
13 | spacelift:
14 | workspace_enabled: true
15 | vars:
16 | enabled: true
17 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/catalog/terraform/vpc.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "infra/vpc":
4 | backend:
5 | s3:
6 | workspace_key_prefix: infra-vpc
7 | settings:
8 | spacelift:
9 | workspace_enabled: true
10 | vars:
11 | enabled: true
12 | name: "common"
13 | subnet_type_tag_key: eg.io/subnet/type
14 | nat_gateway_enabled: true
15 | nat_instance_enabled: false
16 | max_subnet_count: 3
17 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/globals/globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | namespace: eg
3 |
4 | terraform:
5 | vars: {}
6 |
7 | backend_type: s3 # s3, remote, vault, static, etc.
8 | backend:
9 | s3:
10 | encrypt: true
11 | bucket: "eg-ue2-root-tfstate"
12 | key: "terraform.tfstate"
13 | dynamodb_table: "eg-ue2-root-tfstate-lock"
14 | acl: "bucket-owner-full-control"
15 | region: "us-east-2"
16 | role_arn: null
17 | remote:
18 | vault:
19 |
20 | remote_state_backend:
21 | s3:
22 | role_arn: "arn:aws:iam::123456789012:role/eg-gbl-root-terraform"
23 |
24 | helmfile:
25 | vars: {}
26 |
27 | components:
28 | terraform: {}
29 | helmfile: {}
30 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/globals/tenant1-globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | tenant: tenant1
3 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/globals/tenant2-globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | tenant: tenant2
3 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/globals/ue2-globals.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/globals
3 |
4 | vars:
5 | region: us-east-2
6 | environment: ue2
7 |
8 | helmfile:
9 | vars: {}
10 |
11 | components:
12 | terraform:
13 | "infra/vpc":
14 | vars:
15 | availability_zones: ["us-east-2a", "us-east-2b", "us-east-2c"]
16 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/tenant1/ue2/dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/terraform/tenant1-ue2-dev
9 | - catalog/helmfile/echo-server
10 | - catalog/helmfile/infra-server
11 |
12 | vars:
13 | stage: dev
14 |
15 | terraform:
16 | vars: {}
17 |
18 | helmfile:
19 | vars: {}
20 |
21 | components:
22 | terraform:
23 | "infra/vpc":
24 | vars:
25 | cidr_block: 10.10.0.0/18
26 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/tenant1/ue2/prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: prod
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.8.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/tenant1/ue2/staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: staging
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.9.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/tenant2/ue2/dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: dev
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.10.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/tenant2/ue2/prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: prod
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.8.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/remote-state/stacks/tenant2/ue2/staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/vpc
8 | - catalog/helmfile/echo-server
9 | - catalog/helmfile/infra-server
10 |
11 | vars:
12 | stage: staging
13 |
14 | terraform:
15 | vars: {}
16 |
17 | helmfile:
18 | vars: {}
19 |
20 | components:
21 | terraform:
22 | "infra/vpc":
23 | vars:
24 | cidr_block: 10.9.0.0/18
25 |
--------------------------------------------------------------------------------
/examples/remote-state/variables.tf:
--------------------------------------------------------------------------------
1 | variable "atmos_cli_config_path" {
2 | type = string
3 | description = "atmos CLI config path"
4 | default = null
5 | }
6 |
7 | variable "atmos_base_path" {
8 | type = string
9 | description = "atmos base path to components and stacks"
10 | default = null
11 | }
12 |
--------------------------------------------------------------------------------
/examples/remote-state/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.1.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.8.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/spacelift/atmos.yaml:
--------------------------------------------------------------------------------
1 | # CLI config is loaded from the following locations (from lowest to highest priority):
2 | # system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
3 | # home dir (~/.atmos)
4 | # current directory
5 | # ENV vars
6 | # Command-line arguments
7 | #
8 | # It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
9 | # https://en.wikipedia.org/wiki/Glob_(programming)
10 |
11 | # Base path for components, stacks and workflows configurations.
12 | # Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
13 | # Supports both absolute and relative paths.
14 | # If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
15 | # are independent settings (supporting both absolute and relative paths).
16 | # If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
17 | # are considered paths relative to `base_path`.
18 | base_path: "."
19 |
20 | components:
21 | terraform:
22 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
23 | # Supports both absolute and relative paths
24 | base_path: "components/terraform"
25 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
26 | apply_auto_approve: false
27 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
28 | deploy_run_init: true
29 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
30 | init_run_reconfigure: true
31 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
32 | auto_generate_backend_file: false
33 | helmfile:
34 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_BASE_PATH` ENV var, or `--helmfile-dir` command-line argument
35 | # Supports both absolute and relative paths
36 | base_path: "components/helmfile"
37 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH` ENV var
38 | kubeconfig_path: "/dev/shm"
39 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN` ENV var
40 | helm_aws_profile_pattern: "{namespace}-{tenant}-gbl-{stage}-helm"
41 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN` ENV var
42 | cluster_name_pattern: "{namespace}-{tenant}-{environment}-{stage}-eks-cluster"
43 |
44 | stacks:
45 | # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
46 | # Supports both absolute and relative paths
47 | base_path: "stacks"
48 | # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
49 | included_paths:
50 | - "**/*"
51 | # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
52 | excluded_paths:
53 | - "globals/**/*"
54 | - "catalog/**/*"
55 | - "**/*globals*"
56 | # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
57 | name_pattern: "{tenant}-{environment}-{stage}"
58 |
59 | workflows:
60 | # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
61 | # Supports both absolute and relative paths
62 | base_path: "workflows"
63 |
64 | logs:
65 | file: "/dev/stdout"
66 | # Supported log levels: Trace, Debug, Info, Warning, Off
67 | level: Info
68 |
--------------------------------------------------------------------------------
/examples/spacelift/fixtures.tfvars:
--------------------------------------------------------------------------------
1 | enabled = true
2 |
3 | stack_config_path_template = "stacks/%s.yaml"
4 |
5 | stack_deps_processing_enabled = true
6 |
7 | component_deps_processing_enabled = true
8 |
9 | imports_processing_enabled = true
10 |
--------------------------------------------------------------------------------
/examples/spacelift/main.tf:
--------------------------------------------------------------------------------
1 | module "spacelift" {
2 | source = "../../modules/spacelift"
3 |
4 | stack_config_path_template = var.stack_config_path_template
5 | stack_deps_processing_enabled = var.stack_deps_processing_enabled
6 | component_deps_processing_enabled = var.component_deps_processing_enabled
7 | imports_processing_enabled = var.imports_processing_enabled
8 |
9 | env = var.env
10 |
11 | context = module.this.context
12 | }
13 |
--------------------------------------------------------------------------------
/examples/spacelift/outputs.tf:
--------------------------------------------------------------------------------
1 | output "spacelift_stacks" {
2 | value = module.spacelift.spacelift_stacks
3 | description = "Spacelift stacks"
4 | }
5 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/helmfile/echo-server.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | echo-server:
4 | vars:
5 | installed: true
6 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/helmfile/infra-server-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | "infra/infra-server-override":
4 | component: "infra/infra-server"
5 | vars:
6 | installed: true
7 | a: "1_override"
8 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/helmfile/infra-server.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | helmfile:
3 | "infra/infra-server":
4 | vars:
5 | installed: true
6 | a: "1"
7 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/mixins/test-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "mixin/test-1":
4 | vars:
5 | service_1_name: "mixin-1"
6 | metadata:
7 | type: abstract
8 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/mixins/test-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "mixin/test-2":
4 | vars:
5 | service_1_name: "mixin-2"
6 | metadata:
7 | type: abstract
8 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/service-1-override-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override-2":
4 | vars:
5 | service_1_name: "service-1-override-2"
6 | service_1_map:
7 | b: 6
8 | c: 7
9 | d: 8
10 | service_1_list:
11 | - 5
12 | - 6
13 | - 7
14 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/service-1-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_1_name: "service-1-override"
6 | service_1_map:
7 | a: 1
8 | b: 2
9 | c: 3
10 | service_1_list:
11 | - 1
12 | - 2
13 | - 3
14 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/service-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component":
4 | vars:
5 | service_1_name: "service-1"
6 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/service-2-override-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override-2":
4 | vars:
5 | service_2_name: "service-2-override-2"
6 | service_2_map:
7 | a: 4
8 | b: 5
9 | c: 6
10 | service_2_list:
11 | - 4
12 | - 5
13 | - 6
14 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/service-2-override.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_2_name: "service-2-override"
6 | service_2_map:
7 | a: 1
8 | b: 2
9 | c: 3
10 | service_2_list:
11 | - 1
12 | - 2
13 | - 3
14 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/service-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component":
4 | vars:
5 | service_2_name: "service-2"
6 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/top-level-service-1.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | top-level-component1:
4 | vars:
5 | service_1_name: "top-level-service-1"
6 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/services/top-level-service-2.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | top-level-component1:
4 | vars:
5 | service_2_name: "top-level-service-2"
6 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/tenant1-ue2-dev.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "test/test-component-override":
4 | vars:
5 | service_1_name: "service-1-override-2"
6 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/test-component-override-2.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?-override-2.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component-override-2":
12 | # Specify terraform binary to run
13 | command: "/usr/local/bin/terraform"
14 | # The `component` attribute specifies that `test-component-override-2` inherits from the `test-component-override` base component,
15 | # which in turn inherits from `test-component` (inheritance chain).
16 | # `test-component-override-2` can override all the variables and other settings of all its base components (except the `metadata` section).
17 | # In this example, variables for each service are overridden in `catalog/services/service-?-override-2.*`
18 | component: "test/test-component-override"
19 | # Other variables can be overridden here
20 | vars: {}
21 | # Other ENV vars can be overridden here
22 | env:
23 | TEST_ENV_VAR1: "val1-override-2"
24 | TEST_ENV_VAR2: "val2-override-2"
25 | TEST_ENV_VAR4: "val4-override-2"
26 | # Override remote state backend for this component
27 | remote_state_backend_type: static # s3, remote, vault, static, etc.
28 | remote_state_backend:
29 | static:
30 | val1: true
31 | val2: "5"
32 | val3: 7
33 | val4: null
34 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/test-component-override-3.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/mixins/test-*.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component-override-3":
12 | settings:
13 | spacelift:
14 | workspace_enabled: false
15 | vars: {}
16 | env:
17 | TEST_ENV_VAR1: "val1-override-3"
18 | TEST_ENV_VAR2: "val2-override-3"
19 | TEST_ENV_VAR3: "val3-override-3"
20 | TEST_ENV_VAR4: "val4-override-3"
21 | metadata:
22 | # `real` is implicit, you don't need to specify it; `abstract` makes the component protected from being deployed
23 | type: real
24 | # Terraform component. Must exist in `components/terraform` folder.
25 | # If not specified, it's assumed that this component `test/test-component-override-3` is also a Terraform component
26 | # in `components/terraform/test/test-component-override-3` folder
27 | component: "test/test-component"
28 | # Multiple inheritance. It's a down-top/left-right matrix (similar to Method Resolution Order (MRO), which is how Python supports multiple inheritance).
29 | # All base components and mixins are processed and deep-merged in the order they are specified in the `inherits` list:
30 | # 1. `test/test-component-override-2` overrides `test/test-component-override` and its base components (all the way up its inheritance chain).
31 | # 2. `mixin/test-1` overrides `test/test-component-override-2` and its base components (all the way up its inheritance chain).
32 | # 3. `mixin/test-2` overrides `mixin/test-1` and its base components (all the way up its inheritance chain).
33 | # 4. This `test/test-component-override-3` component overrides `mixin/test-2` and its base components (all the way up its inheritance chain).
34 | # Inheritance: test/test-component-override-3 -> mixin/test-2 -> mixin/test-1 -> test/test-component-override-2 -> test/test-component-override -> test/test-component
35 | inherits:
36 | - "test/test-component-override"
37 | - "test/test-component-override-2"
38 | - "mixin/test-1"
39 | - "mixin/test-2"
40 | # Override Terraform workspace
41 | # Note that by default, Terraform workspace is generated from the context, e.g. `-`
42 | terraform_workspace: test-component-override-3-workspace
43 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/test-component-override.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?-override.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component-override":
12 | # Specify terraform binary to run
13 | command: "/usr/local/bin/terraform"
14 | # The `component` attribute specifies that `test-component-override` inherits from the `test-component` base component.
15 | # `test-component-override` can override all the variables and other settings of the base component (except the `metadata` section).
16 | # In this example, variables for each service are overridden in `catalog/services/service-?-override.*`
17 | component: "test/test-component"
18 | # Other variables can be overridden here
19 | vars: {}
20 | # Other ENV vars can be overridden here
21 | env:
22 | TEST_ENV_VAR1: "val1-override"
23 | TEST_ENV_VAR3: "val3-override"
24 | TEST_ENV_VAR4: "val4"
25 | # Override remote state backend for this component
26 | remote_state_backend_type: static # s3, remote, vault, static, etc.
27 | remote_state_backend:
28 | static:
29 | val1: true
30 | val2: "2"
31 | val3: 3
32 | val4: null
33 | metadata:
34 | # Override Terraform workspace
35 | # Note that by default, Terraform workspace is generated from the context, e.g. `-`
36 | terraform_workspace: test-component-override-workspace-override
37 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/test-component.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/service-?.*
8 |
9 | components:
10 | terraform:
11 | "test/test-component":
12 | component: "test/test-component"
13 | settings:
14 | spacelift:
15 | workspace_enabled: true
16 | # Setting `metadata.type: abstract` makes the component `abstract` (similar to OOP abstract classes, which can't be instantiated),
17 | # explicitly prohibiting the component from being deployed,
18 | # and a Spacelift stack from being created for the component (even if `settings.spacelift.workspace_enabled: true`).
19 | # `terraform apply` and `terraform deploy` will fail with an error that the component cannot be provisioned.
20 | # All other terraform commands on this component will succeed.
21 | # If `metadata.type` attribute is not specified, it defaults to `real` (which means the component can be provisioned).
22 | metadata:
23 | type: real # `real` is implicit, you don't need to specify it; `abstract` makes the component protected from being deployed
24 | vars:
25 | enabled: true
26 | env:
27 | TEST_ENV_VAR1: "val1"
28 | TEST_ENV_VAR2: "val2"
29 | TEST_ENV_VAR3: "val3"
30 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/top-level-component1.yaml:
--------------------------------------------------------------------------------
1 | # `import` supports POSIX-style Globs for file names/paths (double-star `**` is supported)
2 | # https://en.wikipedia.org/wiki/Glob_(programming)
3 | # https://pkg.go.dev/gopkg.in/godo.v2/glob
4 | # https://github.com/bmatcuk/doublestar
5 | # File extensions are optional (if not specified, `.yaml` is used by default)
6 | import:
7 | - catalog/terraform/services/top-level-service-?.*
8 |
9 | components:
10 | terraform:
11 | top-level-component1:
12 | settings:
13 | spacelift:
14 | workspace_enabled: true
15 | vars:
16 | enabled: true
17 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/catalog/terraform/vpc.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 | "infra/vpc":
4 | backend:
5 | s3:
6 | workspace_key_prefix: infra-vpc
7 | settings:
8 | spacelift:
9 | workspace_enabled: true
10 | vars:
11 | enabled: true
12 | name: "common"
13 | subnet_type_tag_key: eg.io/subnet/type
14 | nat_gateway_enabled: true
15 | nat_instance_enabled: false
16 | max_subnet_count: 3
17 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/globals/globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | namespace: eg
3 |
4 | terraform:
5 | vars: {}
6 |
7 | backend_type: s3 # s3, remote, vault, static, azurerm, etc.
8 | backend:
9 | s3:
10 | encrypt: true
11 | bucket: "eg-ue2-root-tfstate"
12 | key: "terraform.tfstate"
13 | dynamodb_table: "eg-ue2-root-tfstate-lock"
14 | acl: "bucket-owner-full-control"
15 | region: "us-east-2"
16 | role_arn: null
17 | azurerm:
18 | subscription_id: 88888-8888-8888-8888-8888888888
19 | resource_group_name: rg-terraform-state
20 | storage_account_name: staterraformstate
21 | container_name: dev-tfstate
22 | key: dev.atmos
23 | remote:
24 | vault:
25 |
26 | remote_state_backend:
27 | s3:
28 | role_arn: "arn:aws:iam::123456789012:role/eg-gbl-root-terraform"
29 |
30 | helmfile:
31 | vars: {}
32 |
33 | components:
34 | terraform: {}
35 | helmfile: {}
36 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/globals/tenant1-globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | tenant: tenant1
3 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/globals/tenant2-globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | tenant: tenant2
3 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/globals/ue2-globals.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/globals
3 |
4 | vars:
5 | region: us-east-2
6 | environment: ue2
7 |
8 | helmfile:
9 | vars: {}
10 |
11 | components:
12 | terraform:
13 | "infra/vpc":
14 | vars:
15 | availability_zones: ["us-east-2a", "us-east-2b", "us-east-2c"]
16 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/tenant1/ue2/dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/test-component-override-2
8 | - catalog/terraform/test-component-override-3
9 | - catalog/terraform/vpc
10 | - catalog/terraform/tenant1-ue2-dev
11 | - catalog/helmfile/echo-server
12 | - catalog/helmfile/infra-server
13 | - catalog/helmfile/infra-server-override
14 |
15 | vars:
16 | stage: dev
17 |
18 | terraform:
19 | vars: {}
20 |
21 | helmfile:
22 | vars: {}
23 |
24 | components:
25 | terraform:
26 | "infra/vpc":
27 | vars:
28 | cidr_block: 10.10.0.0/18
29 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/tenant1/ue2/prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/test-component-override-2
8 | - catalog/terraform/test-component-override-3
9 | - catalog/terraform/vpc
10 | - catalog/helmfile/echo-server
11 | - catalog/helmfile/infra-server
12 | - catalog/helmfile/infra-server-override
13 |
14 | vars:
15 | stage: prod
16 |
17 | terraform:
18 | vars: {}
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | "infra/vpc":
26 | vars:
27 | cidr_block: 10.8.0.0/18
28 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/tenant1/ue2/staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant1-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/test-component-override-2
8 | - catalog/terraform/test-component-override-3
9 | - catalog/terraform/vpc
10 | - catalog/helmfile/echo-server
11 | - catalog/helmfile/infra-server
12 | - catalog/helmfile/infra-server-override
13 |
14 | vars:
15 | stage: staging
16 |
17 | terraform:
18 | vars: {}
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | "infra/vpc":
26 | vars:
27 | cidr_block: 10.9.0.0/18
28 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/tenant2/ue2/dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/test-component-override-2
8 | - catalog/terraform/test-component-override-3
9 | - catalog/terraform/vpc
10 | - catalog/helmfile/echo-server
11 | - catalog/helmfile/infra-server
12 | - catalog/helmfile/infra-server-override
13 |
14 | vars:
15 | stage: dev
16 |
17 | terraform:
18 | vars: {}
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | "infra/vpc":
26 | vars:
27 | cidr_block: 10.10.0.0/18
28 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/tenant2/ue2/prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/test-component-override-2
8 | - catalog/terraform/test-component-override-3
9 | - catalog/terraform/vpc
10 | - catalog/helmfile/echo-server
11 | - catalog/helmfile/infra-server
12 | - catalog/helmfile/infra-server-override
13 |
14 | vars:
15 | stage: prod
16 |
17 | terraform:
18 | vars: {}
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | "infra/vpc":
26 | vars:
27 | cidr_block: 10.8.0.0/18
28 |
--------------------------------------------------------------------------------
/examples/spacelift/stacks/tenant2/ue2/staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals/tenant2-globals
3 | - globals/ue2-globals
4 | - catalog/terraform/top-level-component1
5 | - catalog/terraform/test-component
6 | - catalog/terraform/test-component-override
7 | - catalog/terraform/test-component-override-2
8 | - catalog/terraform/test-component-override-3
9 | - catalog/terraform/vpc
10 | - catalog/helmfile/echo-server
11 | - catalog/helmfile/infra-server
12 | - catalog/helmfile/infra-server-override
13 |
14 | vars:
15 | stage: staging
16 |
17 | terraform:
18 | vars: {}
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | "infra/vpc":
26 | vars:
27 | cidr_block: 10.9.0.0/18
28 |
--------------------------------------------------------------------------------
/examples/spacelift/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_deps_processing_enabled" {
2 | type = bool
3 | description = "Boolean flag to enable/disable processing all stack dependencies in the provided stack"
4 | default = false
5 | }
6 |
7 | variable "component_deps_processing_enabled" {
8 | type = bool
9 | description = "Boolean flag to enable/disable processing stack config dependencies for the components in the provided stack"
10 | default = true
11 | }
12 |
13 | variable "imports_processing_enabled" {
14 | type = bool
15 | description = "Enable/disable processing stack imports"
16 | default = false
17 | }
18 |
19 | variable "stack_config_path_template" {
20 | type = string
21 | description = "Stack config path template"
22 | default = "stacks/%s.yaml"
23 | }
24 |
25 | variable "env" {
26 | type = map(string)
27 | description = "Map of ENV vars in the format `key=value`. These ENV vars will be set in the `utils` provider before executing the data source"
28 | default = null
29 | }
30 |
--------------------------------------------------------------------------------
/examples/spacelift/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.8.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/stack/context.tf:
--------------------------------------------------------------------------------
1 | #
2 | # ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label
3 | # All other instances of this file should be a copy of that one
4 | #
5 | #
6 | # Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf
7 | # and then place it in your Terraform module to automatically get
8 | # Cloud Posse's standard configuration inputs suitable for passing
9 | # to Cloud Posse modules.
10 | #
11 | # curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf
12 | #
13 | # Modules should access the whole context as `module.this.context`
14 | # to get the input variables with nulls for defaults,
15 | # for example `context = module.this.context`,
16 | # and access individual variables as `module.this.`,
17 | # with final values filled in.
18 | #
19 | # For example, when using defaults, `module.this.context.delimiter`
20 | # will be null, and `module.this.delimiter` will be `-` (hyphen).
21 | #
22 |
23 | module "this" {
24 | source = "cloudposse/label/null"
25 | version = "0.25.0" # requires Terraform >= 0.13.0
26 |
27 | enabled = var.enabled
28 | namespace = var.namespace
29 | tenant = var.tenant
30 | environment = var.environment
31 | stage = var.stage
32 | name = var.name
33 | delimiter = var.delimiter
34 | attributes = var.attributes
35 | tags = var.tags
36 | additional_tag_map = var.additional_tag_map
37 | label_order = var.label_order
38 | regex_replace_chars = var.regex_replace_chars
39 | id_length_limit = var.id_length_limit
40 | label_key_case = var.label_key_case
41 | label_value_case = var.label_value_case
42 | descriptor_formats = var.descriptor_formats
43 | labels_as_tags = var.labels_as_tags
44 |
45 | context = var.context
46 | }
47 |
48 | # Copy contents of cloudposse/terraform-null-label/variables.tf here
49 |
50 | variable "context" {
51 | type = any
52 | default = {
53 | enabled = true
54 | namespace = null
55 | tenant = null
56 | environment = null
57 | stage = null
58 | name = null
59 | delimiter = null
60 | attributes = []
61 | tags = {}
62 | additional_tag_map = {}
63 | regex_replace_chars = null
64 | label_order = []
65 | id_length_limit = null
66 | label_key_case = null
67 | label_value_case = null
68 | descriptor_formats = {}
69 | # Note: we have to use [] instead of null for unset lists due to
70 | # https://github.com/hashicorp/terraform/issues/28137
71 | # which was not fixed until Terraform 1.0.0,
72 | # but we want the default to be all the labels in `label_order`
73 | # and we want users to be able to prevent all tag generation
74 | # by setting `labels_as_tags` to `[]`, so we need
75 | # a different sentinel to indicate "default"
76 | labels_as_tags = ["unset"]
77 | }
78 | description = <<-EOT
79 | Single object for setting entire context at once.
80 | See description of individual variables for details.
81 | Leave string and numeric variables as `null` to use default value.
82 | Individual variable settings (non-null) override settings in context object,
83 | except for attributes, tags, and additional_tag_map, which are merged.
84 | EOT
85 |
86 | validation {
87 | condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"])
88 | error_message = "Allowed values: `lower`, `title`, `upper`."
89 | }
90 |
91 | validation {
92 | condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"])
93 | error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
94 | }
95 | }
96 |
97 | variable "enabled" {
98 | type = bool
99 | default = null
100 | description = "Set to false to prevent the module from creating any resources"
101 | }
102 |
103 | variable "namespace" {
104 | type = string
105 | default = null
106 | description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique"
107 | }
108 |
109 | variable "tenant" {
110 | type = string
111 | default = null
112 | description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for"
113 | }
114 |
115 | variable "environment" {
116 | type = string
117 | default = null
118 | description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'"
119 | }
120 |
121 | variable "stage" {
122 | type = string
123 | default = null
124 | description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'"
125 | }
126 |
127 | variable "name" {
128 | type = string
129 | default = null
130 | description = <<-EOT
131 | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
132 | This is the only ID element not also included as a `tag`.
133 | The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input.
134 | EOT
135 | }
136 |
137 | variable "delimiter" {
138 | type = string
139 | default = null
140 | description = <<-EOT
141 | Delimiter to be used between ID elements.
142 | Defaults to `-` (hyphen). Set to `""` to use no delimiter at all.
143 | EOT
144 | }
145 |
146 | variable "attributes" {
147 | type = list(string)
148 | default = []
149 | description = <<-EOT
150 | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
151 | in the order they appear in the list. New attributes are appended to the
152 | end of the list. The elements of the list are joined by the `delimiter`
153 | and treated as a single ID element.
154 | EOT
155 | }
156 |
157 | variable "labels_as_tags" {
158 | type = set(string)
159 | default = ["default"]
160 | description = <<-EOT
161 | Set of labels (ID elements) to include as tags in the `tags` output.
162 | Default is to include all labels.
163 | Tags with empty values will not be included in the `tags` output.
164 | Set to `[]` to suppress all generated tags.
165 | **Notes:**
166 | The value of the `name` tag, if included, will be the `id`, not the `name`.
167 | Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
168 | changed in later chained modules. Attempts to change it will be silently ignored.
169 | EOT
170 | }
171 |
172 | variable "tags" {
173 | type = map(string)
174 | default = {}
175 | description = <<-EOT
176 | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
177 | Neither the tag keys nor the tag values will be modified by this module.
178 | EOT
179 | }
180 |
181 | variable "additional_tag_map" {
182 | type = map(string)
183 | default = {}
184 | description = <<-EOT
185 | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
186 | This is for some rare cases where resources want additional configuration of tags
187 | and therefore take a list of maps with tag key, value, and additional configuration.
188 | EOT
189 | }
190 |
191 | variable "label_order" {
192 | type = list(string)
193 | default = null
194 | description = <<-EOT
195 | The order in which the labels (ID elements) appear in the `id`.
196 | Defaults to ["namespace", "environment", "stage", "name", "attributes"].
197 | You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present.
198 | EOT
199 | }
200 |
201 | variable "regex_replace_chars" {
202 | type = string
203 | default = null
204 | description = <<-EOT
205 | Terraform regular expression (regex) string.
206 | Characters matching the regex will be removed from the ID elements.
207 | If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits.
208 | EOT
209 | }
210 |
211 | variable "id_length_limit" {
212 | type = number
213 | default = null
214 | description = <<-EOT
215 | Limit `id` to this many characters (minimum 6).
216 | Set to `0` for unlimited length.
217 | Set to `null` for keep the existing setting, which defaults to `0`.
218 | Does not affect `id_full`.
219 | EOT
220 | validation {
221 | condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0
222 | error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length."
223 | }
224 | }
225 |
226 | variable "label_key_case" {
227 | type = string
228 | default = null
229 | description = <<-EOT
230 | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
231 | Does not affect keys of tags passed in via the `tags` input.
232 | Possible values: `lower`, `title`, `upper`.
233 | Default value: `title`.
234 | EOT
235 |
236 | validation {
237 | condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case)
238 | error_message = "Allowed values: `lower`, `title`, `upper`."
239 | }
240 | }
241 |
242 | variable "label_value_case" {
243 | type = string
244 | default = null
245 | description = <<-EOT
246 | Controls the letter case of ID elements (labels) as included in `id`,
247 | set as tag values, and output by this module individually.
248 | Does not affect values of tags passed in via the `tags` input.
249 | Possible values: `lower`, `title`, `upper` and `none` (no transformation).
250 | Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
251 | Default value: `lower`.
252 | EOT
253 |
254 | validation {
255 | condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case)
256 | error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
257 | }
258 | }
259 |
260 | variable "descriptor_formats" {
261 | type = any
262 | default = {}
263 | description = <<-EOT
264 | Describe additional descriptors to be output in the `descriptors` output map.
265 | Map of maps. Keys are names of descriptors. Values are maps of the form
266 | `{
267 | format = string
268 | labels = list(string)
269 | }`
270 | (Type is `any` so the map values can later be enhanced to provide additional options.)
271 | `format` is a Terraform format string to be passed to the `format()` function.
272 | `labels` is a list of labels, in order, to pass to `format()` function.
273 | Label values will be normalized before being passed to `format()` so they will be
274 | identical to how they appear in `id`.
275 | Default is `{}` (`descriptors` output will be empty).
276 | EOT
277 | }
278 |
279 | #### End of copy of cloudposse/terraform-null-label/variables.tf
280 |
--------------------------------------------------------------------------------
/examples/stack/fixtures.tfvars:
--------------------------------------------------------------------------------
1 | enabled = true
2 |
3 | stack = "my-stack"
4 |
--------------------------------------------------------------------------------
/examples/stack/main.tf:
--------------------------------------------------------------------------------
1 | # Since `var.stack` is provided, the module should just return it
2 | module "stack_1" {
3 | source = "../../modules/stack"
4 |
5 | stack = var.stack
6 |
7 | context = module.this.context
8 | }
9 |
10 | # Since `var.stack` is provided, the module should just return it regardless of all other settings
11 | module "stack_2" {
12 | source = "../../modules/stack"
13 |
14 | stack = var.stack
15 | environment = "uw2"
16 | stage = "dev"
17 |
18 | context = module.this.context
19 | }
20 |
21 | # Since `var.stack` and `var.descriptor_formats` are not provided, the module creates the stack name from the provided context
22 | module "stack_3" {
23 | source = "../../modules/stack"
24 |
25 | environment = "uw2"
26 | stage = "dev"
27 |
28 | context = module.this.context
29 | }
30 |
31 | # Since `var.stack` and `var.descriptor_formats` are not provided, the module creates the stack name from the provided context
32 | module "stack_4" {
33 | source = "../../modules/stack"
34 |
35 | tenant = "acme"
36 | environment = "uw2"
37 | stage = "dev"
38 |
39 | context = module.this.context
40 | }
41 |
42 | # Test `descriptor_formats`
43 | module "stack_5" {
44 | source = "../../modules/stack"
45 |
46 | tenant = "acme"
47 | environment = "uw2"
48 | stage = "dev"
49 |
50 | descriptor_formats = {
51 | stack = {
52 | labels = ["tenant", "environment", "stage"]
53 | format = "%v-%v-%v"
54 | }
55 | }
56 |
57 | context = module.this.context
58 | }
59 |
60 | # Test `descriptor_formats`
61 | module "stack_6" {
62 | source = "../../modules/stack"
63 |
64 | tenant = "acme"
65 | environment = "uw2"
66 | stage = "dev"
67 |
68 | descriptor_formats = {
69 | stack = {
70 | labels = ["stage", "environment", "tenant"]
71 | format = "%v-%v-%v"
72 | }
73 | }
74 |
75 | context = module.this.context
76 | }
77 |
78 | # Test `descriptor_formats`
79 | module "stack_7" {
80 | source = "../../modules/stack"
81 |
82 | tenant = "acme"
83 | environment = "uw2"
84 | stage = "dev"
85 |
86 | descriptor_formats = {
87 | stack = {
88 | labels = ["environment", "tenant", "stage"]
89 | format = "%v-%v-%v"
90 | }
91 | }
92 |
93 | context = module.this.context
94 | }
95 |
96 | # Test `descriptor_formats`
97 | module "stack_8" {
98 | source = "../../modules/stack"
99 |
100 | tenant = "acme"
101 | environment = "uw2"
102 | stage = "dev"
103 |
104 | descriptor_formats = {
105 | stack = {
106 | labels = ["stage", "tenant", "environment"]
107 | format = "%v-%v-%v"
108 | }
109 | }
110 |
111 | context = module.this.context
112 | }
113 |
114 | # Since `var.stack` is provided, the module should just return it regardless of all other settings (don't use `var.stack` and `var.descriptor_formats)
115 | module "stack_9" {
116 | source = "../../modules/stack"
117 |
118 | stack = var.stack
119 | tenant = "acme"
120 | environment = "uw2"
121 | stage = "dev"
122 |
123 | descriptor_formats = {
124 | stack = {
125 | labels = ["tenant", "environment", "stage"]
126 | format = "%v-%v-%v"
127 | }
128 | }
129 |
130 | context = module.this.context
131 | }
132 |
--------------------------------------------------------------------------------
/examples/stack/outputs.tf:
--------------------------------------------------------------------------------
1 | output "stack_1_name" {
2 | value = module.stack_1.stack_name
3 | description = "Name of stack 1"
4 | }
5 |
6 | output "stack_2_name" {
7 | value = module.stack_2.stack_name
8 | description = "Name of stack 2"
9 | }
10 |
11 | output "stack_3_name" {
12 | value = module.stack_3.stack_name
13 | description = "Name of stack 3"
14 | }
15 |
16 | output "stack_4_name" {
17 | value = module.stack_4.stack_name
18 | description = "Name of stack 4"
19 | }
20 |
21 | output "stack_5_name" {
22 | value = module.stack_5.stack_name
23 | description = "Name of stack 5"
24 | }
25 |
26 | output "stack_6_name" {
27 | value = module.stack_6.stack_name
28 | description = "Name of stack 6"
29 | }
30 |
31 | output "stack_7_name" {
32 | value = module.stack_7.stack_name
33 | description = "Name of stack 7"
34 | }
35 |
36 | output "stack_8_name" {
37 | value = module.stack_8.stack_name
38 | description = "Name of stack 8"
39 | }
40 |
41 | output "stack_9_name" {
42 | value = module.stack_9.stack_name
43 | description = "Name of stack 9"
44 | }
45 |
--------------------------------------------------------------------------------
/examples/stack/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack" {
2 | type = string
3 | description = "Stack name"
4 | }
5 |
--------------------------------------------------------------------------------
/examples/stack/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.8.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/stacks/atmos.yaml:
--------------------------------------------------------------------------------
1 | # CLI config is loaded from the following locations (from lowest to highest priority):
2 | # system dir (`/usr/local/etc/atmos` on Linux, `%LOCALAPPDATA%/atmos` on Windows)
3 | # home dir (~/.atmos)
4 | # current directory
5 | # ENV vars
6 | # Command-line arguments
7 | #
8 | # It supports POSIX-style Globs for file names/paths (double-star `**` is supported)
9 | # https://en.wikipedia.org/wiki/Glob_(programming)
10 |
11 | # Base path for components, stacks and workflows configurations.
12 | # Can also be set using `ATMOS_BASE_PATH` ENV var, or `--base-path` command-line argument.
13 | # Supports both absolute and relative paths.
14 | # If not provided or is an empty string, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
15 | # are independent settings (supporting both absolute and relative paths).
16 | # If `base_path` is provided, `components.terraform.base_path`, `components.helmfile.base_path`, `stacks.base_path` and `workflows.base_path`
17 | # are considered paths relative to `base_path`.
18 | base_path: "."
19 |
20 | components:
21 | terraform:
22 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_BASE_PATH` ENV var, or `--terraform-dir` command-line argument
23 | # Supports both absolute and relative paths
24 | base_path: "components/terraform"
25 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_APPLY_AUTO_APPROVE` ENV var
26 | apply_auto_approve: false
27 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_DEPLOY_RUN_INIT` ENV var, or `--deploy-run-init` command-line argument
28 | deploy_run_init: true
29 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_INIT_RUN_RECONFIGURE` ENV var, or `--init-run-reconfigure` command-line argument
30 | init_run_reconfigure: true
31 | # Can also be set using `ATMOS_COMPONENTS_TERRAFORM_AUTO_GENERATE_BACKEND_FILE` ENV var, or `--auto-generate-backend-file` command-line argument
32 | auto_generate_backend_file: false
33 | helmfile:
34 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_BASE_PATH` ENV var, or `--helmfile-dir` command-line argument
35 | # Supports both absolute and relative paths
36 | base_path: "components/helmfile"
37 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_KUBECONFIG_PATH` ENV var
38 | kubeconfig_path: "/dev/shm"
39 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_HELM_AWS_PROFILE_PATTERN` ENV var
40 | helm_aws_profile_pattern: "{namespace}-{tenant}-gbl-{stage}-helm"
41 | # Can also be set using `ATMOS_COMPONENTS_HELMFILE_CLUSTER_NAME_PATTERN` ENV var
42 | cluster_name_pattern: "{namespace}-{tenant}-{environment}-{stage}-eks-cluster"
43 |
44 | stacks:
45 | # Can also be set using `ATMOS_STACKS_BASE_PATH` ENV var, or `--config-dir` and `--stacks-dir` command-line arguments
46 | # Supports both absolute and relative paths
47 | base_path: "stacks"
48 | # Can also be set using `ATMOS_STACKS_INCLUDED_PATHS` ENV var (comma-separated values string)
49 | included_paths:
50 | - "**/*"
51 | # Can also be set using `ATMOS_STACKS_EXCLUDED_PATHS` ENV var (comma-separated values string)
52 | excluded_paths:
53 | - "globals/**/*"
54 | - "catalog/**/*"
55 | - "**/*globals*"
56 | # Can also be set using `ATMOS_STACKS_NAME_PATTERN` ENV var
57 | name_pattern: "{tenant}-{environment}-{stage}"
58 |
59 | workflows:
60 | # Can also be set using `ATMOS_WORKFLOWS_BASE_PATH` ENV var, or `--workflows-dir` command-line arguments
61 | # Supports both absolute and relative paths
62 | base_path: "workflows"
63 |
64 | logs:
65 | file: "/dev/stdout"
66 | # Supported log levels: Trace, Debug, Info, Warning, Off
67 | level: Info
68 |
--------------------------------------------------------------------------------
/examples/stacks/context.tf:
--------------------------------------------------------------------------------
1 | #
2 | # ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label
3 | # All other instances of this file should be a copy of that one
4 | #
5 | #
6 | # Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf
7 | # and then place it in your Terraform module to automatically get
8 | # Cloud Posse's standard configuration inputs suitable for passing
9 | # to Cloud Posse modules.
10 | #
11 | # curl -sL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf -o context.tf
12 | #
13 | # Modules should access the whole context as `module.this.context`
14 | # to get the input variables with nulls for defaults,
15 | # for example `context = module.this.context`,
16 | # and access individual variables as `module.this.`,
17 | # with final values filled in.
18 | #
19 | # For example, when using defaults, `module.this.context.delimiter`
20 | # will be null, and `module.this.delimiter` will be `-` (hyphen).
21 | #
22 |
23 | module "this" {
24 | source = "cloudposse/label/null"
25 | version = "0.25.0" # requires Terraform >= 0.13.0
26 |
27 | enabled = var.enabled
28 | namespace = var.namespace
29 | tenant = var.tenant
30 | environment = var.environment
31 | stage = var.stage
32 | name = var.name
33 | delimiter = var.delimiter
34 | attributes = var.attributes
35 | tags = var.tags
36 | additional_tag_map = var.additional_tag_map
37 | label_order = var.label_order
38 | regex_replace_chars = var.regex_replace_chars
39 | id_length_limit = var.id_length_limit
40 | label_key_case = var.label_key_case
41 | label_value_case = var.label_value_case
42 | descriptor_formats = var.descriptor_formats
43 | labels_as_tags = var.labels_as_tags
44 |
45 | context = var.context
46 | }
47 |
48 | # Copy contents of cloudposse/terraform-null-label/variables.tf here
49 |
50 | variable "context" {
51 | type = any
52 | default = {
53 | enabled = true
54 | namespace = null
55 | tenant = null
56 | environment = null
57 | stage = null
58 | name = null
59 | delimiter = null
60 | attributes = []
61 | tags = {}
62 | additional_tag_map = {}
63 | regex_replace_chars = null
64 | label_order = []
65 | id_length_limit = null
66 | label_key_case = null
67 | label_value_case = null
68 | descriptor_formats = {}
69 | # Note: we have to use [] instead of null for unset lists due to
70 | # https://github.com/hashicorp/terraform/issues/28137
71 | # which was not fixed until Terraform 1.0.0,
72 | # but we want the default to be all the labels in `label_order`
73 | # and we want users to be able to prevent all tag generation
74 | # by setting `labels_as_tags` to `[]`, so we need
75 | # a different sentinel to indicate "default"
76 | labels_as_tags = ["unset"]
77 | }
78 | description = <<-EOT
79 | Single object for setting entire context at once.
80 | See description of individual variables for details.
81 | Leave string and numeric variables as `null` to use default value.
82 | Individual variable settings (non-null) override settings in context object,
83 | except for attributes, tags, and additional_tag_map, which are merged.
84 | EOT
85 |
86 | validation {
87 | condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"])
88 | error_message = "Allowed values: `lower`, `title`, `upper`."
89 | }
90 |
91 | validation {
92 | condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"])
93 | error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
94 | }
95 | }
96 |
97 | variable "enabled" {
98 | type = bool
99 | default = null
100 | description = "Set to false to prevent the module from creating any resources"
101 | }
102 |
103 | variable "namespace" {
104 | type = string
105 | default = null
106 | description = "ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique"
107 | }
108 |
109 | variable "tenant" {
110 | type = string
111 | default = null
112 | description = "ID element _(Rarely used, not included by default)_. A customer identifier, indicating who this instance of a resource is for"
113 | }
114 |
115 | variable "environment" {
116 | type = string
117 | default = null
118 | description = "ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT'"
119 | }
120 |
121 | variable "stage" {
122 | type = string
123 | default = null
124 | description = "ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release'"
125 | }
126 |
127 | variable "name" {
128 | type = string
129 | default = null
130 | description = <<-EOT
131 | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
132 | This is the only ID element not also included as a `tag`.
133 | The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input.
134 | EOT
135 | }
136 |
137 | variable "delimiter" {
138 | type = string
139 | default = null
140 | description = <<-EOT
141 | Delimiter to be used between ID elements.
142 | Defaults to `-` (hyphen). Set to `""` to use no delimiter at all.
143 | EOT
144 | }
145 |
146 | variable "attributes" {
147 | type = list(string)
148 | default = []
149 | description = <<-EOT
150 | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
151 | in the order they appear in the list. New attributes are appended to the
152 | end of the list. The elements of the list are joined by the `delimiter`
153 | and treated as a single ID element.
154 | EOT
155 | }
156 |
157 | variable "labels_as_tags" {
158 | type = set(string)
159 | default = ["default"]
160 | description = <<-EOT
161 | Set of labels (ID elements) to include as tags in the `tags` output.
162 | Default is to include all labels.
163 | Tags with empty values will not be included in the `tags` output.
164 | Set to `[]` to suppress all generated tags.
165 | **Notes:**
166 | The value of the `name` tag, if included, will be the `id`, not the `name`.
167 | Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
168 | changed in later chained modules. Attempts to change it will be silently ignored.
169 | EOT
170 | }
171 |
172 | variable "tags" {
173 | type = map(string)
174 | default = {}
175 | description = <<-EOT
176 | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
177 | Neither the tag keys nor the tag values will be modified by this module.
178 | EOT
179 | }
180 |
181 | variable "additional_tag_map" {
182 | type = map(string)
183 | default = {}
184 | description = <<-EOT
185 | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
186 | This is for some rare cases where resources want additional configuration of tags
187 | and therefore take a list of maps with tag key, value, and additional configuration.
188 | EOT
189 | }
190 |
191 | variable "label_order" {
192 | type = list(string)
193 | default = null
194 | description = <<-EOT
195 | The order in which the labels (ID elements) appear in the `id`.
196 | Defaults to ["namespace", "environment", "stage", "name", "attributes"].
197 | You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present.
198 | EOT
199 | }
200 |
201 | variable "regex_replace_chars" {
202 | type = string
203 | default = null
204 | description = <<-EOT
205 | Terraform regular expression (regex) string.
206 | Characters matching the regex will be removed from the ID elements.
207 | If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits.
208 | EOT
209 | }
210 |
211 | variable "id_length_limit" {
212 | type = number
213 | default = null
214 | description = <<-EOT
215 | Limit `id` to this many characters (minimum 6).
216 | Set to `0` for unlimited length.
217 | Set to `null` for keep the existing setting, which defaults to `0`.
218 | Does not affect `id_full`.
219 | EOT
220 | validation {
221 | condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0
222 | error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length."
223 | }
224 | }
225 |
226 | variable "label_key_case" {
227 | type = string
228 | default = null
229 | description = <<-EOT
230 | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
231 | Does not affect keys of tags passed in via the `tags` input.
232 | Possible values: `lower`, `title`, `upper`.
233 | Default value: `title`.
234 | EOT
235 |
236 | validation {
237 | condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case)
238 | error_message = "Allowed values: `lower`, `title`, `upper`."
239 | }
240 | }
241 |
242 | variable "label_value_case" {
243 | type = string
244 | default = null
245 | description = <<-EOT
246 | Controls the letter case of ID elements (labels) as included in `id`,
247 | set as tag values, and output by this module individually.
248 | Does not affect values of tags passed in via the `tags` input.
249 | Possible values: `lower`, `title`, `upper` and `none` (no transformation).
250 | Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
251 | Default value: `lower`.
252 | EOT
253 |
254 | validation {
255 | condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case)
256 | error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
257 | }
258 | }
259 |
260 | variable "descriptor_formats" {
261 | type = any
262 | default = {}
263 | description = <<-EOT
264 | Describe additional descriptors to be output in the `descriptors` output map.
265 | Map of maps. Keys are names of descriptors. Values are maps of the form
266 | `{
267 | format = string
268 | labels = list(string)
269 | }`
270 | (Type is `any` so the map values can later be enhanced to provide additional options.)
271 | `format` is a Terraform format string to be passed to the `format()` function.
272 | `labels` is a list of labels, in order, to pass to `format()` function.
273 | Label values will be normalized before being passed to `format()` so they will be
274 | identical to how they appear in `id`.
275 | Default is `{}` (`descriptors` output will be empty).
276 | EOT
277 | }
278 |
279 | #### End of copy of cloudposse/terraform-null-label/variables.tf
280 |
--------------------------------------------------------------------------------
/examples/stacks/fixtures.tfvars:
--------------------------------------------------------------------------------
1 | enabled = true
2 |
3 | stacks = [
4 | "uw2-dev",
5 | "uw2-prod",
6 | "uw2-staging",
7 | "uw2-uat"
8 | ]
9 |
10 | stack_deps_processing_enabled = true
11 |
12 | component_deps_processing_enabled = true
13 |
--------------------------------------------------------------------------------
/examples/stacks/main.tf:
--------------------------------------------------------------------------------
1 | module "stacks" {
2 | source = "../../"
3 |
4 | stack_config_local_path = "${path.cwd}/stacks"
5 | stacks = var.stacks
6 | stack_deps_processing_enabled = var.stack_deps_processing_enabled
7 | component_deps_processing_enabled = var.component_deps_processing_enabled
8 |
9 | context = module.this.context
10 | }
11 |
--------------------------------------------------------------------------------
/examples/stacks/outputs.tf:
--------------------------------------------------------------------------------
1 | output "config" {
2 | value = module.stacks.config
3 | description = "Stack configurations"
4 | }
5 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/eks/eks-defaults.yaml:
--------------------------------------------------------------------------------
1 | components:
2 | terraform:
3 |
4 | efs:
5 | vars: {}
6 |
7 | eks-iam:
8 | vars: {}
9 |
10 | helmfile:
11 |
12 | alb-controller:
13 | vars:
14 | installed: true
15 | chart_values:
16 | enableCertManager: true
17 |
18 | codefresh-account:
19 | vars:
20 | installed: true
21 | unlimited_staging_enabled: false
22 |
23 | echo-server:
24 | vars:
25 | installed: true
26 |
27 | efs-provisioner:
28 | vars:
29 | installed: true
30 |
31 | external-dns:
32 | vars:
33 | installed: true
34 |
35 | idp-roles:
36 | vars:
37 | installed: true
38 |
39 | metrics-server:
40 | vars:
41 | installed: true
42 |
43 | cert-manager:
44 | vars:
45 | installed: true
46 |
47 | ocean-controller:
48 | vars:
49 | installed: true
50 |
51 | reloader:
52 | vars:
53 | installed: true
54 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/globals.yaml:
--------------------------------------------------------------------------------
1 | vars:
2 | namespace: eg
3 |
4 | terraform:
5 | vars: {}
6 |
7 | backend_type: s3 # s3, remote, vault, etc.
8 | backend:
9 | s3:
10 | encrypt: true
11 | bucket: "eg-uw2-root-tfstate"
12 | key: "terraform.tfstate"
13 | dynamodb_table: "eg-uw2-root-tfstate-lock"
14 | role_arn: "arn:aws:iam::XXXXXXXXXXXX:role/eg-gbl-root-terraform"
15 | acl: "bucket-owner-full-control"
16 | region: "us-west-2"
17 | remote: {}
18 | vault: {}
19 |
20 | helmfile:
21 | vars: {}
22 |
23 | components:
24 | terraform:
25 | tfstate-backend:
26 | backend:
27 | s3:
28 | workspace_key_prefix: "tfstate-backend"
29 | role_arn: null
30 |
31 | account:
32 | backend:
33 | s3:
34 | workspace_key_prefix: "account"
35 | role_arn: null
36 |
37 | account-map:
38 | backend:
39 | s3:
40 | workspace_key_prefix: "account-map"
41 | role_arn: null
42 |
43 | account-settings:
44 | backend:
45 | s3:
46 | workspace_key_prefix: "account-settings"
47 | role_arn: null
48 |
49 | dns-delegated:
50 | backend:
51 | s3:
52 | workspace_key_prefix: "dns-delegated"
53 |
54 | dns-primary:
55 | backend:
56 | s3:
57 | workspace_key_prefix: "dns-primary"
58 |
59 | eks:
60 | backend:
61 | s3:
62 | workspace_key_prefix: "eks"
63 |
64 | eks-iam:
65 | backend:
66 | s3:
67 | workspace_key_prefix: "eks-iam"
68 |
69 | iam-delegated-roles:
70 | backend:
71 | s3:
72 | workspace_key_prefix: "iam-delegated-roles"
73 | role_arn: null
74 |
75 | iam-primary-roles:
76 | backend:
77 | s3:
78 | workspace_key_prefix: "iam-primary-roles"
79 | role_arn: null
80 |
81 | spotinst-integration:
82 | backend:
83 | s3:
84 | workspace_key_prefix: "spotinst-integration"
85 |
86 | sso:
87 | backend:
88 | s3:
89 | workspace_key_prefix: "sso"
90 | role_arn: null
91 |
92 | config-bucket:
93 | backend:
94 | s3:
95 | workspace_key_prefix: "config-bucket"
96 |
97 | cloudtrail-bucket:
98 | backend:
99 | s3:
100 | workspace_key_prefix: "cloudtrail-bucket"
101 |
102 | cloudtrail:
103 | vars:
104 | cloudtrail_bucket_environment_name: "uw2"
105 | cloudtrail_bucket_stage_name: "audit"
106 | backend:
107 | s3:
108 | workspace_key_prefix: "cloudtrail"
109 |
110 | transit-gateway:
111 | backend:
112 | s3:
113 | workspace_key_prefix: "transit-gateway"
114 |
115 | vpc-flow-logs-bucket:
116 | backend:
117 | s3:
118 | workspace_key_prefix: "vpc-flow-logs-bucket"
119 |
120 | vpc:
121 | vars:
122 | subnet_type_tag_key: "eg.com/subnet/type"
123 | vpc_flow_logs_enabled: true
124 | vpc_flow_logs_bucket_environment_name: "uw2"
125 | vpc_flow_logs_bucket_stage_name: "audit"
126 | vpc_flow_logs_traffic_type: "ALL"
127 | backend:
128 | s3:
129 | workspace_key_prefix: "vpc"
130 |
131 | ecr:
132 | backend:
133 | s3:
134 | workspace_key_prefix: "ecr"
135 |
136 | datadog-integration:
137 | backend:
138 | s3:
139 | workspace_key_prefix: "datadog-integration"
140 |
141 | datadog-monitor:
142 | backend:
143 | s3:
144 | workspace_key_prefix: "datadog-monitor"
145 |
146 | aurora-postgres:
147 | backend:
148 | s3:
149 | workspace_key_prefix: "aurora-postgres"
150 |
151 | efs:
152 | backend:
153 | s3:
154 | workspace_key_prefix: "efs"
155 |
156 | mq-broker:
157 | backend:
158 | s3:
159 | workspace_key_prefix: "mq-broker"
160 |
161 | ses:
162 | backend:
163 | s3:
164 | workspace_key_prefix: "ses"
165 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/uw2-dev.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - uw2-globals
3 | - eks/eks-defaults
4 |
5 | vars:
6 | stage: dev
7 |
8 | terraform:
9 | vars: {}
10 |
11 | helmfile:
12 | vars:
13 | account_number: "1234567890"
14 |
15 | components:
16 | terraform:
17 |
18 | dns-delegated:
19 | vars:
20 | request_acm_certificate: true
21 | zone_config:
22 | - subdomain: dev
23 | zone_name: uw2.example.com
24 | settings:
25 | spacelift:
26 | workspace_enabled: true
27 | autodeploy: false
28 | branch: ""
29 | triggers: []
30 |
31 | eks:
32 | vars:
33 | spotinst_instance_profile: eg-gbl-dev-spotinst-worker
34 | spotinst_oceans:
35 | main:
36 | desired_group_size: 1
37 | max_group_size: 3
38 | min_group_size: 1
39 | kubernetes_version: null
40 | ami_release_version: null
41 | attributes: null
42 | disk_size: 100
43 | instance_types: null
44 | ami_type: "AL2_x86_64"
45 | tags: null
46 | settings:
47 | spacelift:
48 | workspace_enabled: true
49 | autodeploy: true
50 | branch: "test"
51 | triggers: []
52 | env:
53 | ENV_TEST_1: test1_override
54 | ENV_TEST_2: test2_override
55 | ENV_TEST_4: test4
56 |
57 | vpc:
58 | vars:
59 | cidr_block: "10.114.0.0/18"
60 | settings:
61 | spacelift:
62 | workspace_enabled: true
63 | autodeploy: true
64 | branch: ""
65 | triggers: []
66 |
67 | aurora-postgres:
68 | vars:
69 | instance_type: db.r4.large
70 | cluster_size: 1
71 | env:
72 | ENV_TEST_4: test4
73 | ENV_TEST_5: test5
74 | ENV_TEST_6: test6
75 | ENV_TEST_7: test7
76 |
77 | aurora-postgres-2:
78 | component: aurora-postgres
79 | vars:
80 | instance_type: db.r4.xlarge
81 | settings:
82 | spacelift:
83 | workspace_enabled: true
84 | autodeploy: true
85 | branch: "dev"
86 | triggers: []
87 | env:
88 | ENV_TEST_1: test1_override2
89 | ENV_TEST_2: test2_override2
90 | ENV_TEST_8: test8
91 |
92 | helmfile:
93 |
94 | datadog:
95 | vars:
96 | installed: true
97 | datadogTags:
98 | - "env:uw2-dev"
99 | - "region:us-west-2"
100 | - "stage:dev"
101 | env:
102 | ENV_DD_TEST_1: dd1
103 | ENV_DD_TEST_2: dd2
104 | ENV_DD_TEST_3: dd3
105 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/uw2-globals.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - globals
3 |
4 | vars:
5 | region: us-west-2
6 | environment: uw2
7 |
8 | terraform:
9 | vars: {}
10 | settings:
11 | version: 0
12 | spacelift:
13 | workspace_enabled: false
14 | autodeploy: false
15 | env:
16 | ENV_TEST_1: test1
17 | ENV_TEST_2: test2
18 | ENV_TEST_3: test3
19 |
20 | helmfile:
21 | vars:
22 | ssm_region: us-west-2
23 |
24 | components:
25 | terraform:
26 | vpc:
27 | vars:
28 | availability_zones: ["us-west-2b", "us-west-2c", "us-west-2d"]
29 |
30 | eks:
31 | vars:
32 | region_availability_zones: ["us-west-2b", "us-west-2c", "us-west-2d"]
33 |
34 | helmfile:
35 | datadog:
36 | vars:
37 | apm:
38 | enabled: true
39 | processAgent:
40 | enabled: true
41 | systemProbe:
42 | enabled: true
43 | clusterAgent:
44 | enabled: true
45 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/uw2-prod.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - uw2-globals
3 | - eks/eks-defaults
4 |
5 | vars:
6 | stage: prod
7 |
8 | terraform:
9 | vars: {}
10 |
11 | helmfile:
12 | vars:
13 | account_number: "1234567891"
14 |
15 | components:
16 | terraform:
17 |
18 | dns-delegated:
19 | vars:
20 | request_acm_certificate: true
21 | zone_config:
22 | - subdomain: prod
23 | zone_name: uw2.example.com
24 | settings:
25 | spacelift:
26 | workspace_enabled: true
27 | autodeploy: false
28 | branch: ""
29 | triggers: []
30 |
31 | eks:
32 | vars:
33 | spotinst_instance_profile: eg-gbl-prod-spotinst-worker
34 | spotinst_oceans:
35 | main:
36 | desired_group_size: 1
37 | max_group_size: 10
38 | min_group_size: 1
39 | kubernetes_version: null
40 | ami_release_version: null
41 | attributes: null
42 | disk_size: 100
43 | instance_types: null
44 | ami_type: "AL2_x86_64"
45 | tags: null
46 | settings:
47 | spacelift:
48 | workspace_enabled: true
49 | autodeploy: true
50 | branch: ""
51 | triggers: []
52 | env:
53 | ENV_TEST_1: test1_override
54 | ENV_TEST_2: test2_override
55 | ENV_TEST_4: test4
56 |
57 | vpc:
58 | vars:
59 | cidr_block: "10.116.0.0/18"
60 | settings:
61 | spacelift:
62 | workspace_enabled: true
63 | autodeploy: false
64 | branch: ""
65 | triggers: []
66 |
67 | aurora-postgres:
68 | vars:
69 | instance_type: db.r4.large
70 | cluster_size: 3
71 | env:
72 | ENV_TEST_4: test4
73 | ENV_TEST_5: test5
74 | ENV_TEST_6: test6
75 | ENV_TEST_7: test7
76 |
77 | aurora-postgres-2:
78 | component: aurora-postgres
79 | vars:
80 | instance_type: db.r4.xlarge
81 | settings:
82 | spacelift:
83 | workspace_enabled: true
84 | autodeploy: true
85 | branch: ""
86 | triggers: []
87 | env:
88 | ENV_TEST_1: test1_override2
89 | ENV_TEST_2: test2_override2
90 | ENV_TEST_8: test8
91 |
92 | helmfile:
93 |
94 | datadog:
95 | vars:
96 | installed: true
97 | datadogTags:
98 | - "env:uw2-prod"
99 | - "region:us-west-2"
100 | - "stage:prod"
101 | env:
102 | ENV_DD_TEST_1: dd1
103 | ENV_DD_TEST_2: dd2
104 | ENV_DD_TEST_3: dd3
105 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/uw2-staging.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - uw2-globals
3 | - eks/eks-defaults
4 |
5 | vars:
6 | stage: staging
7 |
8 | terraform:
9 | vars: {}
10 |
11 | helmfile:
12 | vars:
13 | account_number: "1234567892"
14 |
15 | components:
16 | terraform:
17 |
18 | dns-delegated:
19 | vars:
20 | request_acm_certificate: true
21 | zone_config:
22 | - subdomain: staging
23 | zone_name: uw2.example.com
24 | settings:
25 | spacelift:
26 | workspace_enabled: true
27 | autodeploy: false
28 | branch: ""
29 | triggers: []
30 |
31 | eks:
32 | vars:
33 | spotinst_instance_profile: eg-gbl-staging-spotinst-worker
34 | spotinst_oceans:
35 | main:
36 | desired_group_size: 1
37 | max_group_size: 5
38 | min_group_size: 1
39 | kubernetes_version: null
40 | ami_release_version: null
41 | attributes: null
42 | disk_size: 100
43 | instance_types: null
44 | ami_type: "AL2_x86_64"
45 | tags: null
46 | settings:
47 | spacelift:
48 | workspace_enabled: true
49 | autodeploy: true
50 | branch: ""
51 | triggers: []
52 | env:
53 | ENV_TEST_1: test1_override
54 | ENV_TEST_2: test2_override
55 | ENV_TEST_4: test4
56 |
57 | vpc:
58 | vars:
59 | cidr_block: "10.118.0.0/18"
60 | settings:
61 | spacelift:
62 | workspace_enabled: true
63 | autodeploy: false
64 | branch: ""
65 | triggers: []
66 |
67 | aurora-postgres:
68 | vars:
69 | instance_type: db.r4.large
70 | cluster_size: 2
71 | env:
72 | ENV_TEST_4: test4
73 | ENV_TEST_5: test5
74 | ENV_TEST_6: test6
75 | ENV_TEST_7: test7
76 |
77 | aurora-postgres-2:
78 | component: aurora-postgres
79 | vars:
80 | instance_type: db.r4.xlarge
81 | settings:
82 | spacelift:
83 | workspace_enabled: true
84 | autodeploy: true
85 | branch: ""
86 | triggers: []
87 | env:
88 | ENV_TEST_1: test1_override2
89 | ENV_TEST_2: test2_override2
90 | ENV_TEST_8: test8
91 |
92 | helmfile:
93 |
94 | datadog:
95 | vars:
96 | installed: true
97 | datadogTags:
98 | - "env:uw2-staging"
99 | - "region:us-west-2"
100 | - "stage:staging"
101 | env:
102 | ENV_DD_TEST_1: dd1
103 | ENV_DD_TEST_2: dd2
104 | ENV_DD_TEST_3: dd3
105 |
--------------------------------------------------------------------------------
/examples/stacks/stacks/uw2-uat.yaml:
--------------------------------------------------------------------------------
1 | import:
2 | - uw2-globals
3 | - eks/eks-defaults
4 |
5 | vars:
6 | stage: uat
7 |
8 | terraform:
9 | vars: {}
10 |
11 | helmfile:
12 | vars:
13 | account_number: "1234567893"
14 |
15 | components:
16 | terraform:
17 |
18 | dns-delegated:
19 | vars:
20 | request_acm_certificate: true
21 | zone_config:
22 | - subdomain: uat
23 | zone_name: uw2.example.com
24 | settings:
25 | spacelift:
26 | workspace_enabled: true
27 | autodeploy: false
28 | branch: ""
29 | triggers: []
30 |
31 | eks:
32 | vars:
33 | spotinst_instance_profile: eg-gbl-uat-spotinst-worker
34 | spotinst_oceans:
35 | main:
36 | desired_group_size: 1
37 | max_group_size: 3
38 | min_group_size: 1
39 | kubernetes_version: null
40 | ami_release_version: null
41 | attributes: null
42 | disk_size: 100
43 | instance_types: null
44 | ami_type: "AL2_x86_64"
45 | tags: null
46 | settings:
47 | spacelift:
48 | workspace_enabled: true
49 | autodeploy: false
50 | branch: "main"
51 | triggers: []
52 | env:
53 | ENV_TEST_1: test1_override
54 | ENV_TEST_2: test2_override
55 | ENV_TEST_4: test4
56 |
57 | vpc:
58 | vars:
59 | cidr_block: "10.120.0.0/18"
60 | settings:
61 | spacelift:
62 | workspace_enabled: true
63 | autodeploy: false
64 | branch: "main"
65 | triggers: []
66 |
67 | aurora-postgres:
68 | vars:
69 | instance_type: db.r4.large
70 | cluster_size: 2
71 | settings:
72 | version: 1
73 | spacelift:
74 | workspace_enabled: false
75 | autodeploy: false
76 | branch: "test3"
77 | triggers: ["4", "5", "6"]
78 | env:
79 | ENV_TEST_4: test4
80 | ENV_TEST_5: test5
81 | ENV_TEST_6: test6
82 | ENV_TEST_7: test7
83 |
84 | aurora-postgres-2:
85 | component: aurora-postgres
86 | vars:
87 | cluster_size: 3
88 | instance_type: db.r4.xlarge
89 | settings:
90 | version: 2
91 | spacelift:
92 | workspace_enabled: true
93 | autodeploy: true
94 | branch: "test4"
95 | triggers: ["7", "8", "9"]
96 | env:
97 | ENV_TEST_1: test1_override2
98 | ENV_TEST_2: test2_override2
99 | ENV_TEST_8: test8
100 |
101 | helmfile:
102 |
103 | datadog:
104 | vars:
105 | installed: true
106 | datadogTags:
107 | - "env:uw2-uat"
108 | - "region:us-west-2"
109 | - "stage:uat"
110 | env:
111 | ENV_DD_TEST_1: dd1
112 | ENV_DD_TEST_2: dd2
113 | ENV_DD_TEST_3: dd3
114 |
--------------------------------------------------------------------------------
/examples/stacks/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_config_local_path" {
2 | type = string
3 | description = "Path to local stack configs"
4 | default = "./stacks"
5 | }
6 |
7 | variable "stacks" {
8 | type = list(string)
9 | description = "A list of stack names"
10 | }
11 |
12 | variable "stack_deps_processing_enabled" {
13 | type = bool
14 | description = "Boolean flag to enable/disable processing all stack dependencies in the provided stack"
15 | default = false
16 | }
17 |
18 | variable "component_deps_processing_enabled" {
19 | type = bool
20 | description = "Boolean flag to enable/disable processing stack config dependencies for the components in the provided stack"
21 | default = false
22 | }
23 |
--------------------------------------------------------------------------------
/examples/stacks/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.8.0"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | data "utils_stack_config_yaml" "config" {
2 | input = [for stack in var.stacks : format("%s/%s.yaml", var.stack_config_local_path, stack)]
3 | process_stack_deps = var.stack_deps_processing_enabled
4 | process_component_deps = var.component_deps_processing_enabled
5 | }
6 |
7 | locals {
8 | decoded = [for i in data.utils_stack_config_yaml.config.output : yamldecode(i)]
9 |
10 | config = [
11 | for stack in local.decoded : {
12 | imports = stack.imports,
13 | components = {
14 | helmfile = stack.components.helmfile,
15 | terraform = stack.components.terraform
16 | }
17 | }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/modules/backend/README.md:
--------------------------------------------------------------------------------
1 | # backend
2 |
3 | Terraform module that accepts stack configuration and returns backend config for a component.
4 |
5 | ## Usage
6 |
7 | The following example loads the stack config `my-stack` (which in turn imports other YAML config dependencies)
8 | and returns the backend config for the component `my-vpc`.
9 |
10 | ```hcl
11 | module "backend" {
12 | source = "cloudposse/stack-config/yaml//modules/backend"
13 | # version = "x.x.x"
14 |
15 | stack = "my-stack"
16 | component = "my-vpc"
17 |
18 | context = module.this.context
19 | }
20 | ```
21 |
22 | The example returns the following `backend` configuration:
23 |
24 | ```hcl
25 | backend_type = s3
26 |
27 | backend = {
28 | "acl" = "bucket-owner-full-control"
29 | "bucket" = "eg-ue2-root-tfstate"
30 | "dynamodb_table" = "eg-ue2-root-tfstate-lock"
31 | "encrypt" = true
32 | "key" = "terraform.tfstate"
33 | "region" = "us-east-2"
34 | "role_arn" = "arn:aws:iam::xxxxxxxxxxxx:role/eg-gbl-root-terraform"
35 | "workspace_key_prefix" = "vpc"
36 | }
37 | ```
38 |
39 | See [examples/complete](../../examples/complete) for more details.
40 |
--------------------------------------------------------------------------------
/modules/backend/main.tf:
--------------------------------------------------------------------------------
1 | data "utils_component_config" "config" {
2 | component = var.component
3 | stack = var.stack
4 | namespace = module.always.namespace
5 | tenant = module.always.tenant
6 | environment = module.always.environment
7 | stage = module.always.stage
8 | ignore_errors = var.ignore_errors
9 | env = var.env
10 | atmos_cli_config_path = var.atmos_cli_config_path
11 | atmos_base_path = var.atmos_base_path
12 | }
13 |
14 | locals {
15 | config = yamldecode(data.utils_component_config.config.output)
16 | backend_type = local.config.backend_type
17 | backend = local.config.backend
18 | }
19 |
--------------------------------------------------------------------------------
/modules/backend/outputs.tf:
--------------------------------------------------------------------------------
1 | output "backend_type" {
2 | value = local.backend_type
3 | description = "Backend type for the component"
4 | }
5 |
6 | output "backend" {
7 | value = local.backend
8 | description = "Backend configuration for the component"
9 | }
10 |
--------------------------------------------------------------------------------
/modules/backend/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack" {
2 | type = string
3 | description = "Stack name"
4 | default = null
5 | }
6 |
7 | variable "component" {
8 | type = string
9 | description = "Component"
10 | }
11 |
12 | variable "ignore_errors" {
13 | type = bool
14 | description = "Set to true to ignore errors from the 'utils' provider (if the component is not found in the stack)"
15 | default = false
16 | }
17 |
18 | variable "env" {
19 | type = map(string)
20 | description = "Map of ENV vars in the format `key=value`. These ENV vars will be set in the `utils` provider before executing the data source"
21 | default = null
22 | }
23 |
24 | variable "atmos_cli_config_path" {
25 | type = string
26 | description = "atmos CLI config path"
27 | default = null
28 | }
29 |
30 | variable "atmos_base_path" {
31 | type = string
32 | description = "atmos base path to components and stacks"
33 | default = null
34 | }
35 |
--------------------------------------------------------------------------------
/modules/backend/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.7.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/modules/env/README.md:
--------------------------------------------------------------------------------
1 | # env
2 |
3 | Terraform module that accepts stack configuration and returns deep-merged ENV variables for a Terraform or helmfile component.
4 |
5 | ## Usage
6 |
7 | The following example loads the stack config `my-stack` (which in turn imports other YAML config dependencies)
8 | and returns ENV variables for Terraform component `my-vpc`.
9 |
10 | ```hcl
11 | module "vars" {
12 | source = "cloudposse/stack-config/yaml//modules/env"
13 | # version = "x.x.x"
14 |
15 | stack_config_local_path = "./stacks"
16 | stack = "my-stack"
17 | component_type = "terraform"
18 | component = "my-vpc"
19 |
20 | context = module.this.context
21 | }
22 | ```
23 |
24 | See [examples/complete](../../examples/complete) for more details.
25 |
--------------------------------------------------------------------------------
/modules/env/main.tf:
--------------------------------------------------------------------------------
1 | module "stack" {
2 | source = "../stack"
3 |
4 | stack = var.stack
5 | context = module.always.context
6 | }
7 |
8 | data "utils_stack_config_yaml" "config" {
9 | base_path = var.stack_config_local_path
10 | input = [format("%s/%s.yaml", var.stack_config_local_path, module.stack.stack_name)]
11 | }
12 |
13 | locals {
14 | config = yamldecode(data.utils_stack_config_yaml.config.output[0])
15 | env = local.config["components"][var.component_type][var.component]["env"]
16 | base_component = try(local.config["components"][var.component_type][var.component]["component"], "")
17 | }
18 |
--------------------------------------------------------------------------------
/modules/env/outputs.tf:
--------------------------------------------------------------------------------
1 | output "env" {
2 | value = local.env
3 | description = "ENV variables for the component"
4 | }
5 |
6 | output "base_component" {
7 | value = local.base_component
8 | description = "Base component name"
9 | }
10 |
--------------------------------------------------------------------------------
/modules/env/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_config_local_path" {
2 | type = string
3 | description = "Path to local stack configs"
4 | }
5 |
6 | variable "stack" {
7 | type = string
8 | description = "Stack name"
9 | default = null
10 | }
11 |
12 | variable "component_type" {
13 | type = string
14 | description = "Component type (terraform or helmfile)"
15 | default = "terraform"
16 | }
17 |
18 | variable "component" {
19 | type = string
20 | description = "Component"
21 | }
22 |
--------------------------------------------------------------------------------
/modules/env/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.7.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/modules/remote-state/README.md:
--------------------------------------------------------------------------------
1 | # remote-state
2 |
3 | Terraform module that accepts a component and a stack name and returns remote state outputs for the component.
4 |
5 | The module supports all backends supported by Terraform and OpenTofu, plus the Atmos-specific `static` backend.
6 |
7 |
8 | ### Errors
9 |
10 | > [!NOTE]
11 | >
12 | > If you experience an error from the `terraform_remote_state` data source,
13 | > this is most likely not an error in this module, but rather an error in the
14 | > `remote_state` configuration in the referenced stack. This module performs
15 | > no validation on the remote state configuration, and only modifies the configuration
16 | > for the `remote` backend (to set the workspace name) and,
17 | > _only when `var.privileged` is set to `true`_, the `s3` configuration (to remove
18 | > settings for assuming a role). If `var.privileged` is left at the default value of `false`
19 | > and you are not using the `remote` backend, then this module will not modify the backend
20 | > configuration in any way.
21 |
22 | ### "Local" Backend
23 |
24 | > [!IMPORTANT]
25 | >
26 | > If the local backend has a relative path, it will be resolved
27 | > relative to the current working directory, which is usually a root module
28 | > referencing the remote state. However, when the local backend is created,
29 | > the current working directory is the directory where the target root module
30 | > is defined. This can cause the lookup to fail if the source is not reachable
31 | > from the client directory as `../source`.
32 |
33 | For example, if your directory structure looks like this:
34 |
35 | ```text
36 | project
37 | ├── components
38 | │ ├── client
39 | │ │ └── main.tf
40 | │ └── complex
41 | │ └── source
42 | │ └── main.tf
43 | └── local-state
44 | └── complex
45 | └── source
46 | └── terraform.tfstate
47 | ```
48 |
49 | Terraform code in `project/components/complex/source` can create its local state
50 | file (`terraform.tfstate`) in the `local-state/complex/source`
51 | directory using `path = "../../../local-state/complex/source/terraform.tfstate"`.
52 | However, Terraform code in `project/components/client` that references the same
53 | local state using the same backend configuration will fail because the current
54 | working directory is `project/components/client` and the relative path will not
55 | resolve correctly.
56 |
57 |
58 | ## Usage
59 |
60 | The following example accepts a stack config `my-stack` (which in turn imports other YAML config dependencies)
61 | and returns remote state outputs from the `s3` backend for `my-vpc` and `eks` Terraform components.
62 |
63 | __NOTE:__ The backend type (`s3`) and backend configuration for the components are defined in the stack YAML config files.
64 |
65 | ```hcl
66 | module "remote_state_my_vpc" {
67 | source = "cloudposse/stack-config/yaml//modules/remote-state"
68 | # Cloud Posse recommends pinning every module to a specific version
69 | # version = "x.x.x"
70 |
71 | stack = "my-stack"
72 | component = "my-vpc"
73 | }
74 |
75 | module "remote_state_eks" {
76 | source = "cloudposse/stack-config/yaml//modules/remote-state"
77 | # Cloud Posse recommends pinning every module to a specific version
78 | # version = "x.x.x"
79 |
80 | stack = "my-stack"
81 | component = "eks"
82 | }
83 | ```
84 |
85 | See [examples/remote-state](../../examples/remote-state) for more details.
86 |
--------------------------------------------------------------------------------
/modules/remote-state/data-source.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | custom_backends = ["none", "bypass", "static"]
3 | is_data_source_backend = !contains(local.custom_backends, local.backend_type)
4 |
5 | remote_workspace = var.workspace != null ? var.workspace : local.workspace
6 | ds_backend = local.is_data_source_backend ? local.backend_type : "none"
7 | ds_workspace = local.ds_backend == "none" ? null : local.remote_workspace
8 |
9 | # The `privileged` flag is no longer used in the Cloud Posse reference architecture, but is maintained for compatibility.
10 | # This was and is only supported for the S3 backend.
11 | #
12 | # When the `privileged` flag is set to `true`, the user running Terraform is considered privileged and therefore
13 | # does not need to assume a different role to access the S3 backend.
14 | #
15 | # This is accomplished by removing any profile or role ARN settings from the configuration.
16 | s3_privileged_backend = { for k, v in local.backend : k => v if !contains(["profile", "role_arn", "assume_role", "assume_role_with_web_identity"], k) }
17 |
18 | # Workaround for the fact that the 2 different backends can be different types,
19 | # but both results of a conditional must be the same type.
20 | s3_backend = {
21 | # normal, not privileged
22 | false = local.backend
23 | # privileged
24 | true = local.s3_privileged_backend
25 | }
26 |
27 | # Customize certain configurations. Otherwise we will just use whatever was configured in the stack.
28 | ds_configurations = {
29 | # If no valid configuration is found for the backend datasource, provide a dummy one.
30 | none = {
31 | path = "${path.module}/dummy-remote-state.json"
32 | }
33 |
34 | remote = merge(local.backend, {
35 | workspaces = {
36 | name = local.remote_workspace
37 | }
38 | })
39 |
40 | s3 = local.s3_backend[var.privileged]
41 | } # ds_configurations
42 |
43 | }
44 |
45 | data "terraform_remote_state" "data_source" {
46 | count = var.bypass ? 0 : 1
47 |
48 | # Use a dummy local backend when the real backend is not supported by the data source
49 | backend = local.ds_backend == "none" ? "local" : local.ds_backend
50 | workspace = local.ds_workspace
51 | # If nothing needs to be customized, just use whatever was configured in the stack
52 | config = lookup(local.ds_configurations, local.ds_backend, local.backend)
53 | defaults = var.defaults
54 | }
55 |
--------------------------------------------------------------------------------
/modules/remote-state/dummy-remote-state.json:
--------------------------------------------------------------------------------
1 | {"version": 1}
2 |
--------------------------------------------------------------------------------
/modules/remote-state/main.tf:
--------------------------------------------------------------------------------
1 | data "utils_component_config" "config" {
2 | count = var.bypass ? 0 : 1
3 |
4 | component = var.component
5 | stack = var.stack
6 | namespace = module.always.namespace
7 | tenant = module.always.tenant
8 | environment = module.always.environment
9 | stage = module.always.stage
10 | ignore_errors = var.ignore_errors
11 | env = var.env
12 | atmos_cli_config_path = var.atmos_cli_config_path
13 | atmos_base_path = var.atmos_base_path
14 | }
15 |
16 | locals {
17 | config = try(yamldecode(data.utils_component_config.config[0].output), {})
18 |
19 | remote_state_backend_type = try(local.config.remote_state_backend_type, "")
20 | backend_type = try(coalesce(local.remote_state_backend_type, local.config.backend_type), "none")
21 |
22 | # If `config.remote_state_backend` is not declared in YAML config, the default value will be an empty map `{}`
23 | backend_config_key = try(local.config.remote_state_backend, null) != null && try(length(local.config.remote_state_backend), 0) > 0 ? "remote_state_backend" : "backend"
24 |
25 | # This is used because the `?` operator in some instances (depending on the condition) changes the types of all items of the map to all `strings`
26 | backend_configs = {
27 | backend = lookup(local.config, "backend", {})
28 | remote_state_backend = lookup(local.config, "remote_state_backend", {})
29 | }
30 |
31 | backend = local.backend_configs[local.backend_config_key]
32 |
33 | workspace = lookup(local.config, "workspace", "")
34 | # workspace_key_prefix = lookup(local.backend, "workspace_key_prefix", null)
35 |
36 | remote_states = {
37 | data_source = try(data.terraform_remote_state.data_source[0].outputs, var.defaults)
38 | bypass = var.defaults
39 | static = local.backend
40 | }
41 |
42 | remote_state_backend_key = var.bypass ? "bypass" : local.is_data_source_backend ? "data_source" : local.backend_type
43 | computed_remote_state_backend_key = try(length(local.remote_states[local.remote_state_backend_key]), 0) > 0 ? local.remote_state_backend_key : "bypass"
44 |
45 | outputs = local.remote_states[local.computed_remote_state_backend_key]
46 | }
47 |
--------------------------------------------------------------------------------
/modules/remote-state/outputs.tf:
--------------------------------------------------------------------------------
1 | output "backend_type" {
2 | value = local.backend_type
3 | description = "Backend type"
4 | }
5 |
6 | output "backend" {
7 | value = local.backend
8 | description = "Backend configuration for the component"
9 | }
10 |
11 | output "s3_workspace_name" {
12 | value = local.ds_backend == "s3" ? local.remote_workspace : null
13 | description = "(DEPRECATED: use `workspace_name` instead): Terraform workspace name for the component s3 backend"
14 | }
15 |
16 | output "remote_workspace_name" {
17 | value = local.ds_backend == "remote" ? local.remote_workspace : null
18 | description = "(DEPRECATED: use `workspace_name` instead): Terraform workspace name for the component remote backend"
19 | }
20 |
21 | output "workspace_name" {
22 | value = local.remote_workspace
23 | description = "Terraform workspace name from which to retrieve the Terraform state"
24 | }
25 |
26 | output "outputs" {
27 | value = local.outputs
28 | description = "Remote state"
29 | }
30 |
--------------------------------------------------------------------------------
/modules/remote-state/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack" {
2 | type = string
3 | description = "Stack name"
4 | default = null
5 | }
6 |
7 | variable "component" {
8 | type = string
9 | description = "Component"
10 | }
11 |
12 | variable "privileged" {
13 | type = bool
14 | description = "True if the caller already has access to the backend without assuming roles"
15 | default = false
16 | }
17 |
18 | variable "defaults" {
19 | type = any
20 | description = "Default values if the data source is empty"
21 | default = null
22 | }
23 |
24 | variable "workspace" {
25 | type = string
26 | description = "Workspace (this overrides the workspace calculated from the context)"
27 | default = null
28 | }
29 |
30 | variable "bypass" {
31 | type = bool
32 | description = "Set to true to skip looking up the remote state and just return the defaults"
33 | default = false
34 | }
35 |
36 | variable "ignore_errors" {
37 | type = bool
38 | description = "Set to true to ignore errors from the 'utils' provider (if the component is not found in the stack)"
39 | default = false
40 | }
41 |
42 | variable "env" {
43 | type = map(string)
44 | description = "Map of ENV vars in the format `key=value`. These ENV vars will be set in the `utils` provider before executing the data source"
45 | default = null
46 | }
47 |
48 | variable "atmos_cli_config_path" {
49 | type = string
50 | description = "atmos CLI config path"
51 | default = null
52 | }
53 |
54 | variable "atmos_base_path" {
55 | type = string
56 | description = "atmos base path to components and stacks"
57 | default = null
58 | }
59 |
--------------------------------------------------------------------------------
/modules/remote-state/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.1.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | # We were previously pinning this to <=1.8.0, but changing this each time we had a new version was a pain. As
16 | # a compromise, we'll pin to a minimum version, but allow any patch version below 2.0.0 and we will make sure
17 | # that if we make any major/breaking changes in cloudposse/utils, we'll increment to 2.0.0.
18 | version = ">= 1.7.1, < 2.0.0"
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/modules/settings/README.md:
--------------------------------------------------------------------------------
1 | # settings
2 |
3 | Terraform module that accepts stack configuration and returns deep-merged settings for a Terraform or helmfile component.
4 |
5 | ## Usage
6 |
7 | The following example loads the stack config `my-stack` (which in turn imports other YAML config dependencies)
8 | and returns settings for Terraform component `my-vpc`.
9 |
10 | ```hcl
11 | module "vars" {
12 | source = "cloudposse/stack-config/yaml//modules/settings"
13 | # version = "x.x.x"
14 |
15 | stack_config_local_path = "./stacks"
16 | stack = "my-stack"
17 | component_type = "terraform"
18 | component = "my-vpc"
19 |
20 | context = module.this.context
21 | }
22 | ```
23 |
24 | See [examples/complete](../../examples/complete) for more details.
25 |
--------------------------------------------------------------------------------
/modules/settings/main.tf:
--------------------------------------------------------------------------------
1 | module "stack" {
2 | source = "../stack"
3 |
4 | stack = var.stack
5 | context = module.always.context
6 | }
7 |
8 | data "utils_stack_config_yaml" "config" {
9 | base_path = var.stack_config_local_path
10 | input = [format("%s/%s.yaml", var.stack_config_local_path, module.stack.stack_name)]
11 | }
12 |
13 | locals {
14 | config = yamldecode(data.utils_stack_config_yaml.config.output[0])
15 | settings = local.config["components"][var.component_type][var.component]["settings"]
16 | base_component = try(local.config["components"][var.component_type][var.component]["component"], "")
17 | }
18 |
--------------------------------------------------------------------------------
/modules/settings/outputs.tf:
--------------------------------------------------------------------------------
1 | output "settings" {
2 | value = local.settings
3 | description = "settings for the component"
4 | }
5 |
6 | output "base_component" {
7 | value = local.base_component
8 | description = "Base component name"
9 | }
10 |
--------------------------------------------------------------------------------
/modules/settings/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_config_local_path" {
2 | type = string
3 | description = "Path to local stack configs"
4 | }
5 |
6 | variable "stack" {
7 | type = string
8 | description = "Stack name"
9 | default = null
10 | }
11 |
12 | variable "component_type" {
13 | type = string
14 | description = "Component type (terraform or helmfile)"
15 | default = "terraform"
16 | }
17 |
18 | variable "component" {
19 | type = string
20 | description = "Component"
21 | }
22 |
--------------------------------------------------------------------------------
/modules/settings/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.7.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/modules/spacelift/README.md:
--------------------------------------------------------------------------------
1 | # spacelift
2 |
3 | Terraform module that accepts infrastructure stack configurations and transforms it into Spacelift stacks.
4 |
5 | ## Usage
6 |
7 | The following example loads the infrastructure YAML stack configs and returns Spacelift stack configurations:
8 |
9 |
10 | ```hcl
11 | module "spacelift" {
12 | source = "../../modules/spacelift"
13 |
14 | stack_config_path_template = "stacks/%s.yaml"
15 | component_deps_processing_enabled = true
16 |
17 | context = module.this.context
18 | }
19 | ```
20 |
21 | See [examples/spacelift](../../examples/spacelift) for more details.
22 |
--------------------------------------------------------------------------------
/modules/spacelift/main.tf:
--------------------------------------------------------------------------------
1 | data "utils_spacelift_stack_config" "spacelift_stacks" {
2 | process_stack_deps = var.stack_deps_processing_enabled
3 | process_component_deps = var.component_deps_processing_enabled
4 | process_imports = var.imports_processing_enabled
5 | stack_config_path_template = var.stack_config_path_template
6 | env = var.env
7 | }
8 |
9 | locals {
10 | spacelift_stacks = yamldecode(data.utils_spacelift_stack_config.spacelift_stacks.output)
11 | }
12 |
--------------------------------------------------------------------------------
/modules/spacelift/outputs.tf:
--------------------------------------------------------------------------------
1 | output "spacelift_stacks" {
2 | value = local.spacelift_stacks
3 | description = "Spacelift stacks"
4 | }
5 |
--------------------------------------------------------------------------------
/modules/spacelift/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_deps_processing_enabled" {
2 | type = bool
3 | description = "Boolean flag to enable/disable processing all stack dependencies in the provided stack"
4 | default = false
5 | }
6 |
7 | variable "component_deps_processing_enabled" {
8 | type = bool
9 | description = "Boolean flag to enable/disable processing stack config dependencies for the components in the provided stack"
10 | default = true
11 | }
12 |
13 | variable "imports_processing_enabled" {
14 | type = bool
15 | description = "Enable/disable processing stack imports"
16 | default = false
17 | }
18 |
19 | variable "stack_config_path_template" {
20 | type = string
21 | description = "Stack config path template"
22 | default = "stacks/%s.yaml"
23 | }
24 |
25 | variable "env" {
26 | type = map(string)
27 | description = "Map of ENV vars in the format `key=value`. These ENV vars will be set in the `utils` provider before executing the data source"
28 | default = null
29 | }
30 |
--------------------------------------------------------------------------------
/modules/spacelift/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.7.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/modules/stack/README.md:
--------------------------------------------------------------------------------
1 | # stack
2 |
3 | Terraform module that constructs stack names.
4 |
5 | If `var.stack` is specified, will be returned as is.
6 |
7 | If not specified, the output will be calculated using the provided `context`.
8 |
--------------------------------------------------------------------------------
/modules/stack/main.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | descriptor_stack = lookup(module.always.descriptors, "stack", null)
3 |
4 | # If `var.stack` is provided, return it.
5 | # Else, if `descriptors["stack"]` is specified, use it.
6 | # Otherwise, construct the stack name from the provided `context`.
7 | stack_name = var.stack != null ? var.stack : (
8 | local.descriptor_stack != null ? local.descriptor_stack : (
9 | module.always.tenant != null && module.always.tenant != "" ? format("%s-%s-%s", module.always.tenant, module.always.environment, module.always.stage) : (
10 | # Default stack name from `environment` and `stage`
11 | format("%s-%s", module.always.environment, module.always.stage)
12 | )
13 | )
14 | )
15 | }
16 |
--------------------------------------------------------------------------------
/modules/stack/outputs.tf:
--------------------------------------------------------------------------------
1 | output "stack_name" {
2 | value = local.stack_name
3 | description = "Stack name"
4 | }
5 |
--------------------------------------------------------------------------------
/modules/stack/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack" {
2 | type = string
3 | description = "Stack name. If specified, will be returned as is. If not specified, will be calculated using the provided `context`"
4 | default = null
5 | }
6 |
--------------------------------------------------------------------------------
/modules/stack/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/modules/vars/README.md:
--------------------------------------------------------------------------------
1 | # vars
2 |
3 | Terraform module that accepts stack configuration and returns deep-merged variables for a Terraform or helmfile component.
4 |
5 | ## Usage
6 |
7 | The following example loads the stack config `my-stack` (which in turn imports other YAML config dependencies)
8 | and returns variables and backend config for Terraform component `my-vpc`.
9 |
10 | ```hcl
11 | module "vars" {
12 | source = "cloudposse/stack-config/yaml//modules/vars"
13 | # version = "x.x.x"
14 |
15 | stack_config_local_path = "./stacks"
16 | stack = "my-stack"
17 | component_type = "terraform"
18 | component = "my-vpc"
19 |
20 | context = module.this.context
21 | }
22 |
23 | module "backend" {
24 | source = "cloudposse/stack-config/yaml//modules/backend"
25 | # version = "x.x.x"
26 |
27 | stack_config_local_path = "./stacks"
28 | stack = "my-stack"
29 | component_type = "terraform"
30 | component = "my-vpc"
31 |
32 | context = module.this.context
33 | }
34 | ```
35 |
36 | The example returns the following `vars` and `backend` configurations for `my-stack` stack and `my-vpc` Terraform component:
37 |
38 | ```hcl
39 | vars = {
40 | "availability_zones" = [
41 | "us-east-2a",
42 | "us-east-2b",
43 | "us-east-2c",
44 | ]
45 | "cidr_block" = "10.132.0.0/18"
46 | "environment" = "ue2"
47 | "level" = 3
48 | "namespace" = "eg"
49 | "param" = "param4"
50 | "region" = "us-east-2"
51 | "stage" = "prod"
52 | "subnet_type_tag_key" = "example/subnet/type"
53 | "test_map" = {
54 | "a" = "a_override_2"
55 | "b" = "b_override"
56 | "c" = [
57 | 1,
58 | 2,
59 | 3,
60 | ]
61 | "map2" = {
62 | "atr1" = 1
63 | "atr2" = 2
64 | "atr3" = [
65 | "3a",
66 | "3b",
67 | "3c",
68 | ]
69 | }
70 | }
71 | "var_1" = "1_override"
72 | "var_2" = "2_override"
73 | "var_3" = "3a"
74 | }
75 |
76 | backend_type = s3
77 |
78 | backend = {
79 | "acl" = "bucket-owner-full-control"
80 | "bucket" = "eg-ue2-root-tfstate"
81 | "dynamodb_table" = "eg-ue2-root-tfstate-lock"
82 | "encrypt" = true
83 | "key" = "terraform.tfstate"
84 | "region" = "us-east-2"
85 | "role_arn" = "arn:aws:iam::xxxxxxxxxxxx:role/eg-gbl-root-terraform"
86 | "workspace_key_prefix" = "vpc"
87 | }
88 | ```
89 |
90 | See [examples/complete](../../examples/complete) for more details.
91 |
--------------------------------------------------------------------------------
/modules/vars/main.tf:
--------------------------------------------------------------------------------
1 | module "stack" {
2 | source = "../stack"
3 |
4 | stack = var.stack
5 | context = module.always.context
6 | }
7 |
8 | data "utils_stack_config_yaml" "config" {
9 | base_path = var.stack_config_local_path
10 | input = [format("%s/%s.yaml", var.stack_config_local_path, module.stack.stack_name)]
11 | }
12 |
13 | locals {
14 | config = yamldecode(data.utils_stack_config_yaml.config.output[0])
15 | vars = local.config["components"][var.component_type][var.component]["vars"]
16 | base_component = try(local.config["components"][var.component_type][var.component]["component"], "")
17 | }
18 |
--------------------------------------------------------------------------------
/modules/vars/outputs.tf:
--------------------------------------------------------------------------------
1 | output "vars" {
2 | value = local.vars
3 | description = "Vars configuration for the component"
4 | }
5 |
6 | output "base_component" {
7 | value = local.base_component
8 | description = "Base component name"
9 | }
10 |
--------------------------------------------------------------------------------
/modules/vars/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_config_local_path" {
2 | type = string
3 | description = "Path to local stack configs"
4 | }
5 |
6 | variable "stack" {
7 | type = string
8 | description = "Stack name"
9 | default = null
10 | }
11 |
12 | variable "component_type" {
13 | type = string
14 | description = "Component type (terraform or helmfile)"
15 | default = "terraform"
16 | }
17 |
18 | variable "component" {
19 | type = string
20 | description = "Component"
21 | }
22 |
--------------------------------------------------------------------------------
/modules/vars/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.7.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | output "config" {
2 | value = local.config
3 | description = "Stack configurations"
4 | }
5 |
--------------------------------------------------------------------------------
/test/.gitignore:
--------------------------------------------------------------------------------
1 | .test-harness
2 | .envrc
3 |
--------------------------------------------------------------------------------
/test/Makefile:
--------------------------------------------------------------------------------
1 | TEST_HARNESS ?= https://github.com/cloudposse/test-harness.git
2 | TEST_HARNESS_BRANCH ?= master
3 | TEST_HARNESS_PATH = $(realpath .test-harness)
4 | BATS_ARGS ?= --tap
5 | BATS_LOG ?= test.log
6 |
7 | # Define a macro to run the tests
8 | define RUN_TESTS
9 | @echo "Running tests in $(1)"
10 | @cd $(1) && bats $(BATS_ARGS) $(addsuffix .bats,$(addprefix $(TEST_HARNESS_PATH)/test/terraform/,$(TESTS)))
11 | endef
12 |
13 | default: all
14 |
15 | -include Makefile.*
16 |
17 | ## Provision the test-harnesss
18 | .test-harness:
19 | [ -d $@ ] || git clone --depth=1 -b $(TEST_HARNESS_BRANCH) $(TEST_HARNESS) $@
20 |
21 | ## Initialize the tests
22 | init: .test-harness
23 |
24 | ## Install all dependencies (OS specific)
25 | deps::
26 | @exit 0
27 |
28 | ## Clean up the test harness
29 | clean:
30 | [ "$(TEST_HARNESS_PATH)" == "/" ] || rm -rf $(TEST_HARNESS_PATH)
31 |
32 | ## Run all tests
33 | all: module examples/complete
34 |
35 | ## Run basic sanity checks against the module itself
36 | module: export TESTS ?= installed lint module-pinning provider-pinning validate terraform-docs input-descriptions output-descriptions
37 | module: deps
38 | $(call RUN_TESTS, ../)
39 |
40 | ## Run tests against example
41 | examples/complete: export TESTS ?= installed lint validate
42 | examples/complete: deps
43 | $(call RUN_TESTS, ../$@)
44 |
--------------------------------------------------------------------------------
/test/Makefile.alpine:
--------------------------------------------------------------------------------
1 | ifneq (,$(wildcard /sbin/apk))
2 | ## Install all dependencies for alpine
3 | deps:: init
4 | @apk add --update terraform-docs@cloudposse json2hcl@cloudposse
5 | endif
6 |
--------------------------------------------------------------------------------
/test/src/.gitignore:
--------------------------------------------------------------------------------
1 | .gopath
2 | vendor/
3 |
--------------------------------------------------------------------------------
/test/src/Makefile:
--------------------------------------------------------------------------------
1 | export TERRAFORM_VERSION ?= $(shell curl -s https://checkpoint-api.hashicorp.com/v1/check/terraform | jq -r -M '.current_version' | cut -d. -f1)
2 |
3 | .DEFAULT_GOAL : all
4 |
5 | .PHONY: all
6 | ## Default target
7 | all: test
8 |
9 | .PHONY : init
10 | ## Initialize tests
11 | init:
12 | @exit 0
13 |
14 | .PHONY : test
15 | ## Run tests
16 | test: init
17 | go mod download
18 | go test -v -timeout 3m -run TestExamplesComplete
19 | go test -v -timeout 3m -run TestExamplesStacks
20 | go test -v -timeout 3m -run TestExamplesSpacelift # NOTE: Test is skipped because the test itself is broken
21 | go test -v -timeout 3m -run TestExamplesStack
22 | go test -v -timeout 3m -run TestExamplesRemoteState
23 | go test -v -timeout 3m -run TestExamplesBackend
24 |
25 | ## Run tests in docker container
26 | docker/test:
27 | docker run --name terratest --rm -it -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -e GITHUB_TOKEN \
28 | -e PATH="/usr/local/terraform/$(TERRAFORM_VERSION)/bin:/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
29 | -v $(CURDIR)/../../:/module/ cloudposse/test-harness:latest -C /module/test/src test
30 |
31 | .PHONY : clean
32 | ## Clean up files
33 | clean:
34 | rm -rf ../../examples/complete/*.tfstate*
35 | rm -rf ../../examples/stacks/*.tfstate*
36 | rm -rf ../../examples/spacelift/*.tfstate*
37 | rm -rf ../../examples/stack/*.tfstate*
38 | rm -rf ../../examples/remote-state/*.tfstate*
39 | rm -rf ../../examples/backend/*.tfstate*
40 |
--------------------------------------------------------------------------------
/test/src/examples_backend_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/gruntwork-io/terratest/modules/terraform"
5 | "github.com/stretchr/testify/assert"
6 | "testing"
7 | )
8 |
9 | // Test the Terraform module in examples/backend using Terratest.
10 | func TestExamplesBackend(t *testing.T) {
11 |
12 | terraformOptions := &terraform.Options{
13 | // The path to where our Terraform code is located
14 | TerraformDir: "../../examples/backend",
15 | Upgrade: true,
16 | // Variables to pass to our Terraform code using -var-file options
17 | VarFiles: []string{"fixtures.tfvars"},
18 | }
19 |
20 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
24 | terraform.InitAndApply(t, terraformOptions)
25 |
26 | // Run `terraform output` to get the value of an output variable
27 | backendType := terraform.Output(t, terraformOptions, "backend_type")
28 | // Verify we're getting back the outputs we expect
29 | assert.Equal(t, "s3", backendType)
30 |
31 | // Run `terraform output` to get the value of an output variable
32 | backend := terraform.OutputMap(t, terraformOptions, "backend")
33 | // Verify we're getting back the outputs we expect
34 | assert.Greater(t, len(backend), 0)
35 | }
36 |
--------------------------------------------------------------------------------
/test/src/examples_complete_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/gruntwork-io/terratest/modules/terraform"
5 | "github.com/stretchr/testify/assert"
6 | "testing"
7 | )
8 |
9 | // Test the Terraform module in examples/complete using Terratest.
10 | func TestExamplesComplete(t *testing.T) {
11 |
12 | terraformOptions := &terraform.Options{
13 | // The path to where our Terraform code is located
14 | TerraformDir: "../../examples/complete",
15 | Upgrade: true,
16 | // Variables to pass to our Terraform code using -var-file options
17 | VarFiles: []string{"fixtures.tfvars"},
18 | }
19 |
20 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
24 | terraform.InitAndApply(t, terraformOptions)
25 |
26 | // Run `terraform output` to get the value of an output variable
27 | vars := terraform.OutputMap(t, terraformOptions, "vars")
28 | // Verify we're getting back the outputs we expect
29 | assert.Greater(t, len(vars), 0)
30 |
31 | // Run `terraform output` to get the value of an output variable
32 | settings := terraform.OutputMap(t, terraformOptions, "settings")
33 | // Verify we're getting back the outputs we expect
34 | assert.Greater(t, len(settings), 0)
35 |
36 | // Run `terraform output` to get the value of an output variable
37 | env := terraform.OutputMap(t, terraformOptions, "env")
38 | // Verify we're getting back the outputs we expect
39 | assert.Greater(t, len(env), 0)
40 |
41 | // Run `terraform output` to get the value of an output variable
42 | stackName := terraform.Output(t, terraformOptions, "stack_name")
43 | // Verify we're getting back the outputs we expect
44 | assert.Equal(t, "my-stack", stackName)
45 | }
46 |
--------------------------------------------------------------------------------
/test/src/examples_remote_state_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/gruntwork-io/terratest/modules/terraform"
5 | "github.com/stretchr/testify/assert"
6 | "testing"
7 | )
8 |
9 | // Test the Terraform module in examples/remote-state using Terratest.
10 | func TestExamplesRemoteState(t *testing.T) {
11 |
12 | terraformOptions := &terraform.Options{
13 | // The path to where our Terraform code is located
14 | TerraformDir: "../../examples/remote-state",
15 | Upgrade: true,
16 | // Variables to pass to our Terraform code using -var-file options
17 | VarFiles: []string{"fixtures.tfvars"},
18 | }
19 |
20 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
24 | terraform.InitAndApply(t, terraformOptions)
25 |
26 | // Run `terraform output` to get the value of an output variable
27 | var output any
28 |
29 | terraform.OutputStruct(t, terraformOptions, "remote_state_using_stack", &output)
30 | remoteStateUsingStack := output.(map[string]any)
31 | // Verify we're getting back the outputs we expect
32 | assert.NotNilf(t, remoteStateUsingStack, "remote state is empty")
33 | assert.Equal(t, true, remoteStateUsingStack["val1"])
34 | assert.Equal(t, "2", remoteStateUsingStack["val2"])
35 | assert.Equal(t, float64(3), remoteStateUsingStack["val3"])
36 | assert.Equal(t, nil, remoteStateUsingStack["val4"])
37 |
38 | terraform.OutputStruct(t, terraformOptions, "remote_state_using_context", &output)
39 | remoteStateUsingContext := output.(map[string]any)
40 | // Verify we're getting back the outputs we expect
41 | assert.NotNilf(t, remoteStateUsingContext, "remote state is empty")
42 | assert.Equal(t, true, remoteStateUsingContext["val1"])
43 | assert.Equal(t, "2", remoteStateUsingContext["val2"])
44 | assert.Equal(t, float64(3), remoteStateUsingContext["val3"])
45 | assert.Equal(t, nil, remoteStateUsingContext["val4"])
46 |
47 | terraform.OutputStruct(t, terraformOptions, "remote_state_using_context_ignore_errors", &output)
48 | remoteStateUsingContextIgnoreErrors := output.(map[string]any)
49 | // Verify we're getting back the outputs we expect
50 | assert.NotNilf(t, remoteStateUsingContextIgnoreErrors, "remote state is empty")
51 | assert.Equal(t, "default-value", remoteStateUsingContextIgnoreErrors["default_output"])
52 |
53 | terraform.OutputStruct(t, terraformOptions, "remote_state_with_bypass", &output)
54 | remoteStateWithBypass := output.(map[string]any)
55 | // Verify we're getting back the outputs we expect
56 | assert.NotNilf(t, remoteStateWithBypass, "remote state is empty")
57 | assert.Equal(t, "default-value", remoteStateWithBypass["default_output"])
58 | }
59 |
--------------------------------------------------------------------------------
/test/src/examples_spacelift_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/gruntwork-io/terratest/modules/terraform"
5 | "github.com/stretchr/testify/assert"
6 | "testing"
7 | )
8 |
9 | // Test the Terraform module in examples/spacelift using Terratest.
10 | func TestExamplesSpacelift(t *testing.T) {
11 |
12 | t.Skip("Skipping test because the test itself is broken with the addition of *-override-2* stacks")
13 |
14 | terraformOptions := &terraform.Options{
15 | // The path to where our Terraform code is located
16 | TerraformDir: "../../examples/spacelift",
17 | Upgrade: true,
18 | // Variables to pass to our Terraform code using -var-file options
19 | VarFiles: []string{"fixtures.tfvars"},
20 | }
21 |
22 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
23 | defer terraform.Destroy(t, terraformOptions)
24 |
25 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
26 | terraform.InitAndApply(t, terraformOptions)
27 |
28 | // Run `terraform output` to get the value of an output variable
29 | var output any
30 | terraform.OutputStruct(t, terraformOptions, "spacelift_stacks", &output)
31 | spaceliftStacks := output.(map[string]any)
32 |
33 | // Verify we're getting back the outputs we expect
34 | assert.Equal(t, 30, len(spaceliftStacks))
35 |
36 | tenant1Ue2DevInfraVpcStack := spaceliftStacks["tenant1-ue2-dev-infra-vpc"].(map[string]any)
37 | tenant1Ue2DevInfraVpcStackInfrastructureStackName := tenant1Ue2DevInfraVpcStack["stack"].(string)
38 | tenant1Ue2DevInfraVpcStackBackend := tenant1Ue2DevInfraVpcStack["backend"].(map[string]any)
39 | tenant1Ue2DevInfraVpcStackBackendWorkspaceKeyPrefix := tenant1Ue2DevInfraVpcStackBackend["workspace_key_prefix"].(string)
40 | assert.Equal(t, "tenant1-ue2-dev", tenant1Ue2DevInfraVpcStackInfrastructureStackName)
41 | assert.Equal(t, "infra-vpc", tenant1Ue2DevInfraVpcStackBackendWorkspaceKeyPrefix)
42 |
43 | tenant1Ue2DevTestTestComponentOverrideComponent := spaceliftStacks["tenant1-ue2-dev-test-test-component-override"].(map[string]any)
44 | tenant1Ue2DevTestTestComponentOverrideComponentInfrastructureStackName := tenant1Ue2DevTestTestComponentOverrideComponent["stack"].(string)
45 | tenant1Ue2DevTestTestComponentOverrideComponentBackend := tenant1Ue2DevTestTestComponentOverrideComponent["backend"].(map[string]any)
46 | tenant1Ue2DevTestTestComponentOverrideComponentBaseComponent := tenant1Ue2DevTestTestComponentOverrideComponent["base_component"].(string)
47 | tenant1Ue2DevTestTestComponentOverrideComponentBackendWorkspaceKeyPrefix := tenant1Ue2DevTestTestComponentOverrideComponentBackend["workspace_key_prefix"].(string)
48 | tenant1Ue2DevTestTestComponentOverrideComponentDeps := tenant1Ue2DevTestTestComponentOverrideComponent["deps"].([]any)
49 | tenant1Ue2DevTestTestComponentOverrideComponentLabels := tenant1Ue2DevTestTestComponentOverrideComponent["labels"].([]any)
50 | tenant1Ue2DevTestTestComponentOverrideTerraformWorkspace := tenant1Ue2DevTestTestComponentOverrideComponent["workspace"]
51 | assert.Equal(t, "tenant1-ue2-dev", tenant1Ue2DevTestTestComponentOverrideComponentInfrastructureStackName)
52 | assert.Equal(t, "test-test-component", tenant1Ue2DevTestTestComponentOverrideComponentBackendWorkspaceKeyPrefix)
53 | assert.Equal(t, "test/test-component", tenant1Ue2DevTestTestComponentOverrideComponentBaseComponent)
54 | assert.Equal(t, 10, len(tenant1Ue2DevTestTestComponentOverrideComponentDeps))
55 | assert.Equal(t, "catalog/terraform/services/service-1", tenant1Ue2DevTestTestComponentOverrideComponentDeps[0])
56 | assert.Equal(t, "catalog/terraform/services/service-1-override", tenant1Ue2DevTestTestComponentOverrideComponentDeps[1])
57 | assert.Equal(t, "catalog/terraform/services/service-2", tenant1Ue2DevTestTestComponentOverrideComponentDeps[2])
58 | assert.Equal(t, "catalog/terraform/services/service-2-override", tenant1Ue2DevTestTestComponentOverrideComponentDeps[3])
59 | assert.Equal(t, "catalog/terraform/tenant1-ue2-dev", tenant1Ue2DevTestTestComponentOverrideComponentDeps[4])
60 | assert.Equal(t, "catalog/terraform/test-component-override", tenant1Ue2DevTestTestComponentOverrideComponentDeps[5])
61 | assert.Equal(t, "globals/globals", tenant1Ue2DevTestTestComponentOverrideComponentDeps[6])
62 | assert.Equal(t, "globals/tenant1-globals", tenant1Ue2DevTestTestComponentOverrideComponentDeps[7])
63 | assert.Equal(t, "globals/ue2-globals", tenant1Ue2DevTestTestComponentOverrideComponentDeps[8])
64 | assert.Equal(t, 35, len(tenant1Ue2DevTestTestComponentOverrideComponentLabels))
65 | assert.Equal(t, "deps:stacks/catalog/terraform/services/service-2.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[25])
66 | assert.Equal(t, "deps:stacks/catalog/terraform/services/service-2-override.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[26])
67 | assert.Equal(t, "deps:stacks/catalog/terraform/tenant1-ue2-dev.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[27])
68 | assert.Equal(t, "deps:stacks/catalog/terraform/test-component-override.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[28])
69 | assert.Equal(t, "deps:stacks/globals/globals.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[29])
70 | assert.Equal(t, "deps:stacks/globals/tenant1-globals.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[30])
71 | assert.Equal(t, "deps:stacks/globals/ue2-globals.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[31])
72 | assert.Equal(t, "deps:stacks/tenant1/ue2/dev.yaml", tenant1Ue2DevTestTestComponentOverrideComponentLabels[32])
73 | assert.Equal(t, "folder:component/test/test-component-override", tenant1Ue2DevTestTestComponentOverrideComponentLabels[33])
74 | assert.Equal(t, "test-component-override-workspace-override", tenant1Ue2DevTestTestComponentOverrideTerraformWorkspace)
75 | }
76 |
--------------------------------------------------------------------------------
/test/src/examples_stack_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/gruntwork-io/terratest/modules/terraform"
5 | "github.com/stretchr/testify/assert"
6 | "testing"
7 | )
8 |
9 | // Test the Terraform module in examples/stack using Terratest.
10 | func TestExamplesStack(t *testing.T) {
11 |
12 | terraformOptions := &terraform.Options{
13 | // The path to where our Terraform code is located
14 | TerraformDir: "../../examples/stack",
15 | Upgrade: true,
16 | // Variables to pass to our Terraform code using -var-file options
17 | VarFiles: []string{"fixtures.tfvars"},
18 | }
19 |
20 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
24 | terraform.InitAndApply(t, terraformOptions)
25 |
26 | // Run `terraform output` to get the value of an output variable
27 | stack1Name := terraform.Output(t, terraformOptions, "stack_1_name")
28 | // Verify we're getting back the outputs we expect
29 | assert.Equal(t, "my-stack", stack1Name)
30 |
31 | // Run `terraform output` to get the value of an output variable
32 | stack2Name := terraform.Output(t, terraformOptions, "stack_2_name")
33 | // Verify we're getting back the outputs we expect
34 | assert.Equal(t, "my-stack", stack2Name)
35 |
36 | // Run `terraform output` to get the value of an output variable
37 | stack3Name := terraform.Output(t, terraformOptions, "stack_3_name")
38 | // Verify we're getting back the outputs we expect
39 | assert.Equal(t, "uw2-dev", stack3Name)
40 |
41 | // Run `terraform output` to get the value of an output variable
42 | stack4Name := terraform.Output(t, terraformOptions, "stack_4_name")
43 | // Verify we're getting back the outputs we expect
44 | assert.Equal(t, "acme-uw2-dev", stack4Name)
45 |
46 | // Run `terraform output` to get the value of an output variable
47 | stack5Name := terraform.Output(t, terraformOptions, "stack_5_name")
48 | // Verify we're getting back the outputs we expect
49 | assert.Equal(t, "acme-uw2-dev", stack5Name)
50 |
51 | // Run `terraform output` to get the value of an output variable
52 | stack6Name := terraform.Output(t, terraformOptions, "stack_6_name")
53 | // Verify we're getting back the outputs we expect
54 | assert.Equal(t, "dev-uw2-acme", stack6Name)
55 |
56 | // Run `terraform output` to get the value of an output variable
57 | stack7Name := terraform.Output(t, terraformOptions, "stack_7_name")
58 | // Verify we're getting back the outputs we expect
59 | assert.Equal(t, "uw2-acme-dev", stack7Name)
60 |
61 | // Run `terraform output` to get the value of an output variable
62 | stack8Name := terraform.Output(t, terraformOptions, "stack_8_name")
63 | // Verify we're getting back the outputs we expect
64 | assert.Equal(t, "dev-acme-uw2", stack8Name)
65 |
66 | // Run `terraform output` to get the value of an output variable
67 | stack9Name := terraform.Output(t, terraformOptions, "stack_9_name")
68 | // Verify we're getting back the outputs we expect
69 | assert.Equal(t, "my-stack", stack9Name)
70 | }
71 |
--------------------------------------------------------------------------------
/test/src/examples_stacks_test.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/gruntwork-io/terratest/modules/terraform"
5 | "github.com/stretchr/testify/assert"
6 | "testing"
7 | )
8 |
9 | // Test the Terraform module in examples/stacks using Terratest.
10 | func TestExamplesStacks(t *testing.T) {
11 |
12 | terraformOptions := &terraform.Options{
13 | // The path to where our Terraform code is located
14 | TerraformDir: "../../examples/stacks",
15 | Upgrade: true,
16 | // Variables to pass to our Terraform code using -var-file options
17 | VarFiles: []string{"fixtures.tfvars"},
18 | }
19 |
20 | // At the end of the test, run `terraform destroy` to clean up any resources that were created
21 | defer terraform.Destroy(t, terraformOptions)
22 |
23 | // This will run `terraform init` and `terraform apply` and fail the test if there are any errors
24 | terraform.InitAndApply(t, terraformOptions)
25 |
26 | // Run `terraform output` to get the value of an output variable
27 | var output any
28 | terraform.OutputStruct(t, terraformOptions, "config", &output)
29 | config := output.([]any)
30 |
31 | // Verify we're getting back the outputs we expect
32 | assert.Equal(t, 4, len(config))
33 | }
34 |
--------------------------------------------------------------------------------
/test/src/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/cloudposse/terraform-yaml-stack-config
2 |
3 | go 1.24
4 |
5 | toolchain go1.24.0
6 |
7 | require (
8 | github.com/gruntwork-io/terratest v0.43.0
9 | github.com/stretchr/testify v1.8.4
10 | )
11 |
12 | require (
13 | cloud.google.com/go v0.110.0 // indirect
14 | cloud.google.com/go/compute v1.19.1 // indirect
15 | cloud.google.com/go/compute/metadata v0.2.3 // indirect
16 | cloud.google.com/go/iam v0.13.0 // indirect
17 | cloud.google.com/go/storage v1.28.1 // indirect
18 | github.com/agext/levenshtein v1.2.3 // indirect
19 | github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
20 | github.com/aws/aws-sdk-go v1.44.122 // indirect
21 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
22 | github.com/davecgh/go-spew v1.1.1 // indirect
23 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
24 | github.com/golang/protobuf v1.5.3 // indirect
25 | github.com/google/go-cmp v0.5.9 // indirect
26 | github.com/google/uuid v1.3.0 // indirect
27 | github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
28 | github.com/googleapis/gax-go/v2 v2.7.1 // indirect
29 | github.com/hashicorp/errwrap v1.0.0 // indirect
30 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
31 | github.com/hashicorp/go-getter v1.7.5 // indirect
32 | github.com/hashicorp/go-multierror v1.1.0 // indirect
33 | github.com/hashicorp/go-safetemp v1.0.0 // indirect
34 | github.com/hashicorp/go-version v1.6.0 // indirect
35 | github.com/hashicorp/hcl/v2 v2.9.1 // indirect
36 | github.com/hashicorp/terraform-json v0.13.0 // indirect
37 | github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
38 | github.com/jmespath/go-jmespath v0.4.0 // indirect
39 | github.com/klauspost/compress v1.15.11 // indirect
40 | github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 // indirect
41 | github.com/mitchellh/go-homedir v1.1.0 // indirect
42 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect
43 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect
44 | github.com/pmezard/go-difflib v1.0.0 // indirect
45 | github.com/tmccombs/hcl2json v0.3.3 // indirect
46 | github.com/ulikunitz/xz v0.5.10 // indirect
47 | github.com/zclconf/go-cty v1.9.1 // indirect
48 | go.opencensus.io v0.24.0 // indirect
49 | golang.org/x/crypto v0.28.0 // indirect
50 | golang.org/x/net v0.30.0 // indirect
51 | golang.org/x/oauth2 v0.7.0 // indirect
52 | golang.org/x/sys v0.26.0 // indirect
53 | golang.org/x/text v0.19.0 // indirect
54 | golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
55 | google.golang.org/api v0.114.0 // indirect
56 | google.golang.org/appengine v1.6.7 // indirect
57 | google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
58 | google.golang.org/grpc v1.56.3 // indirect
59 | google.golang.org/protobuf v1.35.1 // indirect
60 | gopkg.in/yaml.v3 v3.0.1 // indirect
61 | )
62 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | variable "stack_config_local_path" {
2 | type = string
3 | description = "Path to local stack configs"
4 | }
5 |
6 | variable "stacks" {
7 | type = list(string)
8 | description = "A list of infrastructure stack names"
9 | }
10 |
11 | variable "stack_deps_processing_enabled" {
12 | type = bool
13 | description = "Boolean flag to enable/disable processing all stack dependencies in the provided stack"
14 | default = false
15 | }
16 |
17 | variable "component_deps_processing_enabled" {
18 | type = bool
19 | description = "Boolean flag to enable/disable processing stack config dependencies for the components in the provided stack"
20 | default = false
21 | }
22 |
--------------------------------------------------------------------------------
/versions.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 0.14.0"
3 |
4 | required_providers {
5 | local = {
6 | source = "hashicorp/local"
7 | version = ">= 1.3"
8 | }
9 | external = {
10 | source = "hashicorp/external"
11 | version = ">= 2.0"
12 | }
13 | utils = {
14 | source = "cloudposse/utils"
15 | version = ">= 1.7.1"
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------