Caches store frequently accessed data in memory, which is accessible much faster than disk-based storage or even a database. This capability reduces data retrieval latency and improves the application response times. Amazon ElastiCache for Memcached is a fully managed caching service, which means AWS handles maintenance, patching, backups, and monitoring. In this note, I demonstrate how to create an Amazon ElastiCache for Memcached using Terraform and automate it using GitHub Actions. If you are interested in learning about Amazon ElastiCache for Redis, please check -Create an Amazon ElastiCache for Redis cluster using Terraform.
Amazon ElastiCache for Memcached manages caching by storing the cache data across nodes hosted inside subnets in an Amazon VPC. In Amazon ElastiCache, a Memcached node refers to an individual instance of Memcached that is part of a cache cluster hosted in a subnet. Each node is a server running the Memcached software that provides a subset of the cache. Hence, access to the cache nodes is managed via a security group that enables access from a specific CIDR or security group and on a particular port #. Also, ElastiCache supports placing cache nodes in multiple Availability Zones (AZs) within a VPC for high availability and fault tolerance. This ensures that if one AZ becomes unavailable, the cache nodes in other AZs remain accessible.
Creating an Amazon ElastiCache for Memcached has 4 steps. I have the Terraform code to create and manage these AWS Cloud resources in my GitHub repository. So, if you are interested and want to follow along, here is a link to my code repository at GitHub: kunduso/amazon-elasticache-memcached-tf
. Please note that the branch name = create-memcached
.
Step 1: Create an Amazon VPC and subnets to host the ElastiCache cluster
I created four subnets: - two private for each ElastiCache cluster node and two public. The ElastiCache cluster does not require the public subnet at all. (Note: Although I called that a public subnet, there isn’t a route to 0.0.0.0/0
in the public subnet’s route table; hence, it’s as good as a private subnet).
Please note that I’m referring to the branch
create-memcached
in the repository.
The main
branch of the repository uses the public subnet and has a route to the Internet using the Internet Gateway. But that is not required for this use case. The public subnets are created to support a subsequent use case: accessing the ElastiCache for Memcached cluster from an Amazon EC2 instance.
Step 2: Create a subnet group to host the ElastiCache cluster
The cache nodes in the ElastiCache cluster are spread evenly among the subnets you specify in the subnet group. The below code adds the private subnets to the subnet group.
Step 3: Create a security group to access the ElastiCache cluster
Amazon ElastiCache for Memcached does not provide built-in authentication mechanisms for accessing the Memcached cluster directly. This means no user/password authentication method is available, as you might find in databases or other caches. Hence, access control in Amazon ElastiCache for Memcached is managed via Security Group rules. A Security Group controls access to an ElastiCache cluster’s cache nodes. In the Terraform code below, there are two blocks in a security group -the ingress and egress. Since I selected the port number
11211
in the ElastiCache cluster (discussed later), I enabled ingress on that port in the attached security group with the source set to Amazon VPC’s CIDR. That means that the ElastiCache cluster is accessible on that port only from inside the VPC. And for egress, I have it set to the VPC’s CIDR.
Step 4: Create the Amazon ElastiCache for the Memcached cluster
The Amazon ElastiCache for Memcached is the last resource to create. The code block below specifies all the properties required to create it. For a list of all the properties, check Terraform AWS Registry: elasticache_cluster.
That is all the code required to create the ElastiCache cluster for Memcached. However, please note that to follow best practices, a few additional steps must be followed when using the ElastiCache cluster. These are not necessary to create the ElastiCache cluster but are required to use it.
Best practice 1: Store the ElastiCache endpoint as an AWS Systems Manager Parameter Store parameter.
Any application using the ElastiCache cluster will access it on the endpoint. Hence, the application would require that. Although you can embed values in the application, an alternate approach is to store these as encrypted values in the Systems Manager Parameter Store as parameters and provide permissions to the application to fetch and decrypt them from there. That way, hardcoding the values is not required, and the application stays clear of confidential data.
Best practice 2: Create an IAM policy to access the ElastiCache cluster endpoint from the Systems Manager Parameter Store.
After storing the endpoint as a Systems Manager parameter, I created an IAM policy that allows access to that. An application would require the same IAM policy to be attached to the role it assumes to communicate with the Systems Manager parameter. After attaching the IAM policy, the application can communicate with the Systems Manager parameter and get the values of the ElastiCache endpoint.
Since the endpoint value is confidential, encrypting it using a KMS Key, as mentioned above, is a good practice.
Finally, I also automated the provisioning of the AWS resources using GitHub Actions. If you want to learn how I managed the authentication process, head over to this note –securely-integrate-aws-credentials-with-github-actions-using-openid-connect. I also scanned my code for vulnerabilities using Bridgecrew Checkov, which generated a scan report. Here is a note on how to enable Checkov with GitHub Actions. I’m also interested in the cost of these resources and use Infracost for that, which I have covered in detail in this note –estimate AWS resource cost. The vulnerabilities and cost estimate are available in the pull request as comments.
Once I added all the Terraform code for the resources and their configurations, I pushed the changes to my remote repository. The GitHub Actions workflow concluded with the command terraform apply
enabled and provisioned the resources.
To verify, on the AWS Management Console, I navigated to ElastiCache → Memcached caches and selected the ElastiCache cluster that I created using the Terraform code. The image below lists some of the cluster’s properties.
Scrolling down, I saw the individual cache nodes, too.
That brings us to the end of this note. Let me know if you have any questions or suggestions. In my subsequent note, I’ll demonstrate how to connect using Python to the ElastiCache for Memcached from an Amazon EC2 instance in the same VPC.