AWS CDK通常用打字稿编写,但可以用各种编程语言编写。
在本文中,我想写Golang的AWS CDK功能。
假设
此处介绍的Golang代码使用V1.18.7。
AWS CDK版本为v2.52.0。
我们将在本文中讨论的AWS CDK的功能主要是与Typescript版本。
基本功能可以在the document here中找到。
功能(与打字稿差异)
init的目录结构
在GO的情况下,cdk init app --language go
之后创建的目录结构如下。
名为cdk-go
的目录(存储库)。
❯ tree
.
├── README.md
├── cdk-go.go
├── cdk-go_test.go
├── cdk.json
└── go.mod
在打字稿的情况下,分开了bin
,lib
和test
目录,并且基于package.json与init同时安装了模块,并且还生成了node_modules
。
Go更简单,没有层次结构,这可能是由于在GO中开发时经常使用的平坦目录结构。
初始化的文件内容
在GO中,仅生成cdk-go.go
和cdk-go_test.go
GO文件,如上所述。
在Typescript中,堆栈生成代码写在bin
中生成的文件和lib
中生成的文件中的堆栈定义代码中编写,但是在GO中,两者都在同一单个文件(cdk-go.go
)中写入。
这是cdk-go.go
的初始代码。
package main
import (
"github.com/aws/aws-cdk-go/awscdk/v2"
// "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
)
type CdkGoStackProps struct {
awscdk.StackProps
}
func NewCdkGoStack(scope constructs.Construct, id string, props *CdkGoStackProps) awscdk.Stack {
var sprops awscdk.StackProps
if props != nil {
sprops = props.StackProps
}
stack := awscdk.NewStack(scope, &id, &sprops)
// The code that defines your stack goes here
// example resource
// queue := awssqs.NewQueue(stack, jsii.String("CdkGoQueue"), &awssqs.QueueProps{
// VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)),
// })
return stack
}
func main() {
defer jsii.Close()
app := awscdk.NewApp(nil)
NewCdkGoStack(app, "CdkGoStack", &CdkGoStackProps{
awscdk.StackProps{
Env: env(),
},
})
app.Synth(nil)
}
// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func env() *awscdk.Environment {
// If unspecified, this stack will be "environment-agnostic".
// Account/Region-dependent features and context lookups will not work, but a
// single synthesized template can be deployed anywhere.
//---------------------------------------------------------------------------
return nil
// Uncomment if you know exactly what account and region you want to deploy
// the stack to. This is the recommendation for production stacks.
//---------------------------------------------------------------------------
// return &awscdk.Environment{
// Account: jsii.String("123456789012"),
// Region: jsii.String("us-east-1"),
// }
// Uncomment to specialize this stack for the AWS Account and Region that are
// implied by the current CLI configuration. This is recommended for dev
// stacks.
//---------------------------------------------------------------------------
// return &awscdk.Environment{
// Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
// Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
// }
}
struct CdkGoStackProps
具有函数NewCdkGoStack
,main
和env
。
NewXxxStack
是堆栈定义(在typescript中的lib
中),而main
是堆栈生成(在typeScript中的bin
中)。
main()
功能中的defer jsii.Close()
是自动清理CDK应用程序(请参阅上面的官方参考)。
在打字稿版本中找不到函数env
,而是GO版本(从一开始就写成),并使用Account
和Region
返回awscdk.Environment
结构。
顺便说一句,初始化时的测试代码在这里。
package main
// import (
// "testing"
// "github.com/aws/aws-cdk-go/awscdk/v2"
// "github.com/aws/aws-cdk-go/awscdk/v2/assertions"
// "github.com/aws/jsii-runtime-go"
// )
// example tests. To run these tests, uncomment this file along with the
// example resource in cdk-go_test.go
// func TestCdkGoStack(t *testing.T) {
// // GIVEN
// app := awscdk.NewApp(nil)
// // WHEN
// stack := NewCdkGoStack(app, "MyStack", nil)
// // THEN
// template := assertions.Template_FromStack(stack)
// template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
// "VisibilityTimeout": 300,
// })
// }
指针转换为JSII
在某些地方查看上面的代码,尤其是在指定参数时,诸如jsii.Number
,jsii.String
之类的函数围绕参数指定的值。
queue := awssqs.NewQueue(stack, jsii.String("CdkGoQueue"), &awssqs.QueueProps{
VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)),
})
实际上,这是规则在CDK版本中指定参数时 因为GO语言没有零允许的类型,而唯一可以包含 so,要实现可选参数的“无属性”,我们可以通过一个可以作为 这是使用的主要区域。 这是CDK的GO版本的主要且麻烦的功能之一,但是一旦您习惯了,它就没有(?)。我认为一旦您习惯了,这不是问题。 (这会使外观变得更糟,但是...) 在打字稿版本中,我认为它是骆驼,但是在GO版本中,基本上是 cdk中提供的字段和方法名称是pascalcase(以大写字母开始)(请参阅上面的文档)。 这是GO的语言规范,公众(包装外)呼叫只能通过Pascal案件调用。 在GO中进行编码时,如果范围是私有的(正确,包裹),则将是骆驼。 以下是一个示例:当您尝试通过复制打字稿中编写的样本进行示例时,请小心。 是的,我在逃生舱口上遇到了麻烦。这是一个非常大的问题jsii.Number
和jsii.String
是仅返回指针的功能
nil
的类型是指针类型。 (“仅”一词可能具有误导性,但我们不会去这里,而是翻译上述文档。)nil
的指针类型(请参见上面的文档)。
CDK模块中的字段和方法名称是Pascal情况
cfnAppRunner.SetHealthCheckConfiguration(&awsapprunner.CfnService_HealthCheckConfigurationProperty{
Path: jsii.String("/"),
Protocol: jsii.String("HTTP"),
})
无法逃脱舱口。
首先,CDK具有一个方便的功能,称为L2 Construct,您可以通过简单地指定一些必需的值来根据最佳实践来构建资源。
也有L1构造,它允许您通过以与云形式一致的方式指定资源来构建资源。
虽然L2构造很方便且易于创建资源,但它也会抽象参数,因此有一些参数在l2 中未指定。。
因此,有一种方法可以将用L2构造创建的资源铸造为L1构造类型,然后覆盖只能用L1指定的参数,即“ Escape Hatch”。 但是,GO的CDK目前不支持the workshop。 CDK具有一个名为“逃生舱口”的概念,它允许您修改L2构造的基础CFN资源以访问由云形式支持但尚未得到CDK支持的功能。不幸的是,GO的CDK尚未支持此功能,因此我们必须通过L1构造创建资源。有关更多信息,请参见此GitHub问题,并在GO中遵循支持CDK逃生舱口的支持。 那么,如果要指定在L2构造中无法指定的参数,则该怎么办,它必须是L1构造? 同时,有一种方法可以进行逃生舱口。您可以使用方法 但是,这个 “快照测试”是您几乎可以将其视为CDK测试的测试。 您可以在打字稿中使用 从堆栈生成模板,然后将jsonized版本传递给 以下不是与打字稿有所不同,而是更像是独特的开发方法。 使用CDK开发时,您可能有多个代码组。 首先,有CDK代码组,然后是lambda和ecs的代码组。 在这种情况下,可以在一个存储库中准备这些目录,并通过共享go.mod在根目录中构建它们,但是您需要准备一个GO.mod 组合每个中需要的东西一个(多模块)。 (顺便说一句,在打字稿中,您可以使用 go在版本1.18中介绍了一个名为"Workspaces mode"的功能,该功能允许多模块(比以前更容易)。 这允许每个子目录的多模块开发并使用go.mod构建。 击中以下命令将使您处于工作空间模式。 然后将创建以下go.work文件以启用多模块开发。 如果您想看到它,我用AWS CDK制作了an actual example。 (在示例中,我们正在制作App Runner。) 我总结了我对GO的CDK的经验,因为我发现它与打字稿版本完全不同。 老实说,与CDK的打字稿版本相比,它仍然处于起步阶段,但我仍然很高兴能够写!
jsii.Get
。
var cfnAppRunner awsapprunner.CfnService
jsii.Get(apprunnerServiceL2.Node(), "defaultChild", &cfnAppRunner)
cfnAppRunner.SetAutoScalingConfigurationArn(autoScalingConfigurationArn)
jsii.Get
被弃用(请参阅this page),所以我觉得我别无选择,只能使用它。
快照测试
jest
(JavaScript)进行操作,但是在Go中,您可以按照以下方式进行。cupaloy.SnapshotT
以执行快照。
stack := NewAppRunnerStack(app, "AppRunnerStack", appRunnerStackProps)
template := assertions.Template_FromStack(stack, nil)
templateJson := template.ToJSON()
t.Run("Snapshot Test", func(t *testing.T) {
cupaloy.SnapshotT(t, templateJson)
})
额外的
工作区模式
aws-lambda-nodejs
在单个软件包中分别在单个软件包中获取一个不错的lambda和cdk定义。)
go work init moduleA moduleB
go 1.18
use (
./moduleA
./moduleB
)
示例实现
最后