Как настроить AWS Elasticache Serverless с Opentofu и Valkey

Как настроить AWS Elasticache Serverless с Opentofu и Valkey

5 августа 2025 г.

AWS представила Amazon Elasticach Bless в ноябре 2023 года. Однако многие разработчики по -прежнему полагаются на более старые кластеры Redis, которые могут быть реальной болью в спине, чтобы управлять и масштабировать.

В этом уроке мы создадим Elasticache Server Server с помощью двигателя Valkey с помощью Opentofu.

Фокус стека с открытым исходным кодом

Это руководство полностью основано на стеке с открытым исходным кодом:

  • Valkey вместо RedisПолем Redis по -прежнему технически открыт, но из -за изменения лицензии (SSPL) это больше не является безопасным или устойчивым вариантом для многих приложений. Валки-это альтернатива, ориентированная на сообщество, которая остается полностью открытой.
  • OpenTofu вместо терраформПо той же причине: Terraform больше не является полностью открытым исходным кодом из -за перехода к лицензии BSL.

Несмотря на это, вы все равно можете использовать Redis и Terraform, если они соответствуют вашим потребностям в сфере этого руководства.


Предварительные условия

Прежде чем начать, убедитесь, что у вас есть следующая настройка:

  1. Учетная запись AWS с достаточными разрешениями IAM для создания ресурсов Elasticache. Если у вас его еще нет, вы можетезарегистрироватьсядля бесплатной учетной записи AWS.
  2. AWS CLI установлен и настроен с достоверными учетными данными. Вы можете следоватьОфициальное руководство по настройке AWS CLIПри необходимости.

Рабочий каталог для вашего кода. В этом руководстве я буду использовать каталогelasticache_guide


Установите OpenTofu на свою машину

Поскольку мы будем работать с Opentofu, первым шагом является его установка.

Вместо того, чтобы установить OpenTofu напрямую, мы будем использоватьTOFUUTILS/TENV- Мощный менеджер версий для Opentofu, Terraform, Terragrunt, Terramate и Atmos, написанный в Go.

Мы начинаем с Tenv, потому что Opentofu быстро развивается, и наличие менеджера версий облегчает переключение между версиями и оставаться в курсе.

УстановитьtenvСледуйте инструкциям вTenv Github Readmeдля вашей операционной системы. Один разtenvнастроен, вы можете установить определенную версию OpenTofu, запустив:

$ tenv tofu install 1.10.3

Вот и все - теперь у вас есть Opentofu, готовый к использованию!


Создать модуль AWS Elasticache Opentofu

В этом руководстве мы будем придерживаться лучших практик Terraform и Opentofu, создав выделенный модуль OpenTofu для предоставления Elasticache Serverless.

Если вы новичок в Terraform Modules или хотите освежить лучших практик, проверьтеЛучшие практики модуля Terraform от DevopScubeстатья.

Давайте пройдемся через процесс шаг за шагом.

Шаг 1

Создайте новый каталог для модуля внутри вашей рабочей папки:

$ mkdir -p elasticache_guide/modules/elasticache_serverless

Шаг 2

Внутриelasticache_guide/modules/elasticache_serverlessкаталог, создайте файл с именемmain.tfПолем Этот файл содержит базовую спецификацию кластера Elasticache.

resource "aws_elasticache_serverless_cache" "this" {
 count = var.create ? 1 : 0

 engine = var.engine
 name   = var.cache_name

 dynamic "cache_usage_limits" {
   for_each = length(var.cache_usage_limits) > 0 ? [var.cache_usage_limits] : []

   content {

     dynamic "data_storage" {
       for_each = try([cache_usage_limits.value.data_storage], [])
       content {
         maximum = try(data_storage.value.maximum, null)
         minimum = try(data_storage.value.minimum, null)
         unit    = try(data_storage.value.unit, "GB")
       }
     }

     dynamic "ecpu_per_second" {
       for_each = try([cache_usage_limits.value.ecpu_per_second], [])
       content {
         maximum = try(ecpu_per_second.value.maximum, null)
         minimum = try(ecpu_per_second.value.minimum, null)
       }
     }
   }
 }

 daily_snapshot_time      = var.daily_snapshot_time
 description              = coalesce(var.description, "Serverless Cache")
 kms_key_id               = var.kms_key_id
 major_engine_version     = var.major_engine_version
 security_group_ids       = var.security_group_ids
 snapshot_arns_to_restore = var.snapshot_arns_to_restore
 snapshot_retention_limit = var.snapshot_retention_limit
 subnet_ids               = var.subnet_ids
 user_group_id            = aws_elasticache_user_group.main.id

 timeouts {
   create = try(var.timeouts.create, "40m")
   delete = try(var.timeouts.delete, "80m")
   update = try(var.timeouts.update, "40m")
 }

 tags = var.tags
}

