Cross-Account Parameters
NTC Parameters is a purpose-built solution for sharing configuration data across AWS multi-account environments. It addresses the unique challenges of parameter management in complex organizational structures where multiple accounts need access to shared configuration data with different read and write permissions.
The Multi-Account Parameter Challenge
In a well-architected AWS multi-account environment, resources are distributed across specialized accounts based on their function. However, these resources often need to reference each other's configuration details:
Common Scenarios
CloudTrail Configuration
- Organizational CloudTrail hosted in management account or delegated security account
- S3 bucket for log storage hosted in dedicated log archive account
- Trail configuration needs the exact S3 bucket ARN from the log archive account
Security Configuration
- S3 bucket as destination for security findings
- Organizational Unit Ids as targets for security policies
- Notify account owner or security contact about security findings
Network Resource Sharing
- VPC Transit Gateway hosted in connectivity account
- Application accounts need to attach to the Transit Gateway
- Requires sharing Transit Gateway ID, route table IDs, and network CIDRs
Without a centralized parameter sharing solution, these scenarios typically result in:
- Hardcoded values that become maintenance nightmares
- Manual coordination between account teams
- Configuration drift when values change
- Deployment dependencies that complicate automation
Why Not AWS SSM Parameter Store?
While AWS SSM Parameter Store is excellent for single-account parameter management, it has significant limitations in multi-account scenarios:
Access Management Complexity
SSM Parameter Store Limitations:
# SSM requires cross-account IAM roles for write access
resource "aws_iam_role" "parameter_writer" {
name = "ssm-parameter-writer"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::ACCOUNT_ID:root" // we allow another account to assume this role
}
Action = "sts:AssumeRole"
}
]
})
}
# Additional policies needed for parameter access
resource "aws_iam_role_policy" "parameter_writer_policy" {
name = "ssm-parameter-access"
role = aws_iam_role.parameter_writer.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ssm:PutParameter",
"ssm:GetParameter",
"ssm:DeleteParameter"
]
Resource = "arn:aws:ssm:*:*:parameter/myorg/*" // define for which parameters to grant write access
}
]
})
}
# RAM sharing organization configuration to grant read access to parameters
resource "aws_ram_resource_share" "ssm_share" {
name = "ssm-parameter-reader"
allow_external_principals = false
}
resource "aws_ram_resource_association" "ssm_association" {
resource_arn = aws_ssm_parameter.example.arn
resource_share_arn = aws_ram_resource_share.ssm_share.arn
}
resource "aws_ram_principal_association" "dev_shared_params" {
principal = "o-example123456" # grant read access to accounts in organization
resource_share_arn = aws_ram_resource_share.ssm_share.arn
}
NTC Parameters Simplicity:
# Simple S3 bucket policy manages all access
module "ntc_parameters" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-parameters?ref=X.X.X"
bucket_name = "myorg-parameters"
org_id = "o-example123456" # grant read access to accounts in organization
parameter_nodes = [
{
node_name = "connectivity"
node_owner_account_id = "123456789012" # grant write access to Connectivity account
},
{
node_name = "security"
node_owner_account_id = "123456789013" # grant write access to Security account
}
]
}
Data Structure Limitations
SSM Parameter Store:
- Only supports string values
- JSON objects must be encoded as strings
- No native support for complex nested structures
- Requires manual JSON parsing in consuming code
- Up to 8 KB per parameter
# SSM Parameter Store - complex objects as JSON strings
resource "aws_ssm_parameter" "network_config" {
name = "/myorg/network/config"
type = "String"
value = jsonencode({
transit_gateway_id = "tgw-1234567890abcdef0"
route_tables = {
shared = "tgw-rtb-shared123"
isolated = "tgw-rtb-isolated456"
}
cidrs = {
connectivity = "10.0.0.0/16"
workloads = "10.1.0.0/16"
}
})
}
# Consumer must decode JSON manually
data "aws_ssm_parameter" "network_config" {
name = "/myorg/network/config"
}
locals {
network_config = jsondecode(data.aws_ssm_parameter.network_config.value)
tgw_id = local.network_config.transit_gateway_id
}
NTC Parameters:
- Native support for complex JSON structures
- Direct access to nested values
- Type preservation for numbers, booleans, arrays
- No size limits
# NTC Parameters - native JSON support
module "ntc_parameters_writer" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-parameters//modules/writer?ref=X.X.X"
bucket_name = "myorg-parameters"
parameter_node = "connectivity"
node_parameters = {
transit_gateway_id = aws_ec2_transit_gateway.main.id
route_tables = {
shared = aws_ec2_transit_gateway_route_table.shared.id
isolated = aws_ec2_transit_gateway_route_table.isolated.id
}
cidrs = {
connectivity = "10.0.0.0/16"
workloads = "10.1.0.0/16"
}
}
}
# Consumer gets direct access to nested values
module "ntc_parameters_reader" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-parameters//modules/reader?ref=X.X.X"
bucket_name = "myorg-parameters"
}
locals {
tgw_id = module.ntc_parameters_reader.all_parameters.connectivity.transit_gateway_id
shared_rt = module.ntc_parameters_reader.all_parameters.connectivity.route_tables.shared
}
Understanding Parameter Nodes and Node Owners
Before diving into the technical architecture, it's essential to understand the core concepts of Parameter Nodes and Node Owners that make NTC Parameters so effective for multi-account environments.
What are Parameter Nodes?
A Parameter Node is a logical grouping of related parameters that belong to a specific functional area within your AWS organization. Think of it as a namespace or container that organizes parameters by their purpose and ownership.
Each parameter node contains a subset of the total parameters in your organization, focusing on a specific domain such as:
- Network resources (Transit Gateways, VPCs, route tables)
- Security configurations (KMS keys, Security Hub settings, GuardDuty configurations)
- Logging infrastructure (S3 buckets, CloudTrail settings)
- Organization metadata (Account IDs, OU structures, policies)
What are Node Owners?
A Node Owner is the AWS account that has write access to a specific parameter node. This account is responsible for:
- Creating and updating parameters within their node
- Maintaining the accuracy of the parameter data
- Managing the lifecycle of resources that generate these parameters
The node owner concept implements a clear separation of responsibilities - each account manages only the parameters for resources they own, while all accounts can read parameters from all nodes.
Real-World Example: Log Archive Node
Let's look at a real example from a log archive account that owns the log-archive
parameter node:
{
"log_bucket_arns": {
"aws_config": "arn:aws:s3:::myorg-config-archive",
"dns_query_logs": "arn:aws:s3:::myorg-dns-query-logs-archive",
"guardduty": "arn:aws:s3:::myorg-guardduty-archive",
"org_cloudtrail": "arn:aws:s3:::myorg-cloudtrail-archive",
"transit_gateway_flow_logs": "arn:aws:s3:::myorg-transit-gateway-logs-archive",
"vpc_flow_logs": "arn:aws:s3:::myorg-vpc-flow-logs-archive"
},
"log_bucket_ids": {
"aws_config": "myorg-config-archive",
"dns_query_logs": "myorg-dns-query-logs-archive",
"guardduty": "myorg-guardduty-archive",
"org_cloudtrail": "myorg-cloudtrail-archive",
"transit_gateway_flow_logs": "myorg-transit-gateway-logs-archive",
"vpc_flow_logs": "myorg-vpc-flow-logs-archive"
},
"log_bucket_kms_key_arns": {
"aws_config": "arn:aws:kms:us-east-1:444444444444:key/11111111-2222-3333-4444-555555555555",
"dns_query_logs": "arn:aws:kms:us-east-1:444444444444:key/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"guardduty": "arn:aws:kms:us-east-1:444444444444:key/12345678-1234-1234-1234-123456789abc",
"org_cloudtrail": "arn:aws:kms:us-east-1:444444444444:key/87654321-4321-4321-4321-210987654321",
"transit_gateway_flow_logs": "arn:aws:kms:us-east-1:444444444444:key/abcdef12-3456-7890-abcd-ef1234567890",
"vpc_flow_logs": "arn:aws:kms:us-east-1:444444444444:key/fedcba98-7654-3210-fedc-ba9876543210"
}
}
In this example:
- Parameter Node:
log-archive
(owned by the log archive account) - Node Owner: Log archive account (e.g.,
444444444444
) - Parameter Categories: The node contains three main parameter groups:
log_bucket_arns
: Full ARNs for S3 buckets used by different AWS serviceslog_bucket_ids
: Bucket names/IDs for referencelog_bucket_kms_key_arns
: KMS keys used to encrypt each type of log data
Other accounts can now reference these parameters without hardcoding values:
# Security account configuring organizational CloudTrail
resource "aws_cloudtrail" "organization_trail" {
name = "organization-trail"
s3_bucket_name = module.ntc_parameters_reader.all_parameters["log-archive"].log_bucket_ids.org_cloudtrail
kms_key_id = module.ntc_parameters_reader.all_parameters["log-archive"].log_bucket_kms_key_arns.org_cloudtrail
# ... other configuration
}
NTC Parameters Architecture
NTC Parameters leverages S3's robust access control mechanisms to provide a simple yet powerful parameter sharing solution:
Core Components
# S3-based parameter storage with organization-wide access
module "ntc_parameters_bucket" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-parameters?ref=X.X.X"
bucket_name = "myorg-ntc-parameters"
# Automatic read access for all organization members
org_id = "o-example123456"
# Granular write access per parameter node
parameter_nodes = [
{
node_name = "mgmt-organizations"
node_owner_account_id = "111111111111" # Management account
},
{
node_name = "connectivity"
node_owner_account_id = "222222222222" # Connectivity account
},
{
node_name = "security-tooling"
node_owner_account_id = "333333333333" # Security account
},
{
node_name = "log-archive"
node_owner_account_id = "444444444444" # Log archive account
}
]
}
Parameter Node Structure
Parameter nodes are organized in S3 using a specific folder structure that separates ownership information, optional account mapping, and individual node parameters:
s3://myorg-ntc-parameters/
├── nodeowners.json # Node ownership mapping and access control
├── account_map.json # Optional: Complete account inventory from NTC Account Factory
├── mgmt-organizations/
│ └── parameters.json # Organization metadata (org_id, ou_ids, etc.)
├── connectivity/
│ └── parameters.json # Network resources (TGW, VPC CIDRs, etc.)
├── security-tooling/
│ └── parameters.json # Security configurations (Security Hub, GuardDuty)
└── log-archive/
└── parameters.json # Logging infrastructure (S3 buckets, KMS keys)
Key Components:
- nodeowners.json: Contains the mapping of which AWS account owns each parameter node and controls write access
- account_map.json: Optional file automatically created by NTC Account Factory containing complete account inventory with metadata
- Node Folders: Each parameter node has its own folder named after the node (e.g.,
log-archive/
,connectivity/
) - parameters.json: Contains the actual parameter data as nested JSON objects within each node folder
This structure provides clear separation between:
- Ownership metadata (who can write to which node)
- Global account inventory (shared account information)
- Domain-specific parameters (organized by functional area)
Integration with NTC Account Factory
NTC Parameters seamlessly integrates with the NTC Account Factory to provide automatic account inventory sharing:
Account Map Generation
The Account Factory automatically publishes account information and baseline configuration data, but NOT the individual account details shown in the previous example. The actual Account Factory implementation focuses on account groupings and baseline roles:
# In the management account with Account Factory
locals {
ntc_parameters_writer_node = "mgmt-account-factory"
# Parameters to store in the ntc-parameters bucket
ntc_parameters_to_write = {
"core_accounts" = local.account_factory_core_account_ids
"workload_accounts" = local.account_factory_workloads_account_ids
"baseline_role_arns" = module.ntc_account_factory.account_factory_baseline_iam_role_arns
}
# Store and share account map from account factory
ntc_account_map = {
for account in local.account_factory_list_enriched : account.account_id => account
}
}
module "ntc_parameters_writer" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-parameters?ref=X.X.X"
bucket_name = local.ntc_parameters_bucket_name
parameter_node = local.ntc_parameters_writer_node
node_parameters = local.ntc_parameters_to_write
replace_parameters = true
store_account_map = true
account_map = local.ntc_account_map
}
This creates:
-
Node parameters (
s3://bucket/mgmt-account-factory/parameters.json
) containing:core_accounts
: Account IDs for core infrastructure accountsworkload_accounts
: Account IDs for workload accountsbaseline_role_arns
: IAM role ARNs created by the Account Factory for baseline access
-
Account map (
s3://bucket/account_map.json
) containing the complete account inventory generated by Account Factory
Consumer Usage
Any account in the organization can access parameters and account map:
# In any consumer account
module "ntc_parameters_reader" {
source = "github.com/nuvibit-terraform-collection/terraform-aws-ntc-parameters//modules/reader?ref=X.X.X"
bucket_name = "myorg-ntc-parameters"
}
locals {
# Access Account Factory parameters
core_accounts = module.ntc_parameters_reader.all_parameters["mgmt-account-factory"].core_accounts
workload_accounts = module.ntc_parameters_reader.all_parameters["mgmt-account-factory"].workload_accounts
baseline_role_arns = module.ntc_parameters_reader.all_parameters["mgmt-account-factory"].baseline_role_arns
# Access the complete account map (if available)
all_accounts_map = module.ntc_parameters_reader.account_map
}
Conclusion
NTC Parameters provides a robust, scalable solution for cross-account parameter sharing in AWS multi-account environments. By leveraging S3's proven access control mechanisms and native JSON support, it eliminates the complexity of traditional parameter sharing approaches while providing enhanced functionality for complex organizational deployments.
Key advantages include:
- Simplified access management through S3 bucket policies
- Native JSON support for complex data structures
- Seamless Account Factory integration for automatic account inventory sharing
- Organization-wide read access with granular write permissions
- No additional IAM role assumptions required
Whether you're implementing a new multi-account architecture or migrating from existing parameter management solutions, NTC Parameters provides the foundation for reliable, secure, and maintainable configuration sharing across your AWS organization.