这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在 Go 中使用 AWS CDK
Go 是一种 AWS 云开发工具包 (AWS CDK) 完全支持且视为稳定的客户端语言。在 Go 中使用 AWS CDK 采用了熟悉的工具。AWS CDK 的 Go 版本甚至使用了 Go 风格的标识符。
与 CDK 支持的其他语言不同,Go 不是面向对象的传统编程语言。Go 使用组合,而其他语言经常利用继承。我们已经尝试尽可能使用惯用的 Go 方法,但是 CDK 在某些地方可能会有所不同。
本主题提供在 Go 中使用 AWS CDK 时的指导。有关 AWS CDK 简单 Go 项目的演练,请参阅公告博客文章
开始使用 Go
要使用 AWS CDK,您必须拥有 AWS 账户和凭证,并已安装 Node.js 和 AWS CDK 工具包。请参阅开始使用 AWS CDK。
AWS CDK 的 Go 绑定使用标准 Go 工具链
注意
第三方语言弃用:语言版本仅在供应商或社区共享其 EOL(生命周期终止)之前才受支持,如有更改,会另行通知。
创建项目
您可以通过在空目录中调用 cdk init 来创建一个新的 AWS CDK 项目。使用 --language 选项并指定 go:
mkdir my-project cd my-project cdk init app --language go
cdk init 使用项目文件夹的名称来命名项目的各种元素,包括类、子文件夹和文件。文件夹名称中的连字符都将转换为下划线。但是,名称应遵循 Go 标识符的形式;例如,名称不应以数字开头,也不应包含空格。
由此生成的项目包含对 go.mod 中核心 AWS CDK Go 模块 github.com/aws/aws-cdk-go/awscdk/v2 的引用。发出 go get 命令以安装此模块和其他所需模块。
管理 AWS 构造库模块
在大多数 AWS CDK 文档和示例中,“模块”一词通常用于指 AWS 构造库模块,每个 AWS 服务有一个或多个模块,这与该术语的惯用 Go 用法不同。在一个 Go 模块中提供 CDK 构造库,其中包含单独的构造库模块,这些模块支持各种 AWS 服务,在该模块中作为 Go 软件包提供。
某些服务的 AWS 构造库支持位于多个构造库模块(Go 包)中。例如,Amazon Route 53 除了有 awsroute53 主包之外,还有三个构造库模块,分别名为 awsroute53patterns、awsroute53resolver 和 awsroute53targets。
大多数 AWS CDK 应用程序中都需要的 AWS CDK 核心包在 Go 代码中导入为 github.com/aws/aws-cdk-go/awscdk/v2。AWS 构造库中各种服务的软件包位于 github.com/aws/aws-cdk-go/awscdk/v2 下。例如,Amazon S3 模块的命名空间为 github.com/aws/aws-cdk-go/awscdk/v2/awss3。
import ( "github.com/aws/aws-cdk-go/awscdk/v2/awss3" // ... )
为想要在应用程序中使用的服务导入构造库模块(Go 软件包)后,您就可以使用 awss3.Bucket 等来访问该模块中的构造。
在 Go 中管理依赖项
在 Go 中,依赖项版本是在 go.mod 中定义的。默认 go.mod 与此处显示的类似。
module my-package go 1.16 require ( github.com/aws/aws-cdk-go/awscdk/v2 v2.16.0 github.com/aws/constructs-go/constructs/v10 v10.0.5 github.com/aws/jsii-runtime-go v1.29.0 )
包名称(即 Go 语言中所说的模块)由 URL 进行指定,并附加了所需的版本号。Go 的模块系统不支持版本范围。
发出 go get 命令以安装所有所需的模块并更新 go.mod。要查看依赖项的可用更新列表,请发出 go list -m -u all 命令。
Go 中的 AWS CDK 习语
字段和方法名称
在 CDK 的原始语言 TypeScript 中,字段和方法名称使用驼峰式命名法 (likeThis)。在 Go 中,这些名称遵循 Go 惯例,即采用帕斯卡命名法 (LikeThis)。
清理
在您的 main 方法中,请使用 defer jsii.Close() 来确保 CDK 应用程序自行清理。
缺失值和指针转换
在 Go 中,AWS 对象的缺失值(例如属性捆绑包)用 nil 表示。Go 没有可为 null 的类型;唯一可以包含 nil 的类型是指针。因此,为了让值变得可选,所有 CDK 属性、参数和返回值都是指针,即便对于原始类型也是如此。这同时适用于必需值和可选值,因此,如果必需值后来变为可选值,则无需对类型进行重大更改。
传递字面值或表达式时,请使用以下辅助函数来创建指向这些值的指针。
-
jsii.String -
jsii.Number -
jsii.Bool -
jsii.Time
例如,以字符串而不是指向字符串的指针来接收构造的 id 似乎更方便,但为了保持一致性,我们还是建议您在定义自己的构造时以类似方式使用指针。
在处理可选的 AWS CDK 值(包括原始值和复杂类型)时,在对指针执行任何操作之前,应明确测试指针以确保它们不为 nil。Go 不像其他一些语言有“语法糖”来帮助处理空值或缺失值。但是,属性捆绑包和类似结构中的必需值是保证存在的(否则构造会失败),因此无需对这些值进行 nil 检查。
构造和 Props
构造代表一个或多个 AWS 资源及其关联属性,在 Go 中表示为接口。例如,awss3.Bucket 是一个接口。每个构造都有一个工厂函数,例如 awss3.NewBucket,用于返回实现相应接口的结构。
所有工厂函数都采用三个参数:在其中定义构造的 scope(构造树中的父级)、id 和 props(构造用于配置其创建的资源的键/值对捆绑包)。AWS CDK 中其他地方也使用了“属性捆绑包”模式。
在 Go 中,每个构造的 props 都由特定的结构类型表示。例如,awss3.Bucket 采用类型为 awss3.BucketProps 的 props 参数。使用结构体字面量来编写 props 参数。
var bucket = awss3.NewBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps{ Versioned: jsii.Bool(true), })
通用结构
在某些地方,AWS CDK 使用 JavaScript 数组或非类型化对象作为方法的输入。(例如,请参阅 AWS CodeBuild 的 BuildSpec.fromObject() 方法。) 在 Go 中,这些对象分别表示为切片和空接口。
CDK 提供了可变辅助函数,例如 jsii.Strings,用于构建包含原始类型的切片。
jsii.Strings("One", "Two", "Three")
使用任何切片
某些构造期望的属性是多种类型的列表(TypeScript 中的联合类型)。在 Go 中,这些是任何 (*[]any) 的切片。any 确保编译器在那里允许不同类型的分配。请参阅
AWS CDK Go package 的文档,了解允许的类型有哪些。
要使用此类属性,请使用 jsii 提供的帮助程序函数创建不同类型的任意切片:
-
jsii.AnySlice -
jsii.AnyStrings -
jsii.AnyNumbers
例如:
func Arns() *[]*string { a := "arn:aws:s3:::bucket1" b := "arn:aws:s3:::bucket2" return &[]*string{&a, &b} } awsiam.NewCfnUser(stack, jsii.String("User"), &awsiam.CfnUserProps{ ManagedPolicyArns: jsii.AnySlice(Arns()) // or ManagedPolicyArns: jsii.AnyStrings("arn:aws:s3:::bucket1", "arn:aws:s3:::bucket2") // or ManagedPolicyArns: &[]interface{}{ jsii.String("arn:aws:s3:::bucket1"), jsii.String("arn:aws:s3:::bucket2"), } })
这种方法确保 CDK 正确解释您的切片,从而避免在部署或合成堆栈时出现反序列化错误。
开发自定义构造
在 Go 中,编写新构造通常比扩展现有构造更简单。首先,定义一个新的结构类型,如果需要类似扩展的语义,则匿名嵌入一个或多个现有类型。为您要添加的任何新功能以及保存需要的数据所需的字段编写方法。如果您的构造需要 props 接口,则请定义一个。最后,编写一个工厂函数 NewMyConstruct() 来返回构造的实例。
如果您只是在现有构造上更改一些默认值,或者在实例化时添加一个简单的行为,则不需要所有这些管道。相反,写一个工厂函数来调用您正在“扩展”的构造的工厂函数。例如,在其他 CDK 语言中,您可以创建一个 TypedBucket 构造,通过覆盖 s3.Bucket 类型来强制执行 Amazon S3 存储桶中对象的类型,然后在新类型的初始化程序中添加一个存储桶策略,该策略仅允许向存储桶添加指定的文件扩展名。在 Go 中,可以更容易简单编写一个 NewTypedBucket 来返回您已在其中添加了适当存储桶策略的 s3.Bucket(使用 s3.NewBucket 进行实例化)。不需要新的构造类型,因为标准存储桶构造中已经提供了该功能;新的“构造”只是提供了一种更简单的配置方式。
构建、合成和部署
在运行您的应用程序之前,AWS CDK 会自动对其进行编译。但是,手动构建应用程序以检查错误并运行测试可能会很有用。可以在项目的根目录中在命令提示符下发出 go build 命令来执行此操作。
在命令提示符下运行 go test 命令来运行您编写的所有测试。
故障排除
如果遇到如下所示的编译器错误,则意味着字符串切片直接传递给需要切片的属性。
Cannot use 'jsii.Strings("arn:aws:s3:::bucket1", "arn:aws:s3:::bucket2")' (type *[]*string) as the type *[]interface{}
要解决此错误,请将 jsii.Strings() 替换为 jsii.AnyStrings()。有关更多背景信息和其他解决方案,请参阅此
CDK GitHub issue。