Terraform Parameter Store Integration with AWS Systems Manager

Integrating AWS Systems Manager Parameter Store with Terraform enables dynamic infrastructure provisioning while keeping configuration values separate from code. Parameter Store provides a hierarchical, cost-effective place to store configuration data such as AMI IDs, VPC IDs, endpoint URLs, feature flags and sensitive strings. Terraform can read those values at plan and apply time through the awsssmparameter data source, and can also create and manage parameters through resources and community modules.

The approach promotes reusability because a single parameter can be referenced by multiple Terraform configurations, environments and accounts. It also supports dynamic lookups for values that change frequently, like AMIs, ensuring deployments always use the latest version without manually updating code.

Reading Parameter Store Values in Terraform

Fetching a parameter begins with a data source definition. The name attribute accepts the full hierarchical path used in Parameter Store.

hcl data "aws_ssm_parameter" "ami_id" { name = "/my-app/latest-ami-id" }

Replace /my-app/latest-ami-id with the actual parameter name. The slash denotes a hierarchical structure that allows logical organization of parameters.

The retrieved value is exposed as value:

hcl data.aws_ssm_parameter.ami_id.value

The value can be used directly in resource configurations:

hcl resource "aws_instance" "example" { ami = data.aws_ssm_parameter.ami_id.value # ... other instance configurations }

This example shows how to use the AMI ID retrieved from Parameter Store when creating an EC2 instance. The same pattern applies to other resources.

```hcl
data "awsssmparameter" "vpcid" {
name = "/infrastructure/production/vpc
id"
}

resource "awssecuritygroup" "app" {
nameprefix = "myapp-"
vpc
id = data.awsssmparameter.vpc_id.value
# ...
}
```

Reading a SecureString parameter requires decryption:

hcl data "aws_ssm_parameter" "db_password" { name = "/myapp/production/database/password" with_decryption = true }

The value will be decrypted when with_decryption is true.

Handling Secure Strings and Secrets

Secure Strings: If the parameter is a SecureString, you should use data.aws_ssm_parameter.ami_id.value directly in the resource configuration. Avoid storing SecureString values in variables or outputs.

For managing secrets, consider using dedicated secret management tools like AWS Secrets Manager. This is the recommended alternative for credentials that need rotation and cross-account sharing.

When creating parameters with Terraform, the ignore_changes lifecycle rule is recommended for sensitive parameters. Let Terraform create the structure, then manage the actual secret values through a separate workflow.

hcl lifecycle { # Don't overwrite secrets that were updated outside Terraform ignore_changes = [value] }

State management note: While convenient, be mindful that changes made directly to Parameter Store values outside of Terraform won't be reflected in your Terraform state. You might need to use terraform refresh to update the state.

Parameter Store Characteristics

Parameter Store supports multiple data types. Besides String, SSM Parameter Store supports other data types like StringList and SecureString. Choose the appropriate type based on your data.

Parameter Store offers versioning, allowing you to reference specific versions of a parameter if needed.

Parameter Hierarchy: Note that / in the parameter name /my-app/latest-ami-id denotes a hierarchical structure in Parameter Store. This allows you to organize parameters logically.

Dynamic Lookups: This approach is ideal for values that might change frequently, like AMIs, as it ensures you're always using the latest version without manually updating your code.

Cost-Effective: Parameter Store is a cost-effective solution for storing configuration data, especially compared to storing it directly in Terraform state.

Permissions: Ensure your Terraform execution environment has the necessary IAM permissions to read from Parameter Store.

Alternative to Variables: Using Parameter Store can be a more secure and manageable alternative to hardcoding sensitive values directly as variables in your Terraform code.

Tier Limits and Constraints

Standard tier parameters have limits that affect design decisions.

Tier Size Limit Parameter Count Limit
Standard 4 KB 10,000 parameters per region
Advanced Not specified in reference Not specified in reference

Advanced Tier Parameters: The standard tier has a 4 KB limit and caps at 10,000 parameters per region.

Error Handling and Robustness

Error Handling: If the parameter doesn't exist, Terraform will throw an error. You can use the try() function to handle this gracefully.

Modularity: For larger projects, consider using modules to encapsulate the logic of fetching and using parameters, promoting code reusability and maintainability.

Creating and Managing Parameters with Terraform

Terraform can create parameters alongside infrastructure. A common pattern uses the Cloud Posse module for read and write access.

Write example creating a String parameter:

hcl module "store_write" { source = "cloudposse/ssm-parameter-store/aws" # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" parameter_write = [ { name = "/cp/prod/app/database/master_password" value = "password1" type = "String" overwrite = "true" description = "Production database master password" } ] tags = { ManagedBy = "Terraform" } }

Read example:

hcl module "store_read" { source = "cloudposse/ssm-parameter-store/aws" # Cloud Posse recommends pinning every module to a specific version # version = "x.x.x" parameter_read = ["/cp/prod/app/database/master_password"] }

Important: In Cloud Posse's examples, we avoid pinning modules to specific versions to prevent discrepancies between the documentation and the latest released versions. However, for your own projects, we strongly advise pinning each module to the exact version you're using. This practice ensures the stability of your infrastructure.

This example creates a new String parameter called /cp/prod/app/database/master_password with the value of password1.

For a complete example, see examples/complete.

Parameter Store vs Secrets Manager

Both services store configuration values, but they are designed for different use cases.

Criteria Parameter Store Secrets Manager
Use case Plain configuration values, endpoints, feature flags, port numbers Credentials that need rotation, automatic secret rotation
Cost Free for standard tier $0.40 per secret per month
Rotation Manual Automatic secret rotation supported
Sharing Account-level Cross-account secret sharing
Hierarchy Hierarchical naming convention Flat namespace

Use Parameter Store when you have plain configuration values, you want to store data for free, or you need a simple hierarchy for organizing config across services and environments.

Use Secrets Manager when you need automatic secret rotation, you need cross-account secret sharing, or you are storing credentials that need to be rotated on a schedule. Secrets Manager costs $0.40 per secret per month.

Many teams use both: Parameter Store for general configuration and Secrets Manager for credentials that need rotation.

Workflow Best Practices

Define a data source: Use the data "aws_ssm_parameter" resource to fetch the desired parameter from SSM. Specify the parameter name using the name attribute.

Access the value: The retrieved parameter value is available in the data.<data_source_name>.<parameter_name>.value attribute.

Utilize the value: Use the accessed value directly within your resource configurations, such as setting the AMI ID for an EC2 instance.

Secure Strings: Handle SecureString parameters directly within resource configurations to avoid exposing sensitive data.

Error Handling: Implement error handling using the try() function to gracefully manage scenarios where the parameter might not exist.

Alternative for Secrets: Consider using AWS Secrets Manager for managing sensitive information instead of SSM Parameter Store.

By leveraging AWS SSM Parameter Store, you can effectively manage and retrieve configuration values within your Terraform projects. This approach promotes dynamic infrastructure provisioning, enhances security by separating sensitive data from your codebase, and improves code maintainability.

You can adapt this approach to retrieve various configuration parameters and use them across your infrastructure deployments.

Conclusion

Terraform integration with AWS Systems Manager Parameter Store provides a straightforward, cost-effective way to manage application configuration on AWS. The hierarchical naming convention gives you clean IAM boundaries, and Terraform makes it easy to define parameters alongside the infrastructure they configure.

Reading parameters via the aws_ssm_parameter data source enables dynamic, reusable infrastructure where values like AMI IDs, VPC IDs and feature flags are sourced from a central store rather than hard-coded. Using with_decryption = true allows secure retrieval of SecureString values, while lifecycle rules such as ignore_changes protect secrets updated outside Terraform.

Parameter Store excels for plain configuration and hierarchical organization at no cost in the standard tier, with a 4 KB size limit and 10,000 parameters per region cap. For credentials requiring automatic rotation and cross-account sharing, Secrets Manager at $0.40 per secret per month remains the appropriate choice, and many teams use both services together.

Effective patterns include direct value references in resources, error handling with try(), modular encapsulation of read and write logic, and pinning community modules to exact versions for stability. Keeping Terraform responsible for structure and Parameter Store for data separation improves maintainability, security and dynamic provisioning across environments.

Sources

  1. nulldog.com
  2. oneuptime.com
  3. TerraformFoundation

Related Posts