terraform-provider-aws 的 aws_redshift_cluster 数据源:完整参考与源码级解读
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
aws_redshift_cluster是 terraform-provider-aws 提供的一个 Redshift 数据源,用于按集群标识符(cluster identifier)读取现有 Amazon Redshift 集群的完整配置信息,供其他资源或输出引用。本文以该数据源的官方文档为骨架,结合仓库源码(cluster_data_source.go)与测试用例(cluster_data_source_test.go)深入讲解其参数、返回属性、底层读取逻辑及典型实战场景,帮助你在 Terraform 中安全、精确地复用既有 Redshift 集群。
数据源概览与核心用途
在 Terraform 中,数据源(Data Source)用于读取而非管理外部已存在的资源。aws_redshift_cluster数据源的作用是:根据cluster_identifier查询一个已经存在的 Redshift 集群,并把集群的端点、端口、数据库名、节点信息、加密状态、日志配置等几十项属性暴露给配置使用。
典型场景包括:
- 把既有集群的
endpoint与database_name拼装成 JDBC 连接串,供 Kinesis Firehose、ETL 任务等下游消费; - 读取集群安全组、VPC、子网组等信息,用于搭建跨资源依赖;
- 在仅读权限的工作流中获取集群元数据,避免重复定义集群资源。
从源码看,该数据源在仓库中定义于 internal/service/redshift/cluster_data_source.go,通过@SDKDataSource("aws_redshift_cluster", name="Cluster")注解注册,走的是 SDK v2 风格的schema.Resource,并标注了@Tags,即同时支持读取集群上的标签(详见后文)。
参数(Argument Reference)
该数据源仅支持两个参数:
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
cluster_identifier | string | 必填 | 要查询的 Redshift 集群标识符 |
region | string | 可选 | 集群所在区域;默认为 provider 配置中设置的 Region |
其中region是一个全局通用的可选参数,允许你在单个 provider 配置下跨区域读取集群。cluster_identifier是查询的唯一主键,在源码 cluster_data_source.go 中被定义为Required,其余全部属性均为Computed(只读输出),这一点与数据源"只读"的语义一致。
底层读取链路(源码级)
理解数据源行为的关键在于它的 Read 实现。整体调用链如下:
- 数据源 Read 入口:
dataSourceClusterRead(cluster_data_source.go)先从meta中取出 AWS 客户端,再通过c.RedshiftClient(ctx)获取 Redshift API 客户端; - 按 ID 查找集群:调用
findClusterByID(find.go),它构造DescribeClustersInput{ClusterIdentifier: ...},通过DescribeClustersAPI 分页查询后,再用tfresource.AssertSingleValueResult断言结果唯一;随后还会做一次最终一致性校验——当返回的ClusterIdentifier与请求 ID 不一致时,返回retry.NotFoundError,从而避免读到刚创建、尚未完全可见的集群; - 错误处理:若集群不存在或查询失败,返回形如
reading Redshift Cluster (<id>)的 diag 错误(对应 cluster_data_source.go); - 写入 State:将 API 返回的
awstypes.Cluster各字段逐一映射到 Terraform 属性,并以cluster_identifier作为资源 ID(d.SetId(clusterID)); - 额外日志查询:集群基本信息读取完成后,还会额外调用一次
DescribeLoggingStatus(cluster_data_source.go),用来填充bucket_name、enable_logging、log_destination_type、log_exports、s3_key_prefix这组日志相关属性。
值得注意的是,一次数据源读取实际上包含两次 AWS API 调用(DescribeClusters+DescribeLoggingStatus),这保证了日志字段的实时准确性。
返回属性(Attribute Reference)全解
数据源导出以下属性(除region、cluster_identifier参数本身外均为计算值)。按功能归类说明如下。
身份与网络信息
| 属性 | 说明 |
|---|---|
arn | 集群的 ARN,由 clusterARN 通过RegionalARN(ctx, names.Redshift, "cluster:"+id)拼装为区域级 ARN |
cluster_identifier | 集群标识符 |
cluster_namespace_arn | 集群的命名空间 ARN |
endpoint | 集群端点地址(来自rsc.Endpoint.Address) |
port | 集群监听端口(来自rsc.Endpoint.Port) |
vpc_id | 集群所在的 VPC ID |
vpc_security_group_ids | 集群关联的 VPC 安全组 ID 列表 |
availability_zone | 集群所在可用区 |
availability_zone_relocation_enabled | 集群是否支持跨可用区搬迁(布尔值) |
elastic_ip | 集群的弹性 IP |
publicly_accessible | 集群是否可公开访问 |
enhanced_vpc_routing | 是否启用增强型 VPC 路由 |
multi_az | 集群是否为 Multi-AZ 部署(布尔值) |
其中两个布尔属性值得注意:availability_zone_relocation_enabled和multi_az在 AWS API 中实际以字符串("enabled"/"disabled")返回,但 Provider 为了与其余参数保持类型一致,在 cluster.go 中通过clusterAvailabilityZoneRelocationStatus和clusterMultiAZStatus两个辅助函数将其转换为布尔值;若 API 返回了未预期的值(如"pending"),会直接报错提示unexpected ... value。这也是源码注释中明确说明的 API 差异处理。
节点与规格信息
| 属性 | 说明 |
|---|---|
node_type | 集群节点类型(如ra3.large、ra3.xlplus) |
number_of_nodes | 集群节点数量 |
cluster_type | 集群类型,值为single-node或multi-node |
cluster_nodes | 集群节点详情列表,块结构见下文 |
cluster_type并非直接从 API 读取,而是由 dataSourceClusterRead 根据ClusterNodes数量推断:节点数大于 1 时为multi-node,否则为single-node。对应常量定义在 consts.go。
cluster_nodes 子块属性:
| 属性 | 说明 |
|---|---|
node_role | 节点角色,标识是 leader(leader node)还是 compute node(计算节点) |
private_ip_address | 节点在集群内的私有 IP |
public_ip_address | 节点的公有 IP(仅公有节点有值) |
节点扁平化由 flattenClusterNodes 完成,它会遍历 API 返回的每个ClusterNode并逐一映射字段;列表为空时返回nil。
数据库与账号信息
| 属性 | 说明 |
|---|---|
database_name | 集群默认数据库名 |
master_username | 主数据库用户(master DB user)用户名 |
cluster_parameter_group_name | 集群关联的参数组名称(取ClusterParameterGroups列表首个元素,见 cluster_data_source.go) |
cluster_subnet_group_name | 集群关联的子网组名称 |
cluster_public_key | 集群公钥 |
cluster_revision_number | 集群修订号 |
cluster_version | 集群版本(源码额外导出的计算属性,文档未单列) |
maintenance_track_name | 集群维护轨道名称 |
preferred_maintenance_window | 首选维护窗口 |
快照、升级与加密
| 属性 | 说明 |
|---|---|
allow_version_upgrade | 是否允许在维护期内进行大版本升级 |
automated_snapshot_retention_period | 自动快照保留天数(备份保留周期) |
manual_snapshot_retention_period | 手动快照默认保留天数 |
encrypted | 集群数据是否加密 |
kms_key_id | 集群使用的 KMS 加密密钥 ID |
default_iam_role_arn | 创建集群时设为默认的 IAM 角色 ARN |
iam_roles | 与集群关联的 IAM 角色 ARN 列表(来自rsc.IamRoles,经tfslices.ApplyToAll提取 ARN) |
日志与标签
| 属性 | 说明 |
|---|---|
enable_logging | 集群日志记录是否启用 |
bucket_name | 日志存储的 S3 桶名称 |
s3_key_prefix | S3 桶内日志文件夹前缀 |
log_destination_type | 日志目标类型(如 S3 或 CloudWatch) |
log_exports | 导出的日志类型集合(连接日志、用户日志、用户活动日志等) |
aqua_configuration_status | 集群使用 AQUA(Advanced Query Accelerator)的配置状态 |
tags | 集群上的标签映射 |
日志相关字段均来自数据源 Read 阶段追加的DescribeLoggingStatus调用(cluster_data_source.go),仅当日志开启(LoggingEnabled为 true)时才回填这些字段。
实战示例:Kinesis Firehose 引用集群端点
官方文档给出的示例展示了最典型的数据源用法——用aws_redshift_cluster数据源驱动 Kinesis Firehose 的 Redshift 投递配置:
data "aws_redshift_cluster" "example" { cluster_identifier = "example-cluster" } resource "aws_kinesis_firehose_delivery_stream" "example_stream" { name = "terraform-kinesis-firehose-example-stream" destination = "redshift" redshift_configuration { role_arn = aws_iam_role.firehose_role.arn cluster_jdbcurl = "jdbc:redshift://${data.aws_redshift_cluster.example.endpoint}/${data.aws_redshift_cluster.example.database_name}" username = "exampleuser" password = "Exampl3Pass" data_table_name = "example-table" copy_options = "delimiter '|'" # the default delimiter data_table_columns = "example-col" s3_configuration { role_arn = aws_iam_role.firehose_role.arn bucket_arn = aws_s3_bucket.bucket.arn buffer_size = 10 buffer_interval = 400 compression_format = "GZIP" } } }关键点解析:
cluster_jdbcurl通过插值语法拼接endpoint与database_name,动态生成形如jdbc:redshift://<endpoint>/<database>的 JDBC 连接串,无需在配置中硬编码地址;- Firehose 的 Redshift 目的地依赖 S3 作为中转(
s3_configuration必填),缓冲参数buffer_size(MB)与buffer_interval(秒)用于控制写入频率,compression_format可设为GZIP等格式; - 该配置还依赖
aws_iam_role.firehose_role与aws_s3_bucket.bucket两个资源,需要为 Firehose 授予对 S3 桶与 Redshift 集群的写入权限。
更多实战片段:从测试用例提炼可复用配置
仓库的验收测试 cluster_data_source_test.go 提供了多组可直接借鉴的配置模式,覆盖了数据源在不同集群形态下的读取行为。
基础单节点集群(对应TestAccRedshiftClusterDataSource_basic):
resource "aws_redshift_cluster" "test" { cluster_identifier = "example-cluster" database_name = "testdb" master_username = "foo" master_password = "Password1" node_type = "ra3.large" cluster_type = "single-node" skip_final_snapshot = true } data "aws_redshift_cluster" "test" { cluster_identifier = aws_redshift_cluster.test.cluster_identifier }该用例断言了cluster_type为single-node、cluster_nodes.#为1、arn符合区域 ARN 格式(redshift:cluster:{id})等多项输出,并验证数据源与资源之间标签数量一致。
VPC 内多节点集群(对应TestAccRedshiftClusterDataSource_vpc):集群置于子网组中,cluster_type为multi-node、number_of_nodes为 2,数据源可正确返回vpc_id、vpc_security_group_ids(数量为 1)与cluster_subnet_group_name。
日志配置联动(对应TestAccRedshiftClusterDataSource_logging):先创建 S3 桶及允许redshift.amazonaws.com服务主体s3:PutObject、s3:GetBucketAcl的桶策略,再通过aws_redshift_logging资源开启日志(s3_key_prefix = "cluster-logging/"),最后用数据源读取,断言enable_logging为 true、bucket_name与桶资源一致、s3_key_prefix与日志资源一致。注意此时数据源必须通过depends_on = [aws_redshift_logging.test]显式等待日志开启后再读取。
Multi-AZ 集群(对应TestAccRedshiftClusterDataSource_multiAZEnabled):集群配置multi_az = true并搭配encrypted = true与kms_key_id(使用自定义 KMS 密钥),数据源的multi_az属性与资源保持一致。测试还覆盖了availability_zone_relocation_enabled(cluster_data_source_test.go)在单节点集群上开启的读取场景。
与相关数据源/资源的关系
在 terraform-provider-aws 的 Redshift 模块(internal/service/redshift)中,集群数据源与以下对象协同工作:
- aws_redshift_cluster 资源:数据源读取的就是该资源管理的集群;资源负责创建、更新、删除,数据源负责只读查询;
- aws_redshift_cluster_credentials 数据源:用于获取临时数据库凭证,常与集群数据源搭配使用;
- aws_redshift_subnet_group 数据源:读取子网组信息,
cluster_subnet_group_name属性与之对应; - aws_redshift_logging 资源:管理集群日志记录,数据源中的日志字段(
bucket_name、s3_key_prefix等)即来自该资源所配置的日志状态。
其他相关数据源还包括 aws_redshift_orderable_cluster(查询可订购的集群规格)、aws_redshift_data_shares(列出数据共享)等,均可在 website/docs/d 目录中查阅。
小结
aws_redshift_cluster数据源通过一次DescribeClusters查询加一次DescribeLoggingStatus查询,把 Redshift 集群的端点、端口、数据库名、节点拓扑、加密与快照策略、日志配置、标签等完整信息暴露给 Terraform 配置。无论你是要将既有集群接入 Firehose 投递管道,还是在多集群、跨区域环境中编排依赖,都可以用它安全地读取集群元数据,而无需重新管理集群本身。结合仓库源码(cluster_data_source.go)与验收测试(cluster_data_source_test.go),你可以进一步理解每个属性的底层取值逻辑与 API 差异处理,从而在复杂生产环境中写出可预测、可维护的配置。
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考