Шаг 3

Создатьaccess.tfфайл. Здесь мы будем управлять пользователями Elasticach.

resource "random_string" "auth_user_password" {
 for_each = { for k, v in var.access_users : k => v if try(v.generate_password, false) }

 length           = 16
 special          = false
 override_special = "/@£$"
}

#
# Regenerate auth_user / access_u2g_mapping
#
locals {
 access_users = {
   for k, v in var.access_users : k => {
     generated_name = format("%s-%s", var.cache_name, k)
     access_string  = v["access_string"]
     auth_type      = v["auth_type"]
     engine         = v["engine"]
     passwords      = try(v["generate_password"], false) ? [random_string.auth_user_password[k].result] : try(v["passwords"], null)
   }
 }
}

resource "aws_elasticache_user" "main" {
 for_each = local.access_users

 user_id       = each.value["generated_name"]
 user_name     = each.value["generated_name"]
 access_string = each.value["access_string"]
 engine        = each.value["engine"]

 authentication_mode {
   type      = each.value["auth_type"]
   passwords = each.value["passwords"]
 }

 tags = var.tags
}

resource "aws_elasticache_user_group" "main" {
 user_group_id = var.cache_name
 engine        = var.engine

 tags = var.tags

 lifecycle {
   ignore_changes = [user_ids]
 }
}

resource "aws_elasticache_user_group_association" "main" {
 for_each = local.access_users

 user_group_id = aws_elasticache_user_group.main.user_group_id
 user_id       = aws_elasticache_user.main[each.key].user_id

 depends_on = [
   aws_elasticache_user.main,
   aws_elasticache_user_group.main
 ]
}

Обратите внимание: когда вы работаете с AWS Elasticach, без сервера, существует два основных способа доступа и управления вашим кластером:

  • IAM Authentication: Аутентификация соединений с Elasticache для Valkey с использованием AWS IAM Identities. Этот метод улучшает вашу позицию в области безопасности и упрощает административные задачи, особенно при работе в экосистеме AWS.
  • Традиционная аутентификация на основе паролей: У каждого пользователя кэша есть долгоживущий пароль, который используется непосредственно с командой Auth для аутентификации клиентских соединений. Этот метод прост, но требует тщательного управления учетными данными для поддержания безопасности.

Шаг 4

Создатьoutputs.tfфайл. Это файл по умолчанию для выходов модуля Opentofu.

output "arn" {
 description = "The amazon resource name of the serverless cache"
 value       = try(aws_elasticache_serverless_cache.this[0].arn, null)
}

output "create_time" {
 description = "Timestamp of when the serverless cache was created"
 value       = try(aws_elasticache_serverless_cache.this[0].create_time, null)
}

output "endpoint" {
 description = " Represents the information required for client programs to connect to a cache node"
 value       = try(aws_elasticache_serverless_cache.this[0].endpoint, null)
}

output "full_engine_version" {
 description = "The name and version number of the engine the serverless cache is compatible with"
 value       = try(aws_elasticache_serverless_cache.this[0].full_engine_version, null)
}

output "major_engine_version" {
 description = "The version number of the engine the serverless cache is compatible with"
 value       = try(aws_elasticache_serverless_cache.this[0].major_engine_version, null)
}

output "reader_endpoint" {
 description = "Represents the information required for client programs to connect to a cache node"
 value       = try(aws_elasticache_serverless_cache.this[0].reader_endpoint, null)
}

output "status" {
 description = "The current status of the serverless cache. The allowed values are CREATING, AVAILABLE, DELETING, CREATE-FAILED and MODIFYING"
 value       = try(aws_elasticache_serverless_cache.this[0].status, null)
}

