在 AWS CDK 中使用 Go - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 AWS CDK 中使用 Go

Go是 C AWS loud Development Kit (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 Toolkit。请参阅 AWS CDK 入门

AWS CDK 的Go绑定使用标准的 Go 工具链,即 v1.18 或更高版本。您可以使用自己选择的编辑器。

注意

第三方语言弃用:语言版本仅在供应商或社区共享其 EOL(生命周期终止)之前才受支持,如有更改,会另行通知。

创建项目

您可以通过在空目录cdk init中调用来创建新的 AWS CDK 项目。使用 --language 选项并指定 go

mkdir my-project cd my-project cdk init app --language go

cdk init 使用项目文件夹的名称来命名项目的各种元素,包括类、子文件夹和文件。文件夹名称中的连字符都将转换为下划线。但是,除此之外,名称应遵循Go标识符的形式;例如,名称不应以数字开头或包含空格。

生成的项目包括对核心 AWS CDK Go 模块的引用。github.com/aws/aws-cdk-go/awscdk/v2 go.mod发出 go get 命令以安装此模块和其他所需模块。

管理 AWS 构造库模块

在大多数 AWS CDK 文档和示例中,“模块” 一词通常用于指 AWS 构造库模块,每个 AWS 服务一个或多个模块,这与该术语的惯Go用法不同。CDK Construct Library 在一个Go模块中提供,其中包含单独的构造库模块,这些模块支持该模块中作为Go包提供的各种 AWS 服务。

某些服务的 AWS 构造库支持包含在多个构造库模块(Go包)中。例如,Amazon Route 53 除了有 awsroute53 主包之外,还有三个构造库模块,分别名为 awsroute53patternsawsroute53resolverawsroute53targets

你在大多数 AWS CDK 应用程序中都需要的 AWS CDK 的核心软件包是以Go代码形式导入的。github.com/aws/aws-cdk-go/awscdk/v2Construct Librar AWS y 中包含各种服务的软件包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 )

Package 名称(模块,用 Go 的话来说)由 URL 指定,并附加了所需的版本号。 Go的模块系统不支持版本范围。

发出 go get 命令以安装所有所需的模块并更新 go.mod。要查看依赖项的可用更新列表,请发出 go list -m -u all 命令。

AWS CDK 中的成语 Go

字段和方法名称

字段和方法名称在 CDK 的起源语言中 TypeScript使用驼色大小写 (likeThis)。在中Go,它们遵循Go惯例,Pascal大小写也是如此 ()。LikeThis

清理

在您的 main 方法中,请使用 defer jsii.Close() 来确保 CDK 应用程序自行清理。

缺失值和指针转换

在中Go, AWS CDK 对象(例如属性包)中的缺失值用表示。nil Go没有可为空的类型;唯一可以包含的类型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,以及构造用来配置其创建的资源的一 key/value 组对。 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构造来强制执行 Amazon S3 存储桶中对象的类型,方法是覆盖该s3.Bucket类型,然后在新类型的初始化器中添加仅允许向存储桶添加指定文件扩展名的存储桶策略。在中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 有关更多背景信息和其他解决方案,请参阅此处。