Using aws secretsmanager with elasticache
TypeScriptIn order to use AWS Secrets Manager with Amazon ElastiCache, we need to accomplish a few key tasks:
- Create a secret in AWS Secrets Manager that will hold sensitive information like a redis password.
- Create an ElastiCache cluster that will use this secret for accessing its nodes securely.
In the code that follows, we will first create a secret to store an example password. Next, we will use this secret when we set up an ElastiCache cluster, where the secret Arn is used to provide the credentials for the ElastiCache user.
AWS Secrets Manager is a service that helps you protect access to your applications, services, and IT resources without the upfront investment and on-going maintenance costs of operating your own infrastructure. The AWS Secrets Manager secrets can be referenced by your applications and services.
Amazon ElastiCache is a fully managed in-memory data store, compatible with Redis or Memcached, that provides secure, scalable, and, high-performance caching to improve the performance of web applications.
Now let's look at the Pulumi code to achieve this setup:
import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; // Create a new secret in AWS Secrets Manager to store, for example, a Redis password const redisPasswordSecret = new aws.secretsmanager.Secret("redisPasswordSecret", { // Pulumi will generate a name for the secret, you can assign one with the `name` parameter description: "ElastiCache Redis password", }); // Define the secret value, often we'd leave this to automated processes, but we'll hard-code // for demonstration purposes. In a real scenario, it's better to use dynamic references. const redisPasswordSecretValue = new aws.secretsmanager.SecretVersion("redisPassword", { secretId: redisPasswordSecret.id, secretString: pulumi.output("SuperSecretPassword!123"), // Replace with your desired password or generation process }); // Create an ElastiCache subnet group const cacheSubnetGroup = new aws.elasticache.SubnetGroup("cacheSubnetGroup", { subnetIds: [ // List your subnet IDs here ], }); // Create a new ElastiCache cluster with Redis engine that uses our secret for credentials const redisCluster = new aws.elasticache.Cluster("redisCluster", { // List of security group IDs to associate with this cache cluster securityGroupIds: [ // Put your security group(s) id(s) here ], // List of subnet group names that should be used for this cache cluster subnetGroupName: cacheSubnetGroup.name, // The number of cache nodes that the cluster should have numCacheNodes: 1, // Node type (CPU/Memory ratio) to use nodeType: "cache.t2.micro", // The initial version of the engine to use (make sure it aligns with your region) engineVersion: "6.x", // The name of your key management service key to encrypt the replica cache cluster kmsKeyId: redisPasswordSecret.kmsKeyId, // Optional, enhances the secrecy of the stored secret by encrypting it with AWS KMS // The ID of our AWS Secrets Manager Secret to store credentials authToken: redisPasswordSecretValue.secretString.apply(s => s), // Engine should be 'memcached' or 'redis' engine: "redis", // Enable encryption in transit for additional security transitEncryptionEnabled: true, // Set whether the password will be stored in plaintext or hashed atRestEncryptionEnabled: true, }); export const redisEndpoint = redisCluster.cacheNodes.apply(nodes => nodes[0].address); export const redisPort = redisCluster.cacheNodes.apply(nodes => nodes[0].port); export const secretArn = redisPasswordSecret.arn;
Explanation
-
Secret Creation: We first define an AWS Secrets Manager
Secret
resource to securely store cache credentials. The contents of the secret could be auto-generated or provided as a string. -
Secret Value: We then define a
SecretVersion
resource that specifies the actual contents of the secret, separated from the secret itself to allow for easy rotation of values. -
Subnet Group: An ElastiCache
SubnetGroup
is defined, assuming that you have pre-existing subnets that are suitable for your cache nodes to be associated with. -
ElastiCache Cluster: We create the ElastiCache cluster with a specific node type and amount, engine version, and associate it with the subnet group and the secret's ARN for credential lookup.
-
Exports: The final output includes the endpoint and port for the Redis cluster, to use in your application, and also the Secret ARN for any other references.
As we're using sensitive secret strings, it's important to secure these correctly and rotate them as per security best practices. Pulumi itself stores state securely using encryption. Remember to replace placeholders (denoted with comments) with actual resource identifiers and values for your AWS setup.
Use this program as a template to set up your ElastiCache cluster with robust security practices by integrating the AWS Secrets Manager.