使用 terraform-provider-aws 端到端编排 AWS Resilience Hub V2:策略、系统、服务与输入源全资源实战
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
AWS Resilience Hub 是 AWS 提供的韧性(Resilience)评估与管理服务,用于定义可用性目标、评估应用架构的容灾能力并持续跟踪改进。Resilience Hub V2(下一代 Resilience Hub)在原有模型之上引入了 Policy(策略)、System(系统)、Service(服务)、User Journey(用户旅程)、Service Function(服务功能)与 Input Source(输入源)等更细粒度的分层建模方式。本指南以 examples/resiliencehubv2/README.md 为骨架,结合 examples/resiliencehubv2/main.tf 完整示例与internal/service/resiliencehubv2目录下的源码实现,讲解如何用 terraform-provider-aws 一次性编排完整、可复用的 Resilience Hub V2 落地配置,读完即可照着复制并运行属于自己的韧性评估环境。
一、示例全景:六类资源如何组合成完整韧性体系
该示例的目标是"像真实客户那样端到端组合"一套 Resilience Hub V2 配置,共涉及六个资源:
| 资源类型 | 在示例中的角色 |
|---|---|
aws_resiliencehubv2_policy | 可复用的韧性策略,定义可用性 SLO(Availability SLO)与多可用区容灾目标 |
aws_resiliencehubv2_system | 顶层系统分组,用于将服务归类组织 |
aws_resiliencehubv2_service | 按上述策略接受评估的服务 |
aws_resiliencehubv2_user_journey | 系统内关键端到端用户旅程 |
aws_resiliencehubv2_service_function | 服务内技术工作流的子集 |
aws_resiliencehubv2_input_source | 从 CloudFormation 栈发现资源的输入源 |
从源码看,这六类资源全部由 internal/service/resiliencehubv2/service_package_gen.go 注册到 Provider 的 FrameworkResources 中,此外该服务包还提供aws_resiliencehubv2_policy、aws_resiliencehubv2_service、aws_resiliencehubv2_system三个数据源,以及aws_resiliencehubv2_assertion断言资源,说明该模块已具备完整的"建模—评估—断言"闭环能力。
二、完整示例配置逐段拆解
下面是 examples/resiliencehubv2/main.tf 的完整内容,它同时声明了 Terraform 版本约束、AWS Provider 区域以及上述六个资源,我们按区块逐段讲解。
2.1 Provider 与版本声明
terraform { required_version = ">= 0.12" } provider "aws" { region = "us-west-2" } data "aws_region" "current" {}required_version = ">= 0.12":示例保持对 Terraform 0.12 及更高版本的兼容;实际生产环境建议使用当前稳定版 Terraform 与最新版 AWS Provider。region = "us-west-2":指定默认区域。Resilience Hub V2 的资源在 service_package_gen.go 中均通过inttypes.ResourceRegionDefault()注册为"默认区域资源",即跟随 Provider 配置的区域。data "aws_region" "current" {}:读取当前区域名,随后用于aws_resiliencehubv2_service的regions字段,保证服务评估区域与 Provider 区域一致。
2.2 策略资源:定义可用性 SLO 与容灾目标
# A reusable resilience policy defining availability SLO and DR targets. resource "aws_resiliencehubv2_policy" "example" { name = "terraform-example-policy" availability_slo { target = 99.9 } multi_az { disaster_recovery_approach = "ACTIVE_ACTIVE" rpo_in_minutes = 5 rto_in_minutes = 10 } }结合 internal/service/resiliencehubv2/policy.go 的 Schema 实现,该资源的关键约束如下:
name(必填):必须匹配^[A-Za-z0-9][A-Za-z0-9_\-]{1,59}$,即 2~60 个字符、以字母或数字开头,仅允许字母、数字、连字符和下划线;且name与kms_key_id都带RequiresReplace(),修改会触发重建。availability_slo.target(必填):Float 类型,取值范围0~100,表示可用性百分比(示例中的99.9即 99.9%)。availability_slo块最多 1 个。multi_az(可选,最多 1 个):disaster_recovery_approach(必填):枚举类型,示例使用ACTIVE_ACTIVE;rpo_in_minutes(可选):恢复点目标(Recovery Point Objective),整数且>= 0;rto_in_minutes(可选):恢复时间目标(Recovery Time Objective),整数且>= 0。
- 除示例用到的两个块外,源码还支持
data_recovery(time_between_backups_in_minutes,整数>= 0)与multi_region(结构与multi_az相同,但disaster_recovery_approach为多区域枚举)两个可选块。 - 通过
listvalidator.AtLeastOneOf校验:availability_slo、data_recovery、multi_az、multi_region四者至少要配置其中一个,保证策略一定包含某种韧性目标。 - 顶层还支持
description(长度 0~615)、kms_key_id(ARN,指定即强制使用客户托管 KMS 密钥)、tags与tags_all。
在生命周期实现上,Create 阶段会调用CreatePolicy并补充ClientToken(由create.UniqueId生成)与Tags;Update 阶段存在一个值得注意的细节:当某个列表块从有值变为空时,源码通过fwplanmodifiers.ListEmptied显式发送空结构体(如&awstypes.AvailabilitySlo{})而不是省略字段,确保服务端能正确"清空"目标(policy.go)。
2.3 系统资源:顶层分组
# A top-level system that groups services together. resource "aws_resiliencehubv2_system" "example" { name = "terraform-example-system" description = "Example Resilience Hub system" }internal/service/resiliencehubv2/system.go 显示该系统资源属性精简:
name(必填):同样适用 2~60 字符的资源名校验,且RequiresReplace。description(可选):长度 0~615。kms_key_id(可选,ARN,RequiresReplace)。sharing_enabled(可选):布尔值,是否允许与其他账户共享该系统。- 计算属性:
organization_id、ou_id(所属 AWS Organizations 组织/OU)、system_id(系统 ID)与arn。
示例只声明了名称与描述,其余均为可选或由服务端回填,适合作为最轻量的分组起点。
2.4 服务资源:接受策略评估的核心实体
# A service assessed against the policy above. resource "aws_resiliencehubv2_service" "example" { name = "terraform-example-service" regions = [data.aws_region.current.name] policy_arn = aws_resiliencehubv2_policy.example.arn permission_model { invoker_role_name = "AWSResilienceHubAssessmentRole" } }internal/service/resiliencehubv2/service.go 是六类资源中属性最丰富的一个:
name(必填):2~60 字符校验,RequiresReplace。regions(必填):字符串集合,校验SizeBetween(1, 5)且每个值必须是合法 AWS 区域名。示例通过data.aws_region.current.name引用当前区域。policy_arn(可选):要绑定的策略 ARN,示例用aws_resiliencehubv2_policy.example.arn建立资源间依赖,Terraform 会自动保证先创建策略再创建服务。permission_model(必填,且恰 1 个):invoker_role_name(必填):承担评估调用角色的 IAM 角色名。示例 README 特别强调:该角色必须在apply之前存在于账户中,即AWSResilienceHubAssessmentRole。cross_account_role(可选,0~5 个):跨账户角色块,包含cross_account_role_arn(必填,ARN)与external_id(可选,外部 ID),用于跨账户评估场景。
dependency_discovery(可选):依赖发现模式枚举,Computed,创建后由服务端回填(Read 阶段会根据svc.DependencyDiscovery.Status映射为Enabled/Disabled,见 service.go)。associated_system(可选,0~20 个):关联系统块,包含system_arn(必填)与user_journey_ids(可选,1~20 个),用于把服务挂到系统下并关联特定用户旅程。注意 service.go 中有一条重要注释:UpdateService会把省略的associated_system视为"不变化",因此要删除最后一个关联块时,Provider 会显式发送空列表[]awstypes.AssociatedSystem{}才能生效。- 此外支持
description(0~615)、kms_key_id(ARN,RequiresReplace)、tags/tags_all。
创建与更新时,Provider 对CreateService/UpdateService使用tfresource.RetryWhenIsAErrorMessageContains重试,匹配ValidationException且错误信息包含"Ensure the role exists and its trust policy allows access",重试窗口为propagationTimeout(2 分钟,定义在 consts.go),用于容忍 IAM 角色刚创建后尚未传播完成的场景。
2.5 用户旅程资源:关键端到端路径
# A critical user journey within the system. resource "aws_resiliencehubv2_user_journey" "example" { name = "terraform-example-journey" system_arn = aws_resiliencehubv2_system.example.arn }用户旅程代表系统内一条关键端到端用户路径。依据 internal/service/resiliencehubv2/user_journey.go:
name(必填):2~60 字符校验。system_arn(必填):所属系统的 ARN,RequiresReplace,示例引用aws_resiliencehubv2_system.example.arn,Terraform 自动保证系统先于旅程创建。policy_arn(可选):可单独为该旅程覆盖策略。description(可选):长度 0~500。- 计算属性:
user_journey_id。
身份标识为system_arn + user_journey_id二元组:Read/Delete 都通过GetUserJourney/DeleteUserJourney以两个字段联合定位;导入时使用userJourneyImportID.Parse将system_arn/user_journey_id形式的分隔 ID 解析回两个字段(user_journey.go)。
2.6 服务功能资源:服务内的技术工作流
# A technical workflow subset of the service. resource "aws_resiliencehubv2_service_function" "example" { name = "terraform-example-function" service_arn = aws_resiliencehubv2_service.example.arn criticality = "PRIMARY" }服务功能是服务内部更细粒度的技术工作流。依据 internal/service/resiliencehubv2/service_function.go:
name(必填):2~60 字符校验。service_arn(必填):所属服务的 ARN,RequiresReplace。criticality(必填):枚举类型ServiceFunctionCriticality,示例使用PRIMARY(主功能),用于标记该功能在业务中的重要程度。description(可选):长度 0~500。- 计算属性:
service_function_id。
同样以service_arn + service_function_id为二元身份,导入 ID 格式为service_arn/service_function_id。
2.7 输入源资源:从 CloudFormation 栈发现资源
# A CloudFormation stack used as a resource-discovery input source. resource "aws_cloudformation_stack" "example" { name = "terraform-example-stack" template_body = jsonencode({ AWSTemplateFormatVersion = "2010-09-09" Description = "Example stack for Resilience Hub input source" Resources = { WaitHandle = { Type = "AWS::CloudFormation::WaitConditionHandle" } } }) } # An input source that discovers resources from the CloudFormation stack. resource "aws_resiliencehubv2_input_source" "example" { service_arn = aws_resiliencehubv2_service.example.arn resource_configuration { cfn_stack_arn = aws_cloudformation_stack.example.id } }输入源用于向服务注入待评估的"真实资源清单"。示例先创建一个仅含WaitConditionHandle的最小 CloudFormation 栈(template_body内联 JSON),再把栈 ARN 作为输入源。
internal/service/resiliencehubv2/input_source.go 显示该资源支持五种互斥的资源发现方式(tfobjectvalidator.ExactlyOneOfChildren强制只能选一种):
| 方式 | 字段/块 | 适用场景 |
|---|---|---|
| CloudFormation 栈 | resource_configuration.cfn_stack_arn | 从 CFN 栈发现资源(示例所用) |
| 设计文件 | resource_configuration.design_file_s3_url | 从 S3 上的架构设计文件导入 |
| EKS 集群 | resource_configuration.eks(含cluster_arn必填、namespaces必填 1~10 个、每个名称 1~63 字符) | 从 EKS 指定命名空间发现资源 |
| 资源标签 | resource_configuration.resource_tag(key1~128 字符,values0~10 个、每个 0~256 字符) | 按标签批量圈定资源 |
| Terraform 状态 | resource_configuration.tf_state_file_url | 从 Terraform 状态文件导入资源 |
关键生命周期细节:
- 这是一个"创建后不可更新"的资源:
inputSourceResource内嵌framework.WithNoUpdate,service_arn与整个resource_configuration均带RequiresReplace,任何变更都会重建输入源。 service_arn(必填)+input_source_id(计算)构成二元身份,导入 ID 为service_arn/input_source_id(input_source.go)。- Create 使用
tfresource.RetryWhenIsAErrorMessageContains重试AccessDeniedException,错误信息匹配"The invoker role does not have access to",同样是 2 分钟传播窗口——这正是 README 提示"评估角色必须预先存在"的底层原因之一。 - Read 阶段依据
is.Type枚举(CfnStack、DesignFile、Eks、Tags、Terraform)反填对应的resource_configuration子字段(input_source.go)。
三、运行示例的完整流程
在包含上述配置文件的目录中依次执行:
terraform init terraform plan terraform applyterraform init:初始化工作目录并下载 AWS Provider。terraform plan:生成执行计划,重点确认六个资源与 CloudFormation 栈的创建顺序(Terraform 会依据policy_arn、system_arn、service_arn等引用自动拓扑排序)。terraform apply:按依赖顺序创建资源;如提示确认则输入yes。
前置条件:评估角色必须预先存在
README 明确指出:aws_resiliencehubv2_service的permission_model.invoker_role_name引用的AWSResilienceHubAssessmentRoleIAM 角色必须在apply之前已经存在于账户中,否则服务创建或输入源接入时会触发ValidationException("Ensure the role exists and its trust policy allows access")或AccessDeniedException("The invoker role does not have access to")。Provider 虽然会针对这两类错误做最多 2 分钟的传播重试,但角色本身缺失时重试最终仍会失败。因此建议先通过 IAM 资源(或控制台)创建该角色并配置好信任策略,再执行本示例。
验证与清理
- 验证:
terraform state list查看已管理的资源,或terraform show查看各资源回填的arn、system_id、user_journey_id、service_function_id、input_source_id等计算属性。 - 清理:执行
terraform destroy会按依赖逆序删除输入源、服务功能、用户旅程、服务、系统、策略以及 CloudFormation 栈。
四、源码级要点小结
综合 internal/service/resiliencehubv2 目录下的实现,使用该示例时有四个值得关注的工程细节:
- 命名校验统一:
validResourceName定义在 policy.go,规则为^[A-Za-z0-9][A-Za-z0-9_\-]{1,59}$,被 policy、system、service、user_journey、service_function 五个资源复用,命名不规范会在plan阶段即被拦截。 - 传播延迟容错:
propagationTimeout = 2 * time.Minute(consts.go)配合tfresource.RetryWhenIsAErrorMessageContains,专门处理 IAM 角色/跨账户授权刚生效时的临时性错误,生产环境编排角色资源时不必额外手写depends_on睡眠。 - 列表块清空语义:policy 的 SLO/DR 目标块与 service 的
associated_system在"从有到无"时,Provider 会显式发送空结构体或空列表,避免"未传参"被服务端误解为"不修改"。 - 身份与导入:user_journey、service_function、input_source 都是"父 ARN + 子 ID"的二元身份资源,导入时统一使用
父ARN/子ID的分隔格式;policy、service、system 则直接以 ARN 为身份并可整体导入。
五、进一步探索
- 完整示例配置:examples/resiliencehubv2/main.tf
- 示例说明文档:examples/resiliencehubv2/README.md
- 服务包注册与数据源/资源清单:internal/service/resiliencehubv2/service_package_gen.go
- 各资源源码:policy.go、system.go、service.go、user_journey.go、service_function.go、input_source.go
- 资源级文档:
website/docs/r/resiliencehubv2_policy.html.markdown、website/docs/r/resiliencehubv2_service.html.markdown、website/docs/r/resiliencehubv2_input_source.html.markdown等(位于 website/docs/r 目录)
通过上述六类资源,你可以在 Terraform 中完整复刻"策略 → 系统 → 服务 → 用户旅程 → 服务功能 → 输入源"的 Resilience Hub V2 建模链路,并借助 Provider 内置的校验、传播重试与导入能力,把韧性治理纳入基础设施即代码的日常流程。
【免费下载链接】terraform-provider-awsThe AWS Provider enables Terraform to manage AWS resources.项目地址: https://gitcode.com/GitHub_Trending/te/terraform-provider-aws
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考