output "access_users" {
 value = local.access_users
}

Шаг 5

Создатьvariables.tfфайл. Это файл для переменных модуля Opentofu, где мы предварительно определили некоторые значения по умолчанию.

variable "create" {
 description = "Determines whether serverless resource will be created."
 type        = bool
 default     = true
}

variable "cache_name" {
 description = "The name which serves as a unique identifier to the serverless cache."
 type        = string
 default     = null
}

variable "cache_usage_limits" {
 description = "Sets the cache usage limits for storage and ElastiCache Processing Units for the cache."
 type        = map(any)
 default     = {}
}

variable "daily_snapshot_time" {
 description = "The daily time that snapshots will be created from the new serverless cache. Only supported for engine type `redis`. Defaults to 0."
 type        = string
 default     = null
}

variable "description" {
 description = "User-created description for the serverless cache."
 type        = string
 default     = null
}

variable "engine" {
 description = "Name of the cache engine to be used for this cache cluster. Valid values are `memcached` or `redis`."
 type        = string
 default     = "redis"
}

variable "kms_key_id" {
 description = "ARN of the customer managed key for encrypting the data at rest. If no KMS key is provided, a default service key is used."
 type        = string
 default     = null
}

variable "major_engine_version" {
 description = "The version of the cache engine that will be used to create the serverless cache."
 type        = string
 default     = null
}

variable "security_group_ids" {
 description = "One or more VPC security groups associated with the serverless cache."
 type        = list(string)
 default     = []
}

variable "snapshot_arns_to_restore" {
 description = "The list of ARN(s) of the snapshot that the new serverless cache will be created from. Available for Redis only."
 type        = list(string)
 default     = null
}

variable "snapshot_retention_limit" {
 description = "(Redis only) The number of snapshots that will be retained for the serverless cache that is being created."
 type        = number
 default     = null
}


variable "subnet_ids" {
 description = "A list of the identifiers of the subnets where the VPC endpoint for the serverless cache will be deployed."
 type        = list(string)
 default     = []
}

variable "timeouts" {
 description = "Define maximum timeout for creating, updating, and deleting serverless resources."
 type        = map(string)
 default     = {}
}

variable "tags" {
 description = "A map of tags to add to all resources"
 type        = map(string)
 default     = {}
}

#
# Access
#
variable "access_users" {
 default = {}
}

Шаг 6

Создатьversions.tfфайл. Это файл метаданных с версиями Opentofu и поставщика.

terraform {
 required_version = ">= 1.0"

 required_providers {
   aws = {
     source  = "hashicorp/aws"
     version = ">= 5.77"
   }
 }
}

Вот и все - вы создали свой собственный модуль для управления AWS Elasticach Serverless! Теперь давайте перейдем к созданию зависимой инфраструктуры, которую мы будем использовать это руководство.


Создать зависимую инфраструктуру AWS

Модуль AWS Elasticache недостаточен для нашего руководства; Чтобы использовать кластер, мы должны построить дополнительную инфраструктуру, такую как VPC, Subsets, KMS и группы безопасности. Давайте построим все это вelasticache_guide/main.tfфайл:

module "vpc" {
 source  = "terraform-aws-modules/vpc/aws"
 version = "~> 5.0"

 name = "kvendingoldo-demo-elasticache-serverless"
 cidr = "10.0.0.0/16"

 azs             = ["us-east-1a", "us-east-1b"]
 private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]

 enable_dns_hostnames = true
 enable_dns_support   = true
}

module "security_groups" {
 source  = "terraform-aws-modules/security-group/aws"
 version = "~> 5.0"

 name        = "kvendingoldo-demo-elasticache-serverless"
 description = "Security group for ElastiCache Serverless"
 vpc_id      = module.vpc.vpc_id

 security_group_rules = {
   ingress_self = {
     type        = "ingress"
     from_port   = 6379
     to_port     = 6379
     protocol    = "tcp"
     self        = true
     description = "Allow self-traffic"
   }
   egress_all = {
     type        = "egress"
     from_port   = 0
     to_port     = 0
     protocol    = "-1"
     cidr_blocks = ["0.0.0.0/0"]
     description = "Allow all egress"
   }
 }
}

