Skip to content

Commit

Permalink
Use terraform-provider-utils Terraform provider for the module and …
Browse files Browse the repository at this point in the history
…all submodules (#8)

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates

* Updates
  • Loading branch information
aknysh authored Feb 8, 2021
1 parent fb855bc commit 813df73
Show file tree
Hide file tree
Showing 61 changed files with 1,979 additions and 1,714 deletions.
7 changes: 4 additions & 3 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@

# Cloud Posse must review any changes to standard context definition,
# but some changes can be rubber-stamped.
**/context.tf @cloudposse/engineering @cloudposse/approvers
README.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
docs/*.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
**/*.tf @cloudposse/engineering @cloudposse/approvers
README.yaml @cloudposse/engineering @cloudposse/approvers
README.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers
docs/*.md @cloudposse/engineering @cloudposse/contributors @cloudposse/approvers

# Cloud Posse Admins must review all changes to CODEOWNERS or the mergify configuration
.github/mergify.yml @cloudposse/admins
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.tfstate.*
.terraform
.terraform.tfstate.lock.info
**/.terraform.lock.hcl

**/.idea
**/*.iml
Expand Down
158 changes: 81 additions & 77 deletions README.md

Large diffs are not rendered by default.

132 changes: 61 additions & 71 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,18 @@ categories:
- stacks
- helm
- helmfile
- provider
- terraform-provider
- deep-merge
- backend
- s3
- backend-s3

# List any related terraform modules that this module may be used with or that this module depends on.
related:
- name: "terraform-provider-utils"
description: "The Cloud Posse Terraform Provider for various utilities."
url: "https://github.com/cloudposse/terraform-provider-utils"
- name: "terraform-yaml-config"
description: "Terraform module to convert local and remote YAML configuration templates into Terraform lists and maps."
url: "https://github.com/cloudposse/terraform-yaml-config"
Expand Down Expand Up @@ -84,14 +93,11 @@ references:
- name: "Terraform `template_file` data source"
description: "The `template_file` data source renders a template from a template string, which is usually loaded from an external file."
url: "https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file"
- name: "Deepmerge"
description: "Terraform module to perform a deep map merge of standard Terraform maps and objects."
url: "https://github.com/Imperative-Systems-Inc/terraform-modules/tree/master/deepmerge"

# Short description of this project
description: |-
Terraform module that loads an opinionated ["stack" configuration](#examples) from local or remote YAML sources
using the [`cloudposse/terraform-yaml-config`](https://github.com/cloudposse/terraform-yaml-config) module.
Terraform module that loads and processes an opinionated ["stack" configuration](#examples) from YAML sources
using the [`terraform-provider-utils`](https://github.com/cloudposse/terraform-provider-utils) Terraform provider.
It supports deep-merged variables, backend config, and remote state outputs for Terraform and helmfile components.
Expand All @@ -105,27 +111,24 @@ introduction: |-
- [remote-state](modules/remote-state) - accepts stack configuration and returns remote state outputs for a Terraform component.
The module supports `s3` and `remote` (Terraform Cloud) backends.
### Attributions
Big thanks to [Imperative Systems Inc.](https://github.com/Imperative-Systems-Inc)
for the excellent [deepmerge](https://github.com/Imperative-Systems-Inc/terraform-modules/tree/master/deepmerge) Terraform module
to perform a deep map merge of standard Terraform maps and objects.
# How to use this module. Should be an easy example to copy and paste.
usage: |-
For a complete example, see [examples/complete](examples/complete).
For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest),
see [test](test).
For an example on how to configure remote state for Terraform components in YAML config files and then read the components outputs from the remote state,
see [examples/remote-state](examples/remote-state).
For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest),
see [test](test).
For an example on how to process `vars` and `backend` configurations for all Terraform and helmfile components for a list of stacks,
see [examples/stacks](examples/stacks).
# Example usage
examples: |-
Here's an example stack configuration file:
Here's an example of a stack configuration file:
```yaml
import:
Expand Down Expand Up @@ -160,36 +163,35 @@ examples: |-
### Complete example
This example loads the stack config `my-stack` (which in turn imports other YAML config dependencies)
and returns variables, backend config, and imports for stack `my-stack` and Terraform component `my-vpc`.
and returns variables and backend config for the Terraform component `my-vpc` from the stack `my-stack`.
```hcl
module "stack_config" {
source = "cloudposse/stack-config/yaml"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
stack_config_local_path = "./config"
stack = "my-stack"
}
module "vars" {
source = "cloudposse/stack-config/yaml//modules/vars"
# version = "x.x.x"
config = module.stack_config.config
component = "my-vpc"
}
module "backend" {
source = "cloudposse/stack-config/yaml//modules/backend"
# version = "x.x.x"
config = module.stack_config.config
component = "my-vpc"
}
module "vars" {
source = "cloudposse/stack-config/yaml//modules/vars"
# version = "x.x.x"
stack_config_local_path = "./stacks"
stack = "my-stack"
component_type = "terraform"
component = "my-vpc"
context = module.this.context
}
module "backend" {
source = "cloudposse/stack-config/yaml//modules/backend"
# version = "x.x.x"
stack_config_local_path = "./stacks"
stack = "my-stack"
component_type = "terraform"
component = "my-vpc"
context = module.this.context
}
```
The example returns the following `vars`, `backend`, and `import` configurations for `my-stack` stack and `my-vpc` Terraform component:
The example returns the following `vars` and `backend` configurations for the `my-vpc` Terraform component:
```hcl
vars = {
Expand Down Expand Up @@ -241,13 +243,6 @@ examples: |-
"role_arn" = "arn:aws:iam::xxxxxxxxxxxx:role/eg-gbl-root-terraform"
"workspace_key_prefix" = "vpc"
}
all_imports_list = [
"imports-level-2.yaml",
"imports-level-3.yaml",
"imports-level-3a.yaml",
"imports-level-4.yaml",
]
```
See [examples/complete](examples/complete) for more details.
Expand All @@ -261,30 +256,25 @@ examples: |-
__NOTE:__ The backend type (`s3`) and backend configuration for the components are defined in the stack YAML config files.
```hcl
module "stack_config" {
source = "cloudposse/stack-config/yaml"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
stack_config_local_path = "./config"
stack = "my-stack"
}
module "remote_state_my_vpc" {
source = "cloudposse/stack-config/yaml//modules/remote-state"
# version = "x.x.x"
config = module.stack_config.config
component = "my-vpc"
}
module "remote_state_eks" {
source = "cloudposse/stack-config/yaml//modules/remote-state"
# version = "x.x.x"
config = module.stack_config.config
component = "eks"
}
module "remote_state_my_vpc" {
source = "cloudposse/stack-config/yaml"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
stack_config_local_path = "./stacks"
stack = "my-stack"
component = "my-vpc"
}
module "remote_state_eks" {
source = "cloudposse/stack-config/yaml"
# Cloud Posse recommends pinning every module to a specific version
# version = "x.x.x"
stack_config_local_path = "./stacks"
stack = "my-stack"
component = "eks"
}
```
See [examples/remote-state](examples/remote-state) for more details.
Expand Down
66 changes: 50 additions & 16 deletions context.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

module "this" {
source = "cloudposse/label/null"
version = "0.22.1" // requires Terraform >= 0.12.26
version = "0.24.1" # requires Terraform >= 0.13.0

enabled = var.enabled
namespace = var.namespace
Expand All @@ -34,27 +34,16 @@ module "this" {
label_order = var.label_order
regex_replace_chars = var.regex_replace_chars
id_length_limit = var.id_length_limit
label_key_case = var.label_key_case
label_value_case = var.label_value_case

context = var.context
}

# Copy contents of cloudposse/terraform-null-label/variables.tf here

variable "context" {
type = object({
enabled = bool
namespace = string
environment = string
stage = string
name = string
delimiter = string
attributes = list(string)
tags = map(string)
additional_tag_map = map(string)
regex_replace_chars = string
label_order = list(string)
id_length_limit = number
})
type = any
default = {
enabled = true
namespace = null
Expand All @@ -68,6 +57,8 @@ variable "context" {
regex_replace_chars = null
label_order = []
id_length_limit = null
label_key_case = null
label_value_case = null
}
description = <<-EOT
Single object for setting entire context at once.
Expand All @@ -76,6 +67,16 @@ variable "context" {
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional_tag_map, which are merged.
EOT

validation {
condition = lookup(var.context, "label_key_case", null) == null ? true : contains(["lower", "title", "upper"], var.context["label_key_case"])
error_message = "Allowed values: `lower`, `title`, `upper`."
}

validation {
condition = lookup(var.context, "label_value_case", null) == null ? true : contains(["lower", "title", "upper", "none"], var.context["label_value_case"])
error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
}
}

variable "enabled" {
Expand Down Expand Up @@ -158,11 +159,44 @@ variable "id_length_limit" {
type = number
default = null
description = <<-EOT
Limit `id` to this many characters.
Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for default, which is `0`.
Does not affect `id_full`.
EOT
validation {
condition = var.id_length_limit == null ? true : var.id_length_limit >= 6 || var.id_length_limit == 0
error_message = "The id_length_limit must be >= 6 if supplied (not null), or 0 for unlimited length."
}
}

variable "label_key_case" {
type = string
default = null
description = <<-EOT
The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`.
Possible values: `lower`, `title`, `upper`.
Default value: `title`.
EOT

validation {
condition = var.label_key_case == null ? true : contains(["lower", "title", "upper"], var.label_key_case)
error_message = "Allowed values: `lower`, `title`, `upper`."
}
}

variable "label_value_case" {
type = string
default = null
description = <<-EOT
The letter case of output label values (also used in `tags` and `id`).
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Default value: `lower`.
EOT

validation {
condition = var.label_value_case == null ? true : contains(["lower", "title", "upper", "none"], var.label_value_case)
error_message = "Allowed values: `lower`, `title`, `upper`, `none`."
}
}
#### End of copy of cloudposse/terraform-null-label/variables.tf
21 changes: 11 additions & 10 deletions docs/terraform.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,42 @@
|------|---------|
| terraform | >= 0.13.0 |
| external | >= 2.0 |
| http | >= 2.0 |
| local | >= 1.3 |
| template | >= 2.2 |
| utils | >= 0.2.0 |

## Providers

No provider.
| Name | Version |
|------|---------|
| utils | >= 0.2.0 |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
| attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no |
| context | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | <pre>object({<br> enabled = bool<br> namespace = string<br> environment = string<br> stage = string<br> name = string<br> delimiter = string<br> attributes = list(string)<br> tags = map(string)<br> additional_tag_map = map(string)<br> regex_replace_chars = string<br> label_order = list(string)<br> id_length_limit = number<br> })</pre> | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_order": [],<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {}<br>}</pre> | no |
| context | Single object for setting entire context at once.<br>See description of individual variables for details.<br>Leave string and numeric variables as `null` to use default value.<br>Individual variable settings (non-null) override settings in context object,<br>except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | <pre>{<br> "additional_tag_map": {},<br> "attributes": [],<br> "delimiter": null,<br> "enabled": true,<br> "environment": null,<br> "id_length_limit": null,<br> "label_key_case": null,<br> "label_order": [],<br> "label_value_case": null,<br> "name": null,<br> "namespace": null,<br> "regex_replace_chars": null,<br> "stage": null,<br> "tags": {}<br>}</pre> | no |
| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| enabled | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| environment | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| id\_length\_limit | Limit `id` to this many characters.<br>Set to `0` for unlimited length.<br>Set to `null` for default, which is `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| id\_length\_limit | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for default, which is `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| label\_key\_case | The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`.<br>Possible values: `lower`, `title`, `upper`.<br>Default value: `title`. | `string` | `null` | no |
| label\_order | The naming order of the id output and Name tag.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no |
| label\_value\_case | The letter case of output label values (also used in `tags` and `id`).<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Default value: `lower`. | `string` | `null` | no |
| name | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no |
| namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no |
| parameters | Map of parameters for interpolation within the YAML config templates | `map(string)` | `{}` | no |
| regex\_replace\_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| stack | Stack name | `string` | `null` | no |
| stack\_config\_local\_path | Path to local stack configs | `string` | `""` | no |
| stack\_config\_remote\_path | Path to remote stack configs | `string` | `""` | no |
| stack\_config\_local\_path | Path to local stack configs | `string` | n/a | yes |
| stacks | A list of stack names | `list(string)` | n/a | yes |
| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| config | Stack config |
| imports | List of all imported YAML files |
| config | Stack configurations |

<!-- markdownlint-restore -->
Loading

0 comments on commit 813df73

Please sign in to comment.