SecretManagement for Terraform and Ansible

In this quick article, I’ll show you how I use AWS SSM Parameter Store as a glue between Terrafom and Ansible.

Use Case

For a personal project, I needed to pass some parameters (key/value) and secrets (encrypted) from my IaC Terraform to Ansible.

AWS SSM PS ?

AWS SSM Parameter Store is a secure key-value storage, a native EC2 functionality.

From AWS Documentation:

Parameter Store offers the following benefits and features:

  • Use a secure, scalable, hosted secrets management service (No servers to manage).
  • Improve your security posture by separating your data from your code.
  • Store configuration data and secure strings in hierarchies and track versions.
  • Control and audit access at granular levels.
  • Configure change notifications and trigger automated actions.
  • Tag parameters individually, and then secure access from different levels, including operational, parameter, EC2 tag, or path levels.
  • Reference AWS Secrets Manager secrets by using Parameter Store parameters.
  • Use Parameter Store parameters with other Systems Manager capabilities and AWS services to retrieve secrets and configuration data from a central store. The following AWS services support Parameter Store parameters: Amazon EC2, Amazon Elastic Container Service, AWS Lambda, AWS CloudFormation, AWS CodeBuild, and AWS CodeDeploy.
  • Configure integration with AWS KMS, Amazon SNS, Amazon CloudWatch, and AWS CloudTrail for encryption, notification, monitoring, and audit capabilities.

Terraform

Set SSM secrets the right way:

  1. Generate a password from your code.
  2. Set the password in a SecureString

below an example of Terraform usage:

# Generate Secure Password
resource "random_string" "rds_password" {
  length = 15
  special = false
}

# Secure RDS Password
resource "aws_ssm_parameter" "rds_password" {
  name  = "${var.project-name}-rds-password"
  description  = "${var.project-name}-${var.env}-rds-password"
  type  = "SecureString"
  value = "${random_string.rds_password.result}"
}

# RDS Endpoint
resource "aws_ssm_parameter" "rds_endpoint" {
  name  = "${var.project-name}-rds-endpoint"
  type  = "String"
  value = "${aws_db_instance.project-db.endpoint}"
}

Ansible

Read SSM secrets the right way:

Required Ansible version >= 2.5

From environement variables (host_vars):

# MySQL Password
wp_mysql_password: "{{ lookup('aws_ssm', 'project-rds-password', region='eu-west-3' ) }}"

Leave a Comment