HashiCorp公式ブログによると、8月からCDK for TerraformがGAリリースされ、さらにGoにも完全にサポートするようになったので、早速使ってみました。
CDK for Terraform(CDKTF)とは
CDK for Terraform(CDKTF)は、使い慣れたプログラミング言語を使用してインフラストラクチャを定義およびプロビジョニングできるツールです。CDKTFを利用することで、HashiCorp構成言語(HCL)を習得することなくTerraformエコシステム全体にアクセスでき、既存のツールチェーンのパワーをテスト、依存関係管理などに活用できるようになリます。
1. CDK for Terraform実装の前提条件
CDKTFを使う前に、下記の前提条件を満たす必要があります:
- Terraform v1.0以上インストールされていること
- AWSアカウントを持ち、かつCredentials情報が設定されていること
- Go v1.16以上インストールされていること
2. CDK for Terraformのインストール
CDKTFは、ほぼ全OSでnpmを使ってインストールすることができます。
また、MacOSではHomebrewでCDKTFをインストールできます。
npmの場合:
npm install --global cdktf-cli@latest
Homebrewの場合:
brew install cdktf
3. CDK for Terraformプロジェクトの作成と初期化
CDKTFプロジェクトを作成するには、空きディレクトリが必要のため、
まずプロジェクト用にcdktf-demo
というディレクトリを作成します。
mkdir cdktf-demo
続いて、cdktf-demo
ディレクトリに移動します。
cd cdktf-demo
cdktf-demo
ディレクトリ内で、cdktf init
コマンドを使って好きな言語でプロジェクトを初期化します。
本記事ではGoを使用するので、--template
にgoを記入します。
cdktf init --template="go"
? Do you want to continue with Terraform Cloud remote state management? No
? Project Name cdktf-demo
? Project Description A simple getting started project for cdktf.
? Do you want to send crash reports to the CDKTF team? See
https://www.terraform.io/cdktf/create-and-deploy/configuration-file#enable-crash-reporting-for-the-cli for more
information Yes
go: downloading github.com/hashicorp/terraform-cdk-go/cdktf v0.12.0
go: downloading github.com/aws/constructs-go/constructs/v10 v10.1.56
go: downloading github.com/aws/jsii-runtime-go v1.62.0
go: downloading github.com/Masterminds/semver/v3 v3.1.1
go: upgraded github.com/aws/constructs-go/constructs/v10 v10.0.25 => v10.1.56
========================================================================================================
Your cdktf go project is ready!
cat help Prints this message
Compile:
go build Builds your go project
Synthesize:
cdktf synth [stack] Synthesize Terraform resources to cdktf.out/
Diff:
cdktf diff [stack] Perform a diff (terraform plan) for the given stack
Deploy:
cdktf deploy [stack] Deploy the given stack
Destroy:
cdktf destroy [stack] Destroy the given stack
Learn more about using modules and providers https://cdk.tf/modules-and-providers
Use Providers:
Use the add command to add providers:
cdktf provider add "aws@~>3.0" null kreuzwerker/docker
Learn more: https://cdk.tf/modules-and-providers
========================================================================================================
上記のようなアウトプットを確認ができましたら、プロジェクトの初期化が完了となります。
4. AWSプロバイダーの追加
続いて、AWSプロバイダーを追加します。
cdktf provider add "aws@~>4.0"
Checking whether pre-built provider exists for the following constraints:
provider: aws
version : ~>4.0
language: go
cdktf : v0.12.0
Found pre-built provider.
Adding package github.com/hashicorp/cdktf-provider-aws-go/aws @ 9.0.10
[2022-08-08T11:56:34.251] [ERROR] default - go: downloading github.com/hashicorp/cdktf-provider-aws-go v0.0.0-20220804010506-f53ab9125fed
go: downloading github.com/hashicorp/cdktf-provider-aws-go v0.0.0-20220804010506-f53ab9125fed
[2022-08-08T11:57:15.499] [ERROR] default - go: module github.com/hashicorp/cdktf-provider-aws-go@upgrade found (v0.0.0-20220804010506-f53ab9125fed), but does not contain package github.com/hashicorp/cdktf-provider-aws-go/aws
go: module github.com/hashicorp/cdktf-provider-aws-go@upgrade found (v0.0.0-20220804010506-f53ab9125fed), but does not contain package github.com/hashicorp/cdktf-provider-aws-go/aws
Error: non-zero exit code 1
なぜか公式のドキュメント通りに行かず、パッケージが見つからないようですが、
https://pkg.go.dev/ でcdktf-provider-aws-goライブラリーを調べたところ、パッケージのURLはgithub.com/hashicorp/cdktf-provider-aws-go/aws
ではなく
github.com/hashicorp/cdktf-provider-aws-go/aws/v9
になったため、go get
で手動で追加します。
go get github.com/hashicorp/cdktf-provider-aws-go/aws/v9
go: downloading github.com/hashicorp/cdktf-provider-aws-go/aws/v9 v9.0.10
go: downloading github.com/aws/jsii-runtime-go v1.63.2
go: downloading github.com/aws/constructs-go/constructs/v10 v10.1.66
go: upgraded github.com/aws/constructs-go/constructs/v10 v10.1.56 => v10.1.66
go: added github.com/hashicorp/cdktf-provider-aws-go/aws/v9 v9.0.10
5. AWSリソースの作成
S3バケットを作成したいので、まずS3のライブラリーを追加します:
go get github.com/hashicorp/cdktf-provider-aws-go/aws/v9/s3
続いて、cdktf-demo
ディレクトリ内のmain.go
を編集して、新しいS3バケットを作ってみましょう。
package main
import (
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
"github.com/hashicorp/cdktf-provider-aws-go/aws/v9"
"github.com/hashicorp/cdktf-provider-aws-go/aws/v9/s3"
"github.com/hashicorp/terraform-cdk-go/cdktf"
)
func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
stack := cdktf.NewTerraformStack(scope, &id)
s3Bucket := s3.NewS3Bucket(stack, jsii.String("cdktf-demo-s3-bucket"), &s3.S3BucketConfig{
Bucket: jsii.String("cdktf-demo-s3-bucket"),
})
// アウトプット
cdktf.NewTerraformOutput(stack, jsii.String("bucket_arn"), &cdktf.TerraformOutputConfig{
Value: s3Bucket.Arn(),
})
return stack
}
func main() {
app := cdktf.NewApp(nil)
stack := NewMyStack(app, "cdktf-demo")
const region = "ap-northeast-1"
// プロバイダー設定
aws.NewAwsProvider(stack, jsii.String("aws"), &aws.AwsProviderConfig{
Region: jsii.String(region),
})
// ステージファイル設定
cdktf.NewS3Backend(stack, &cdktf.S3BackendProps{
Bucket: jsii.String("cdktf-demo-bucket"), // 事前にステージ管理のS3バケットの作成が必要です。
Key: jsii.String("s3/demo-s3-bucket.tfstate"),
Region: jsii.String(region),
})
app.Synth()
}
go mod tidy
を実行します。
❯ go mod tidy
go: downloading github.com/stretchr/testify v1.8.0
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading github.com/davecgh/go-spew v1.1.1
準備が終わりましたので、cdktf plan
を実行して差分を見てみましょう。
❯ cdktf plan
cdktf-demo Initializing the backend...
cdktf-demo
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
cdktf-demo Initializing provider plugins...
- Finding hashicorp/aws versions matching "4.24.0"...
cdktf-demo - Installing hashicorp/aws v4.24.0...
cdktf-demo - Installed hashicorp/aws v4.24.0 (signed by HashiCorp)
cdktf-demo Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
cdktf-demo Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
cdktf-demo # aws_s3_bucket.cdktf-demo-s3-bucket (cdktf-demo-s3-bucket) will be created
+ resource "aws_s3_bucket" "cdktf-demo-s3-bucket" {
+ acceleration_status = (known after apply)
+ acl = (known after apply)
+ arn = (known after apply)
+ bucket = "cdktf-demo-s3-bucket"
+ bucket_domain_name = (known after apply)
+ bucket_regional_domain_name = (known after apply)
+ force_destroy = false
+ hosted_zone_id = (known after apply)
+ id = (known after apply)
+ object_lock_enabled = (known after apply)
+ policy = (known after apply)
+ region = (known after apply)
+ request_payer = (known after apply)
+ tags_all = (known after apply)
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
+ cors_rule {
+ allowed_headers = (known after apply)
+ allowed_methods = (known after apply)
+ allowed_origins = (known after apply)
+ expose_headers = (known after apply)
+ max_age_seconds = (known after apply)
}
+ grant {
+ id = (known after apply)
+ permissions = (known after apply)
+ type = (known after apply)
+ uri = (known after apply)
}
+ lifecycle_rule {
+ abort_incomplete_multipart_upload_days = (known after apply)
+ enabled = (known after apply)
+ id = (known after apply)
+ prefix = (known after apply)
+ tags = (known after apply)
+ expiration {
+ date = (known after apply)
+ days = (known after apply)
+ expired_object_delete_marker = (known after apply)
}
+ noncurrent_version_expiration {
+ days = (known after apply)
}
+ noncurrent_version_transition {
+ days = (known after apply)
+ storage_class = (known after apply)
}
+ transition {
+ date = (known after apply)
+ days = (known after apply)
+ storage_class = (known after apply)
}
}
+ logging {
+ target_bucket = (known after apply)
+ target_prefix = (known after apply)
}
+ object_lock_configuration {
+ object_lock_enabled = (known after apply)
+ rule {
+ default_retention {
+ days = (known after apply)
+ mode = (known after apply)
+ years = (known after apply)
}
}
}
+ replication_configuration {
+ role = (known after apply)
+ rules {
+ delete_marker_replication_status = (known after apply)
+ id = (known after apply)
+ prefix = (known after apply)
+ priority = (known after apply)
+ status = (known after apply)
+ destination {
+ account_id = (known after apply)
+ bucket = (known after apply)
+ replica_kms_key_id = (known after apply)
+ storage_class = (known after apply)
+ access_control_translation {
+ owner = (known after apply)
}
+ metrics {
+ minutes = (known after apply)
+ status = (known after apply)
}
+ replication_time {
+ minutes = (known after apply)
+ status = (known after apply)
}
}
+ filter {
+ prefix = (known after apply)
+ tags = (known after apply)
}
+ source_selection_criteria {
+ sse_kms_encrypted_objects {
+ enabled = (known after apply)
}
}
}
}
+ server_side_encryption_configuration {
+ rule {
+ bucket_key_enabled = (known after apply)
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = (known after apply)
+ sse_algorithm = (known after apply)
}
}
}
+ versioning {
+ enabled = (known after apply)
+ mfa_delete = (known after apply)
}
+ website {
+ error_document = (known after apply)
+ index_document = (known after apply)
+ redirect_all_requests_to = (known after apply)
+ routing_rules = (known after apply)
}
}
cdktf-demo Plan: 1 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ bucket_arn = (known after apply)
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
特に問題なさそうなので続いて、cdktf apply
でS3バケットを作成します。
❯ cdktf apply
cdktf-demo Initializing the backend...
cdktf-demo Initializing provider plugins...
cdktf-demo - Reusing previous version of hashicorp/aws from the dependency lock file
cdktf-demo - Using previously-installed hashicorp/aws v4.24.0
cdktf-demo Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
cdktf-demo Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
cdktf-demo # aws_s3_bucket.cdktf-demo-s3-bucket (cdktf-demo-s3-bucket) will be created
+ resource "aws_s3_bucket" "cdktf-demo-s3-bucket" {
+ acceleration_status = (known after apply)
+ acl = (known after apply)
+ arn = (known after apply)
+ bucket = "cdktf-demo-s3-bucket"
+ bucket_domain_name = (known after apply)
+ bucket_regional_domain_name = (known after apply)
+ force_destroy = false
+ hosted_zone_id = (known after apply)
+ id = (known after apply)
+ object_lock_enabled = (known after apply)
+ policy = (known after apply)
+ region = (known after apply)
+ request_payer = (known after apply)
+ tags_all = (known after apply)
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
+ cors_rule {
+ allowed_headers = (known after apply)
+ allowed_methods = (known after apply)
+ allowed_origins = (known after apply)
+ expose_headers = (known after apply)
+ max_age_seconds = (known after apply)
}
+ grant {
+ id = (known after apply)
+ permissions = (known after apply)
+ type = (known after apply)
+ uri = (known after apply)
}
+ lifecycle_rule {
+ abort_incomplete_multipart_upload_days = (known after apply)
+ enabled = (known after apply)
+ id = (known after apply)
+ prefix = (known after apply)
+ tags = (known after apply)
+ expiration {
+ date = (known after apply)
+ days = (known after apply)
+ expired_object_delete_marker = (known after apply)
}
+ noncurrent_version_expiration {
+ days = (known after apply)
}
+ noncurrent_version_transition {
+ days = (known after apply)
+ storage_class = (known after apply)
}
+ transition {
+ date = (known after apply)
+ days = (known after apply)
+ storage_class = (known after apply)
}
}
+ logging {
+ target_bucket = (known after apply)
+ target_prefix = (known after apply)
}
+ object_lock_configuration {
+ object_lock_enabled = (known after apply)
+ rule {
+ default_retention {
+ days = (known after apply)
+ mode = (known after apply)
+ years = (known after apply)
}
}
}
+ replication_configuration {
+ role = (known after apply)
+ rules {
+ delete_marker_replication_status = (known after apply)
+ id = (known after apply)
+ prefix = (known after apply)
+ priority = (known after apply)
+ status = (known after apply)
+ destination {
+ account_id = (known after apply)
+ bucket = (known after apply)
+ replica_kms_key_id = (known after apply)
+ storage_class = (known after apply)
+ access_control_translation {
+ owner = (known after apply)
}
+ metrics {
+ minutes = (known after apply)
+ status = (known after apply)
}
+ replication_time {
+ minutes = (known after apply)
+ status = (known after apply)
}
}
+ filter {
+ prefix = (known after apply)
+ tags = (known after apply)
}
+ source_selection_criteria {
+ sse_kms_encrypted_objects {
+ enabled = (known after apply)
}
}
}
}
+ server_side_encryption_configuration {
+ rule {
+ bucket_key_enabled = (known after apply)
+ apply_server_side_encryption_by_default {
+ kms_master_key_id = (known after apply)
+ sse_algorithm = (known after apply)
}
}
}
+ versioning {
+ enabled = (known after apply)
+ mfa_delete = (known after apply)
}
+ website {
+ error_document = (known after apply)
+ index_document = (known after apply)
+ redirect_all_requests_to = (known after apply)
+ routing_rules = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
cdktf-demo
Changes to Outputs:
+ bucket_arn = (known after apply)
─────────────────────────────────────────────────────────────────────────────
Saved the plan to: plan
To perform exactly these actions, run the following command to apply:
terraform apply "plan"
cdktf-demo aws_s3_bucket.cdktf-demo-s3-bucket (cdktf-demo-s3-bucket): Creating...
cdktf-demo aws_s3_bucket.cdktf-demo-s3-bucket (cdktf-demo-s3-bucket): Creation complete after 3s [id=cdktf-demo-s3-bucket]
cdktf-demo
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
bucket_arn = "arn:aws:s3:::cdktf-demo-s3-bucket"
cdktf-demo
bucket_arn = arn:aws:s3:::cdktf-demo-s3-bucket
以上でCDKTFによりAWSリソースの作成ができました。
リソースの削除もterraformコマンドと同様にcdktf destroy
で削除可能です。
プロフィール
-
Web広告事業→AWSクラウドエンジニア→フルスタックエンジニア
最近SaaSの開発、Rustとtauri絶賛勉強中です。
最新の投稿
- レポート2023.05.19DevOpsDays Tokyo 2023 レポート – DevSecOpsについてまとめてみた
- IaC2022.08.09CDK for Terraformを使ってAWS基盤を構築してみました
- Trending2022.08.05GitHubトレンド週刊 8/4号
- Github2022.07.29GitHubトレンド週刊 7/28号