Configuration Scheme
The configuration supported for all of our patterns follows a consistent scheme. This describes the internal workings of the patterns and how the YAML based content provided by the user is combined with a set of internal defaults in order to create a final set of options and customizations when managing resources
Minimum input variables
Rather than define 200 separate input variables we will read all of our user provided configuration from a single YAML syntax file; the configuration_file
variable.
# User provided config
variable "configuration_file" {
description = "An encoded map payload of configuration attributes in a YAML file"
default = null
}
# Sub-module or advanced usage for nested resources
variable "configuration_map" {
description = "An encoded map payload of configuration attributes intended for advanced usage"
default = null
}
For advanced usage with nested resources and sub-modules it is possible to provide the configuration as a native Terraform map object - this should not considered a stable configuration interface.
locals {
# Imported config values from User
user_config = try(
yamldecode(file("${var.configuration_file}"), # 1. Default source: YAML File
var.configuration_map, # 2. Advanced usage: Terraform Map
{} # 3. Fallback value
)
}
The user_config
is then overlayed on the default values internal to the pattern in order to create a final set of values for use with the packaged Terraform resources.
Case naming
In order to match the existing convention documented in all of the Terraform provider resources we will make use of snake_case naming. This allows us to pass configuration values (maps, dicts, arrays, etc) directly to providers and their managed resources without additional transformation. For each pattern, snake_case is used for all of the top level keys within the configuration block.
- You can read about the various case types used in modern development in this nice tutorial from FreeCoedCamp.
- The Hashicorp Style Guide also defines a number of rules for naming that can be enforced automatically by running
terraform fmt
.
Pattern ID
Each pattern will be coded to look for a YAML config block that corresponds to it's internal pattern ID.
locals {
# Internal pattern ID
pattern_id = "enterprise_reference_example"
}
This allows a single YAML file to hold configuration for multiple patterns that may be part of the same workload, sharing the common options and still supporting customization at a per-pattern level.
# Shared configuration
common_config:
prefix_tokens:
org: "HIO"
tenant: "RI23"
lifecycle: "dev"
default_tags:
Lifecycle: "Development"
CostCenter: "DEMO-REINVENT23"
# RDS instance
enterprise_database:
demo-db-01:
db_engine: "mysql"
db_instance_type: "t2.large"
tags:
Name: "demo-db-01"
Function: 'RDS database for the demo for re:Invent'
# Multiple EC2 instances
enterprise_stateful_vm:
# 1st one
demo-web-01:
instance_ami: "amazonlinux2"
instance_type: "t2.micro"
tags:
Name: "demo-web-01"
Function: 'Web services demo server for re:Invent'
# 2nd one
demo-app-01:
instance_ami: "redhat8"
instance_type: "t2.micro"
tags:
Name: "demo-app-01"
Function: 'All in one demo server for re:Invent'
# ..and on we go
Prefix tokens
The tokens will be combined using a separator (-
) to create two prefixes; one for regional resources (ie. EC2, VPC, RDS) and a second for global resources (ie. IAM) which is defined as an internal pattern variable.
locals {
# Internal prefix separator
prefix_token_separator = "-"
}
Resource tags
The default tags provided (Key: common_config.default_tags
) in the YAML will be combined with any user provided tags and finally supplimented by any resource-specific tags that are intended to support future automation or integrations as meta-data sources.
# Shared configuration
common_config:
...
default_tags: # <- Added to all resources
Lifecycle: "Development"
CostCenter: "DEMO-REINVENT23"
# RDS instance
enterprise_database:
demo-db-01:
...
tags:
Name: "demo-db-01" # <- Added to this resource instance
...
# EC2 instances
enterprise_stateful_vm:
VM01:
instance_ami: "amazonlinux2"
instance_type: "t2.micro"
VM02:
instance_ami: "amazonlinux2"
instance_type: "t2.micro"
VM03:
instance_ami: "amazonlinux2"
instance_type: "t2.micro"
tags: # <- Added to this resource instance
Name: VERYSPECIAL01
resource "aws_iam_role" "mgmt_vpc_flow_logs" {
...
# Add default, resource specific and and User provided tags
tags = merge(
local.default_tags,
{
# Global resource prefix used as IAM resources are global to the AWS account
"Name" = format("%s-VPC-FLOW-LOGS-ROLE", local.gbl_resource_prefix)
}
)
...
}
resource "aws_vpc_endpoint" "security_ec2_vpc_endpoint" {
...
# Add default, resource specific and and User provided tags
tags = merge(
local.default_tags,
{
# Regional resource prefix used
"Name" = format("%s-VPCE-EC2", local.resource_prefix)
}
)
...
}
- Any valid YAML key-value pair can be used
- Values provided will be used as-is and not be case modified, truncated or encoded
- Setting any key-value pair for
default_tags
will replace all of the internal default tags applied
YAML key levels
- Ensure that all patterns are loading configuration from a top level (L1) key within the provided YAML file that matches the coded Pattern ID
- Ensure that 2nd level (L2) is used for pattern features block
- Ensure that all features are using 3rd level (L3) keys nested below the pattern features block to control on/off irrespective of other feature configuration
key_level_1: # 1st Level for Pattern ID
key-level-2: "pattern_features" # 2nd Level for Pattern Features
key-level-3: "feature" # 3rd Level for Pattern Feature
enterprise_container_registry:
pattern_features: # Pattern Features block
shared_container_registry: # Feature block
enabled: true # Feature switch
registry_images: # Feature customization
- blox
- awsh
Config file line length
---
# Try to limit max line length to 120 chars to ensure that it will display correctly at default zoom on the
# worx docs site and when printed