CDKTFでconfig-driven importを試してみる
CDKTF 0.19でconfig-driven importがサポートされたので、試してみました。
CDKTF 0.19 adds support for config-driven import and refactoring
config-driven importとは
Terraform 1.5で追加された機能です。
従来からTerraformでは、terraform import
コマンドで既存リソースをTerraformの構成管理下に置くことができました。
しかし、このコマンドはリソースを1つずつインポートする必要がある・結果をプレビューすることができない等制限もありました。
config-driven importでは、import
ブロックを利用することで上記の制限をなくし、インポート操作をコードで定義できるようになりました。
import { # ID of the cloud resource # Check provider documentation for importable resources and format id = “i-abcd1234” # Resource address to = aws_instance.example }
今回のアップデートでCDKTFでもconfig-driven importがサポートされました。
Terraform 1.5 brings config-driven import and checksからコードを引用
Terraform v1.5.0 で追加された import ブロックと check ブロックを試してみた | DevelopersIO
何が嬉しい?
- インポート操作が簡単にできるようになった
- cdktfではimportのコマンドが提供されていないため、従来はimportに一工夫必要だった
- Support `terraform import` via the cdk cli · Issue #1134 · hashicorp/terraform-cdk
やってみた
アップデートブログと同様にS3バケットをimportしてみます。
前提
- terraform version : 1.5以上
- cdktf version: 0.19.0以上
- 言語はtypescript
- AWS providerを使用
- Stateファイルはlocal保存
手動でテスト用のリソースを用意
S3バケットを作成します。
$ BUCKET_NAME="test-cdktf-import-20231018" # 任意の名前に置き換えてください $ aws s3api create-bucket --bucket $BUCKET_NAME --create-bucket-configuration LocationConstraint=ap-northeast-1
CDKTFのプロジェクトを作成する
検証用にCDKTFのプロジェクトを作成します。
$ mkdir config-driven-import $ cd config-driven-import $ npx cdktf init --template="typescript" --providers="aws@~>5.0" --local Note: By supplying '--local' option you have chosen local storage mode for storing the state of your stack. This means that your Terraform state file will be stored locally on disk in a file 'terraform.<STACK NAME>.tfstate' in the root of your project. ? Project Name config-driven-import ? Project Description A simple getting started project for cdktf. ? Do you want to start from an existing Terraform project? no ? Do you want to send crash reports to the CDKTF team? Refer to https://developer.hashicorp.com/terraform/cdktf/create-and-deploy/configuration-file#enable-crash-reporting-for-the-cli for more information yes added 2 packages, and audited 57 packages in 784ms 7 packages are looking for funding run `npm fund` for details found 0 vulnerabilities added 313 packages, and audited 370 packages in 11s 37 packages are looking for funding run `npm fund` for details found 0 vulnerabilities ======================================================================================================== Your CDKTF TypeScript project is ready!
コマンド実行後は以下のディレクトリ構成になります。
$ ls -1 __tests__ cdktf.json cdktf.out help jest.config.js main.ts node_modules package-lock.json package.json setup.js tsconfig.json
手動で作成したS3バケットをCDKTFでimportする
main.ts
を以下の用に変更します。
import { Construct } from "constructs"; import { App, TerraformStack } from "cdktf"; import { AwsProvider } from "@cdktf/provider-aws/lib/provider"; import { S3Bucket } from "@cdktf/provider-aws/lib/s3-bucket"; class MyStack extends TerraformStack { constructor(scope: Construct, id: string) { super(scope, id); new AwsProvider(this, "AWS", { region: "ap-northeast-1", }); // 「test-cdktf-import-20231018」の部分は作成したバケット名に置き換えてください new S3Bucket(this, "bucket", {}).importFrom("test-cdktf-import-20231018"); } } const app = new App(); new MyStack(app, "config-driven-import"); app.synth();
AWS認証情報をセットして、diffを確認します。
$ cdktf diff config-driven-import Initializing the backend... config-driven-import Initializing provider plugins... - Reusing previous version of hashicorp/aws from the dependency lock file config-driven-import - Using previously-installed hashicorp/aws v5.21.0 Terraform has been successfully initialized! config-driven-import 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. config-driven-import aws_s3_bucket.bucket (bucket): Preparing import... [id=test-cdktf-import-20231018] config-driven-import aws_s3_bucket.bucket (bucket): Refreshing state... [id=test-cdktf-import-20231018] config-driven-import Terraform will perform the following actions: config-driven-import # aws_s3_bucket.bucket (bucket) will be imported resource "aws_s3_bucket" "bucket" { arn = "arn:aws:s3:::test-cdktf-import-20231018" bucket = "test-cdktf-import-20231018" bucket_domain_name = "test-cdktf-import-20231018.s3.amazonaws.com" bucket_regional_domain_name = "test-cdktf-import-20231018.s3.ap-northeast-1.amazonaws.com" hosted_zone_id = "XXXXXXXXXX" id = "test-cdktf-import-20231018" object_lock_enabled = false region = "ap-northeast-1" request_payer = "BucketOwner" tags = {} tags_all = {} grant { id = "XXXXXXXXXX" permissions = [ "FULL_CONTROL", ] type = "CanonicalUser" } server_side_encryption_configuration { rule { bucket_key_enabled = false apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } } versioning { enabled = false mfa_delete = false } } Plan: 1 to import, 0 to add, 0 to change, 0 to destroy. ───────────────────────────────────────────────────────────────────────────── Saved the plan to: plan To perform exactly these actions, run the following command to apply: terraform apply "plan"
該当のS3バケットをimportしようとしていることがわかります。
importを実行します。
$ cdktf deploy # 省略 Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed. No outputs found.
Terraformのimportブロックと同様に、cdktf deploy(apply)
後はimportFromの記述は削除して問題ありません。
import { Construct } from "constructs"; import { App, TerraformStack } from "cdktf"; import { AwsProvider } from "@cdktf/provider-aws/lib/provider"; import { S3Bucket } from "@cdktf/provider-aws/lib/s3-bucket"; import { S3BucketVersioningA } from "@cdktf/provider-aws/lib/s3-bucket-versioning"; class MyStack extends TerraformStack { constructor(scope: Construct, id: string) { super(scope, id); new AwsProvider(this, "AWS", { region: "ap-northeast-1", }); new S3Bucket(this, "bucket", { }); } } const app = new App(); new MyStack(app, "config-driven-import"); app.synth();
importFrom削除後も、差分が出ないことが確認できます。
$ cdktf diff # 省略 No changes. Your infrastructure matches the configuration.
importFromは残しておいても動作に問題はありませんが、importFromの返り値がvoidのため、「S3バケット クラスを変数に入れて他の部分で使う」といったことができません。
(「動作確認: importしたリソースをcdktf経由で変更してみる」のconst bucket = new S3Bucket(...
のようなことができない)
そのため、import後はimportFromを削除するようにしましょう。
動作確認: importしたリソースをcdktf経由で変更してみる
cdktf経由でリソースを変更してみましょう。
S3バケットのバージョニングをcdktf経由で有効化してみます。
import時点では、バケットのバージョニングが無効です。
コード上でバケットのバージョニングを有効化します。
import { Construct } from "constructs"; import { App, TerraformStack } from "cdktf"; import { AwsProvider } from "@cdktf/provider-aws/lib/provider"; import { S3Bucket } from "@cdktf/provider-aws/lib/s3-bucket"; import { S3BucketVersioningA } from "@cdktf/provider-aws/lib/s3-bucket-versioning"; class MyStack extends TerraformStack { constructor(scope: Construct, id: string) { super(scope, id); new AwsProvider(this, "AWS", { region: "ap-northeast-1", }); const bucket = new S3Bucket(this, "bucket", { }); new S3BucketVersioningA(this, "versioning", { bucket: bucket.id, versioningConfiguration: { status: "Enabled", } }) } } const app = new App(); new MyStack(app, "config-driven-import"); app.synth();
diffで変更内容を確認します。
$ cdktf diff config-driven-import Initializing the backend... config-driven-import Initializing provider plugins... - Reusing previous version of hashicorp/aws from the dependency lock file config-driven-import - Using previously-installed hashicorp/aws v5.21.0 Terraform has been successfully initialized! config-driven-import 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. config-driven-import aws_s3_bucket.bucket (bucket): Refreshing state... [id=test-cdktf-import-20231018] config-driven-import 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: config-driven-import # aws_s3_bucket_versioning.versioning (versioning) will be created + resource "aws_s3_bucket_versioning" "versioning" { + bucket = "test-cdktf-import-20231018" + id = (known after apply) + versioning_configuration { + mfa_delete = (known after apply) + status = "Enabled" } } Plan: 1 to add, 0 to change, 0 to destroy. ───────────────────────────────────────────────────────────────────────────── Saved the plan to: plan To perform exactly these actions, run the following command to apply: terraform apply "plan"
バージョニングがEnabled
になることがわかります。変更を適用します。
$ cdktf deploy # 省略 Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
コンソール上からも有効化できていることを確認できました。
おわりに
CDKTFを使って、既存リソースをimportしてCDKTF経由で変更を試してみました。
config-driven importのサポートでCDKTFはますます便利になりました。
バックエンドがterraformなだけあり、快適にimportできます。
以上、AWS事業本部の佐藤(@chari7311)でした。