module "kms_elasticache_serverless" {
 source  = "terraform-aws-modules/kms/aws"
 version = "~> 1.0"

 alias       = "kvendingoldo-demo-elasticache-serverless"
 description = "KMS key for ElastiCache Serverless encryption"

 enable_key_rotation = true
}

module "elasticache_serverless" {
 source = "./modules/elasticache_serverless"

 engine     = "valkey"
 cache_name = "kvendingoldo-demo-elasticache-serverless"

 cache_usage_limits = {
   data_storage = {
     maximum = 2 # 2Gb
   }
   ecpu_per_second = {
     maximum = 2000 # Approximate for 2 vCPUs (1000 per vCPU)
   }
 }

 daily_snapshot_time = "22:00"
 description         = "Valkey serverless cluster for kvendingoldo demo"

 kms_key_id           = module.kms_elasticache_serverless[0].key_arn
 major_engine_version = "7"
 security_group_ids = [
   module.security_groups["elasticache_serverless"].id
 ]
 subnet_ids = module.vpc.private_subnets

 snapshot_retention_limit = 7

 access_users = {
   "admin-iam" = {
     access_string = "on ~* +@all"
     engine        = "valkey"
     auth_type     = "iam"
   }
   "admin-pwd" = {
     access_string     = "on ~* +@all"
     engine            = "valkey"
     auth_type         = "password"
     generate_password = true
   }
 }
}

output "elasticache_serverless_endpoint" {
 value = module.elasticache_serverless.endpoint
}

output "elasticache_serverless_users" {
 value = module.elasticache_serverless.access_users
}

Как видите, этот файл частично использует модули сообщества из Интернета для создания VPC, KMS и группы безопасности. If you like, you can useРодные ресурсы Terraform AWSвместо.


Применить код OpenTofu

Прежде чем применять наши ресурсы AWS, нам нужно инициализировать OpenTofu. На этом этапе Opentofu создаст файл состояния и загрузит всех необходимых поставщиков.

Для этого запустите следующую команду:

$ tofu init

Далее, давайте посмотрим, что Опентофу планирует сделать, создав план выполнения, используя следующую команду:

$ tofu plan

После просмотра плана, наконец, настало время применить нашу конфигурацию, используя следующую команду:

$ tofu apply -auto-approve

После завершения, OpenTofu отобразит подробности предварительному экземпляру Elasticach Valkey.


Подключиться к кластеру

Шаг 1: Получите конечную точку

Как упоминалось ранее, вы увидите детали подключения на выводе OpenTofu. В качестве альтернативы, вы можете получить конечную точку, используя AWS CLI со следующей командой:

$ aws elasticache describe-serverless-caches --query "serverlessCaches[?cacheName=='kvendingoldo-demo-elasticache-serverless'].endpoint"


Шаг 2: Подключите Redis-Cli

Valkey совместим с клиентами Redis. Вы можете использовать предпочтительный клиент для подключения к конечной точке в порте Redis по умолчанию6379Полем В моем случае я используюredis-cli:
$ redis-cli -h <serverless_endpoint> -p 6379 -a <your_password>

Запустите простую команду для подтверждения соединения:
ping

Вы должны получить ответ:

PONG


Очистка ресурсов

После проверки того, что все работает, вы можете разрушить созданные ресурсы, когда они больше не нужны, чтобы избежать ненужных затрат, используя следующую команду:

$ tofu destroy -auto-approve

Это удалит экземпляр Elasticache и все связанные ресурсы.


Заключение

В этом руководстве мы прошли через создание выделенного модуля Opentofu для предоставления AWS Elasticache Server с двигателем Valkey, следуя передовым методам инфраструктуры в качестве кода. Мы покрыли настройку Opentofu, создание многоразовых модулей и подключение к экземпляру Valkey.

Используя Opentofu и Valkey, вы получаете полностью открытое и гибкое решение для управления без сервера к кэшированию AWS, помогая избежать лицензионных ловушек и сохранять контроль над вашей инфраструктурой.

Не стесняйтесь расширять модуль, чтобы соответствовать вашим потребностям и изучить дополнительные возможности автоматизации. Если у вас есть какие -либо вопросы или вы хотите глубже погрузиться в связанные темы, просто дайте мне знать!

Счастливого кэширования!



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE