Terraform AWS Provider 数据源aws_memorydb_cluster完全指南:查询 MemoryDB 集群配置与运行状态
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
aws_memorydb_cluster是 Terraform AWS Provider 提供的只读数据源(Data Source),用于按集群名称拉取 AWS MemoryDB for Valkey(前身 MemoryDB for Redis)集群的完整配置快照与运行信息,包括分片拓扑、节点端点、加密与网络设置、快照策略及标签。本文以该数据源官方文档为主体,结合仓库源码 cluster_data_source.go、cluster.go 与验收测试 cluster_data_source_test.go 深入讲解其参数、全部导出属性与底层读取原理,帮助你安全地在 Terraform 配置中引用已有集群,而不会产生资源变更。
数据源概览:为什么需要只读集群查询
在 Terraform 中,"数据源"用于读取基础设施的既有状态,而不是创建或修改它。aws_memorydb_cluster数据源的核心价值在于:
- 解耦跨模块引用:当集群由其他团队或其他 Terraform 配置创建时,可以直接按名称读取其
arn、cluster_endpoint.address等信息,作为依赖注入给下游资源(如安全组规则、DNS 记录、应用配置)。 - 避免配置漂移:数据源每次执行
terraform plan/apply都会重新调用 AWS API 刷新数据,读取结果实时反映云端实际状态。 - 补充资源属性的"无法直读"项:如
num_replicas_per_shard这类 API 不直接返回的字段,数据源也通过源码中的推导逻辑给出可靠值(详见下文源码解析)。
从仓库实现看,该数据源通过 service_package_gen.go 注册为 SDK 数据源aws_memorydb_cluster(Name 为 "Cluster"),并声明以arn作为标签标识属性。
参数(Argument Reference)
该数据源支持的参数非常简单,仅有 2 个:
| 参数 | 必填 | 说明 |
|---|---|---|
name | 是 | 集群名称。Terraform 调用DescribeClusters时按该名称精确匹配。 |
region | 否 | 集群所属区域。默认为 provider 配置 中设置的区域(即 provider 的region参数)。 |
region参数是 AWS Provider 所有资源/数据源的通用约定:当你需要查询与 provider 默认区域不同的集群时,可在数据源块内显式覆盖,例如region = "eu-west-1",读取操作会在该区域执行。
名称命名约束(来自源码校验)
虽然数据源只读名称,但该名称本身必须遵守 MemoryDB 集群的命名规范。仓库 validate.go 中的校验规则同样适用于你传入的name:
- 长度 1~40 个字符(
clusterNameMaxLength = 40); - 仅允许小写字母、数字与连字符(
^[0-9a-z-]+$); - 不允许连续两个连字符
--; - 不允许以连字符结尾。
基本使用示例
官方文档给出了最简用法——只按名称读取,输出任意所需属性:
data "aws_memorydb_cluster" "example" { name = "my-cluster" } output "cluster_arn" { value = data.aws_memorydb_cluster.example.arn } output "cluster_endpoint" { value = data.aws_memorydb_cluster.example.cluster_endpoint[0].address }完整实战示例:资源创建 + 数据源读取
数据源最常见的用法是与aws_memorydb_cluster资源配对,将创建后的集群反向读取,供其他配置引用。下面组合了仓库测试 cluster_data_source_test.go 中的真实配置骨架(该测试同时创建了 VPC、安全组、KMS 密钥、子网组、ACL 与集群):
# 安全组(运行在测试创建的 VPC 内) resource "aws_security_group" "test" { name = "tf-test-sg" description = "MemoryDB cluster security group" vpc_id = aws_vpc.test.id } # 集群静态加密使用的 KMS 密钥 resource "aws_kms_key" "test" { deletion_window_in_days = 7 enable_key_rotation = true } resource "aws_memorydb_cluster" "test" { acl_name = aws_memorydb_acl.test.id auto_minor_version_upgrade = false kms_key_arn = aws_kms_key.test.arn name = "tf-test-cluster" node_type = "db.t4g.small" num_shards = 2 security_group_ids = [aws_security_group.test.id] snapshot_retention_limit = 7 subnet_group_name = aws_memorydb_subnet_group.test.id tls_enabled = true tags = { Test = "test" } } # 数据源按资源名称反向读取同一集群 data "aws_memorydb_cluster" "test" { name = aws_memorydb_cluster.test.name } output "engine_patch_version" { value = data.aws_memorydb_cluster.test.engine_patch_version }其中aws_memorydb_cluster资源支持的关键参数(详见 资源文档)包括:engine(取值redis或valkey)、engine_version(不支持降级)、port(默认6379)、ip_discovery(默认ipv4,若为ipv6则network_type必须为ipv6或dual_stack)、tls_enabled(默认true,设为false时acl_name必须为open-access)、name_prefix与name二选一、snapshot_arns/snapshot_name用于从备份或 S3 中的 RDB 文件恢复。
属性参考(Attribute Reference)
除参数外,数据源导出以下属性(与资源一致,全部为Computed,见 cluster_data_source.go)。按功能分组如下:
标识与描述
| 属性 | 类型 | 说明 |
|---|---|---|
id | string | 与name相同(源码中d.SetId(aws.ToString(cluster.Name)))。 |
arn | string | 集群的 Amazon 资源名称(ARN)。 |
description | string | 集群描述。 |
网络、安全与加密
| 属性 | 类型 | 说明 |
|---|---|---|
acl_name | string | 与集群关联的访问控制列表(ACL)名称。 |
security_group_ids | set(string) | 与该集群关联的 VPC 安全组 ID 集合。 |
subnet_group_name | string | 集群使用的子网组名称。 |
kms_key_arn | string | 用于集群静态加密的 KMS 密钥 ARN。 |
tls_enabled | bool | 为true表示启用了传输中加密。 |
network_type | string | 集群的 IP 地址类型(ipv4/ipv6/dual_stack)。 |
ip_discovery | string | 集群发现 IP 地址的机制(ipv4/ipv6)。 |
cluster_endpoint | list | 集群配置端点:cluster_endpoint.0.address(DNS 主机名)与cluster_endpoint.0.port(监听端口)。 |
port | int | 每个节点接受连接所使用的端口号。 |
引擎与容量
| 属性 | 类型 | 说明 |
|---|---|---|
engine | string | 运行在集群节点上的引擎(redis或valkey)。 |
engine_version | string | 集群使用的引擎版本号。 |
engine_patch_version | string | 集群使用的引擎补丁版本号。 |
node_type | string | 集群节点的计算与内存容量(如db.t4g.small)。 |
num_shards | int | 集群中的分片(shard)数量。 |
num_replicas_per_shard | int | 每个分片应用的副本数。 |
data_tiering | bool | 为true表示启用了数据分层(data tiering)。 |
auto_minor_version_upgrade | bool | 为true表示集群允许自动进行引擎次要版本升级。 |
parameter_group_name | string | 与集群关联的参数组名称。 |
分片拓扑(shards)
shards是一个以分片name为集合键的 set,每个分片包含:
| 属性 | 说明 |
|---|---|
shards.*.name | 分片名称。 |
shards.*.num_nodes | 该分片内的节点数。 |
shards.*.slots | 该分片的 keyspace,例如0-16383。 |
shards.*.nodes | 该分片内的节点集合,每个节点包含:availability_zone(节点所在可用区)、create_time(创建时间,如2022-01-01T21:00:00Z)、name(节点名)、endpoint(节点端点,含address与port)。 |
快照与通知
| 属性 | 类型 | 说明 |
|---|---|---|
snapshot_retention_limit | int | MemoryDB 在删除自动快照前保留的天数;为0时自动备份被禁用。 |
snapshot_window | string | 每日 UTC 快照时间窗,例如05:00-09:00。 |
final_snapshot_name | string | 资源删除时创建的最终快照名称(省略则不创建最终快照)。 |
sns_topic_arn | string | 接收集群通知的 SNS 主题 ARN。 |
maintenance_window | string | 每周维护时间窗,格式为ddd:hh24:mi-ddd:hh24:mi(24 小时制 UTC),例如sun:23:00-mon:01:30,最小维护窗口为 60 分钟。 |
标签
| 属性 | 类型 | 说明 |
|---|---|---|
tags | map(string) | 分配给集群的标签映射。 |
源码级实现解析:数据源如何工作
读取调用链
数据源的读取入口是dataSourceClusterRead(cluster_data_source.go),其核心流程为:
- 从 provider 上下文中获取 MemoryDB SDK v2 客户端:
conn := meta.(*conns.AWSClient).MemoryDBClient(ctx); - 读取
name参数,调用findClusterByName; - 内部构造
DescribeClustersInput{ClusterName, ShowShardDetails: true}(cluster.go),ShowShardDetails: true保证返回完整的分片与节点拓扑——这正是shards.*.nodes.*属性有数据的来源; - 通过
DescribeClusters分页器遍历所有页(findClusters),并对结果调用tfresource.AssertSingleValueResult——如果按名称匹配到 0 个或多个集群,读取会直接报错,确保数据源结果的唯一确定性; - 集群不存在时,错误会被包装为
SingularDataSourceFindError("MemoryDB Cluster", err),在 plan 阶段即可暴露"集群不存在"的清晰错误。
几个易被忽视的数据转换细节
源码中有多处值得注意的"API 行为修正",理解它们有助于正确解读数据源输出:
id即name:数据源把集群名称直接设为资源 ID(d.SetId(aws.ToString(cluster.Name))),与文档"id- Same asname"一致。data_tiering是字符串转布尔:MemoryDB API 返回的DataTiering是字符串("true"/"false"),源码用strconv.ParseBool转换后才写入d.Set("data_tiering", v),若转换失败会返回错误诊断。kms_key_arn的字段名陷阱:API 字段名为KmsKeyId,但实际返回的是 ARN。源码明确注释// KmsKeyId is actually an ARN here.,直接写入kms_key_arn,这正是文档将该属性命名为kms_key_arn而非kms_key_id的原因。sns_topic_arn有条件导出:只有SnsTopicStatus == "ACTIVE"(常量clusterSNSTopicStatusActive,见 enum.go)时才会设置sns_topic_arn,否则置为空字符串——避免把处于解除过程中的 SNS 关联误报为有效值。num_replicas_per_shard无法直读,采用推导:API 不直接返回副本数。deriveClusterNumReplicasPerShard(cluster.go)遍历所有分片,只在分片状态为available时统计节点数,取最大分片的NumberOfNodes - 1作为副本数。注释说明这是"保守起见,限定在稳定分片上"的推导策略。security_group_ids扁平化:API 返回的SecurityGroups是SecurityGroupMembership列表(含 ID 与状态),源码用tfslices.ApplyToAll只提取SecurityGroupId生成 set。
分片与节点的集合结构
shards与nodes在 schema 中都是TypeSet,并分别以分片名、节点名作为 hash 键(clusterShardHash/clusterShardNodeHash,见 cluster.go)。扁平化逻辑flattenShards(cluster.go)将每个分片转换为{name, num_nodes, slots, nodes},每个节点转换为{availability_zone, create_time(RFC3339 格式), endpoint{address, port}, name}。
因此,在 HCL 中遍历分片和节点非常方便:
output "node_addresses" { value = [ for shard in data.aws_memorydb_cluster.example.shards : [for node in shard.nodes : node.endpoint[0].address] ] }数据源与资源的关系
数据源与aws_memorydb_cluster资源共用同一套 find/flatten/wait 基础设施:资源的resourceClusterRead与数据源的dataSourceClusterRead读路径几乎一致(cluster.go),区别在于资源在集群不存在时会从 state 中移除(d.SetId("")),而数据源直接报错。两者都依赖waitClusterAvailable等状态机等待集群进入available状态(enum.go 中定义了creating/updating/snapshotting/available/deleting等集群状态)。
关联数据源
MemoryDB 服务包还提供了其他配套数据源,均注册在 service_package_gen.go 中,可以组合使用:
- aws_memorydb_acl 数据源(
acl.go/acl_data_source.go):按名称读取 ACL、minimum_engine_version与用户列表; aws_memorydb_parameter_group、aws_memorydb_subnet_group、aws_memorydb_snapshot、aws_memorydb_user数据源:分别读取参数组、子网组、快照与用户信息。
例如,要同时获取集群及其 ACL 信息:
data "aws_memorydb_cluster" "example" { name = "my-cluster" } data "aws_memorydb_acl" "example" { name = data.aws_memorydb_cluster.example.acl_name }验收测试如何保障数据源行为
仓库中的 cluster_data_source_test.go 用TestAccMemoryDBClusterDataSource_basic对数据源做了完整的端到端验证:它先创建包含 2 个分片(num_shards = 2)、KMS 加密、安全组、标签(Test = "test")的集群,再用数据源按名称读取,并通过resource.TestCheckResourceAttrPair逐一断言数据源每个属性与资源属性完全一致,覆盖acl_name、arn、cluster_endpoint.0.address/.port、data_tiering、engine、engine_version、ip_discovery、maintenance_window、node_type、num_shards、shards.#(断言为 2)及shards.0.nodes.#(断言为 2)等全部字段,甚至精确校验了security_group_ids.#、tags.Test与tls_enabled。
这意味着:凡是在该测试中通过的属性,都保证与aws_memorydb_cluster资源的状态写入一致,你可以放心用数据源做资源配置漂移校验——例如在 CI 中对比资源定义与数据源读取结果。
使用注意事项与最佳实践
region覆盖只影响本次读取:若集群不在 provider 默认区域,务必在数据源内显式指定region,否则会因集群不存在而报SingularDataSourceFindError类错误。- 名称必须完全匹配:数据源按精确名称查找,且 MemoryDB 对名称大小写敏感;传入错误名称会在 plan 阶段直接失败,这是数据源相对于资源(会自行创建)的一大差异。
- 只读不产生变更:数据源不会出现在
terraform apply的变更计划中,适合承载"仅消费、不管理"的集群信息;若要管理生命周期,请使用 aws_memorydb_cluster 资源。 cluster_endpoint与port是配套读取的:源码中只有ClusterEndpoint非空时才会同时写入cluster_endpoint与顶层port,两者总是保持一致。- 分片集合无稳定顺序:
shards/nodes是TypeSet,遍历结果顺序不定,编写for表达式或引用shards.0时不要依赖顺序,建议按name或对全部元素做聚合处理。
小结
aws_memorydb_cluster数据源以极简的参数面(name+ 可选region)提供了覆盖集群全维度运行信息的只读视图,从 ARN、端点、分片节点拓扑到快照、维护窗口、标签一应俱全。其实现深度依赖 MemoryDBDescribeClusters接口(含ShowShardDetails),并通过多处源码级修正(如字符串布尔转换、num_replicas_per_shard推导、SNS 状态过滤)保证了输出与 Terraform 资源语义的一致性。若你需要进一步了解集群的创建、管理与导入细节,可继续阅读 cluster.go 与 资源文档。
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考