iToverDose/Software· 6 MAY 2026 · 16:04

Secure AWS Secrets Manager Access for Cloud Infrastructure

Learn how to integrate AWS Secrets Manager with Terraform to securely retrieve and manage application credentials in cloud infrastructure.

DEV Community4 min read0 Comments

Modern cloud applications rely on secrets like API keys, database passwords, and encryption tokens. Storing these in plaintext or local files creates security risks. AWS Secrets Manager provides an encrypted solution, but integrating it into infrastructure requires careful setup.

This guide covers creating secrets, retrieving them via Terraform, and deploying them securely to EC2 instances. Follow along to implement a scalable secrets management workflow that meets enterprise security standards.

Why AWS Secrets Manager Matters for Cloud Applications

Environment variables and configuration files are common ways to pass secrets to applications. However, these methods expose sensitive data in logs, version control systems, or instance metadata. AWS Secrets Manager addresses this by:

  • Automatically rotating credentials without downtime
  • Encrypting secrets at rest using AWS KMS
  • Providing fine-grained IAM access controls
  • Centralizing secrets management across multiple services

For infrastructure-as-code deployments, integrating Secrets Manager ensures secrets remain secure throughout the application lifecycle.

Creating and Updating Secrets via CLI

Secrets can be created through the AWS Console or programmatically using the AWS CLI. The CLI approach works well for automation pipelines and infrastructure code. Here’s how to create a new secret:

aws secretsmanager create-secret \
  --name "my_app/v1/credentials" \
  --description "Application credentials for production environment" \
  --secret-string '{
    "api_key": "your-actual-api-key-here",
    "database_password": "secure-password-123",
    "encryption_key": "aes-256-key-value"
  }'

The command returns metadata about the secret, including its Amazon Resource Name (ARN) and unique version identifier. This metadata is crucial for later retrieval in infrastructure code.

Automating Secret Updates with a Script

Manually updating secrets via the AWS Console becomes tedious at scale. A Bash script can read from a local .env file, convert its contents to JSON, and update the secret in AWS Secrets Manager. The script handles both creation and updates:

#!/bin/bash

if [ ! -f .env ]; then
  echo "Error: .env file not found in the current directory!"
  exit 1
fi

# Initialize JSON string
SECRET_JSON="{"
FIRST_ENTRY=true

# Read .env file line by line
while IFS='=' read -r key value; do
  # Skip empty lines and comments
  [[ -z "$key" || "$key" =~ ^# ]] && continue
  
  # Remove surrounding quotes from value
  value=$(echo "$value" | sed 's/^"//;s/"$//')
  
  # Add comma separator if not the first entry
  if [ "$FIRST_ENTRY" = true ]; then
    FIRST_ENTRY=false
  else
    SECRET_JSON="$SECRET_JSON,"
  fi
  
  # Add key-value pair to JSON string
  SECRET_JSON="$SECRET_JSON\"$key\": \"$value\""
done < .env

SECRET_JSON="$SECRET_JSON}"

# Check if secret exists
if aws secretsmanager describe-secret --secret-id "my_app/v1/credentials" >/dev/null 2>&1; then
  # Update existing secret
  aws secretsmanager update-secret \
    --secret-id "my_app/v1/credentials" \
    --secret-string "$SECRET_JSON"
  echo "✅ Secret updated successfully!"
else
  # Create new secret if it doesn't exist
  aws secretsmanager create-secret \
    --name "my_app/v1/credentials" \
    --description "Application credentials" \
    --secret-string "$SECRET_JSON"
  echo "✅ New secret created successfully!"
fi

A sample .env file might look like:

api_key=abc123xyz456

database_password=secure-pass-789
db_host=production-db.cluster-xyz.us-east-1.rds.amazonaws.com

Running the script updates the secret in AWS. The JSON structure preserves the original key-value pairs, making it easy to reference specific values later.

Integrating Secrets Manager with Terraform Infrastructure

Terraform becomes more powerful when it can dynamically fetch secrets from AWS Secrets Manager. This approach avoids hardcoding sensitive values in configuration files. The integration requires two key components in your Terraform modules.

Retrieving Secret Metadata

First, define a data source to fetch the secret’s metadata, including its ARN. This doesn’t retrieve the actual secret value but provides the identifier needed for subsequent operations:

# modules/secrets/main.tf
data "aws_caller_identity" "current" {}

data "aws_secretsmanager_secret" "app_secrets" {
  name = var.credentials_name
}

The aws_caller_identity data source provides context about the current AWS account and IAM principal making the API calls. This is useful for logging and debugging.

Fetching the Actual Secret Value

Next, retrieve the secret value itself using its ARN. This data source fetches the latest version of the secret by default:

# modules/secrets/main.tf
data "aws_secretsmanager_secret_version" "current" {
  secret_id = data.aws_secretsmanager_secret.app_secrets.id
}

The secret value is stored as a JSON string. Terraform’s jsondecode function converts this into a map that can be referenced in other resources. For example, to expose the secret to an EC2 instance:

# modules/secrets/outputs.tf
output "secrets" {
  value     = jsondecode(data.aws_secretsmanager_secret_version.current.secret_string)
  sensitive = true
}

Setting sensitive = true ensures the values aren’t displayed in Terraform logs or outputs.

Deploying Secrets to EC2 Instances

With the secrets mapped in Terraform, they can be injected into EC2 instances during provisioning. Here’s how to pass the api_key as an environment variable to a Docker container running on the instance:

# main.tf
module "secrets" {
  source            = "./modules/secrets"
  credentials_name  = "my_app/v1/credentials"
}

module "ec2_instance" {
  source              = "./modules/ec2"
  instance_ami        = var.instance_ami
  instance_type       = var.instance_type
  security_group_id   = module.security_group.security_group_id
  subnet_id           = module.network.public_subnet_ids[0]
  ssh_public_key      = var.ssh_public_key
  user_data = <<-EOF
    #!/bin/bash
    sudo apt-get update -y
    sudo apt-get install -y docker.io
    sudo systemctl start docker
    sudo systemctl enable docker
    sudo usermod -aG docker $USERNAME
    
    # Start container with secrets as environment variables
    sudo docker run -d -p 80:80 \
      -e API_KEY=${module.secrets.secrets.api_key} \
      -e DB_PASSWORD=${module.secrets.secrets.database_password} \
      nginx
  EOF
}

This approach keeps secrets out of version control while maintaining their security during deployment. The values are only available to the instance at runtime.

Best Practices for Secure Secret Management

Implementing AWS Secrets Manager is just the first step. Follow these practices to maximize security:

  • Use IAM roles instead of access keys for Terraform to interact with Secrets Manager
  • Enable automatic secret rotation for credentials
  • Restrict access using IAM policies tied to specific secret ARNs
  • Monitor secret access with AWS CloudTrail
  • Rotate secrets regularly, especially after personnel changes
  • Avoid logging secret values in Terraform state files

As cloud architectures grow more complex, centralized secrets management becomes essential. AWS Secrets Manager provides the foundation for secure, scalable secret handling that integrates seamlessly with infrastructure-as-code tools like Terraform.

AI summary

Learn to integrate AWS Secrets Manager with Terraform for secure secret retrieval and management. Step-by-step guide to creating, updating, and deploying secrets in cloud infrastructure.

Comments

00
LEAVE A COMMENT
ID #J9VB6P

0 / 1200 CHARACTERS

Human check

6 + 4 = ?

Will appear after editor review

Moderation · Spam protection active

No approved comments yet. Be first.