CDK for Terraformを使ってAWS Step Functionsをデプロイする
背景
業務の中でCDK for Terraform
を使って、AWS Step Functions
を構築する機会がありました。
そのやり方を今後使用する方や私自身の備忘録として記載しておきます!
CDK for Terraformとは
Cloud Development Kit for Terraform(CDKTF)は、使い慣れたプログラミング言語を使ってインフラの定義やプロビジョニングを行うことができます。これにより、HashiCorp Configuration Language(HCL)を学ぶことなくTerraformエコシステム全体にアクセスでき、テストや依存関係管理などに既存のツールチェインの力を活用することができます。
TypeScript、Python、Java、C#、Goをサポートしています。
CDK for Terraformは、AWS Cloud Development Kitのコンセプトとライブラリを活用し、お客様のコードをTerraform用のインフラ構成ファイルに変換します。
※公式ページから引用
つまり、AWS Cloud Development Kitを使って、Terraformを動かすことができるIaC (Infrastructure as Code) の一種です!
実装方法
事前に必要なもの(2023/05/12時点)
Terraform CLI ( 1.2 以上 )
Node.js ( v16 以上 )
CDK for Terraform
をインストールします
$ npm install --global cdktf-cli@latest
一応正常にインストールされたかを確認
$ cdktf help
Please pass a command to cdktf, here are all available ones:
cdktf
コマンド:
cdktf init Create a new cdktf project from a template.
cdktf get Generate CDK Constructs for Terraform providers
and modules.
cdktf convert Converts a single file of HCL configuration to
CDK for Terraform. Takes the file to be
converted on stdin.
cdktf deploy [stacks...] Deploy the given stacks [エイリアス: apply]
cdktf destroy [stacks..] Destroy the given stacks
cdktf diff [stack] Perform a diff (terraform plan) for the given
stack [エイリアス: plan]
cdktf list List stacks in app.
cdktf login Retrieves an API token to connect to Terraform
Cloud or Terraform Enterprise.
cdktf synth Synthesizes Terraform code for the given app in
a directory. [エイリアス: synthesize]
cdktf watch [stacks..] [experimental] Watch for file changes and
automatically trigger a deploy
cdktf output [stacks..] Prints the output of stacks
[エイリアス: outputs]
cdktf debug Get debug information about the current project
and environment
cdktf provider A set of subcommands that facilitates provider
management
cdktf completion generate completion script
オプション:
--version バージョンを表示 [真偽]
--disable-plugin-cache-env Dont set TF_PLUGIN_CACHE_DIR
automatically. This is useful when the
plugin cache is configured differently.
Supported using the env
CDKTF_DISABLE_PLUGIN_CACHE_ENV.
[真偽] [デフォルト: false]
--log-level Which log level should be written. Only
supported via setting the env
CDKTF_LOG_LEVEL [文字列]
-h, --help ヘルプを表示 [真偽]
Options can be specified via environment variables with the "CDKTF_" prefix
(e.g. "CDKTF_OUTPUT")
大丈夫そうです!
作業用ディレクトリの作成
ディレクトリ作って、移動しておきます
$ mkdir cdktf-step-function
$ cd cdktf-step-function
初期化
今回はTypeScript
で書いていきます。
$ cdktf init --template=typescript --local
templateで使用する言語を指定し、--localをつけることで自分のプロジェクトでtfstateを管理するようにしています。
対話形式で複数聞かれるのでプロジェクトに合わせて作成していきます。
$ cdktf init --template=typescript --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 cdktf-step-functions
? 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 No
added 2 packages, and audited 57 packages in 2s
7 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
added 302 packages, and audited 359 packages in 30s
37 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
========================================================================================================
Your cdktf typescript project is ready!
cat help Print this message
Compile:
npm run get Import/update Terraform providers and modules (you should check-in this directory)
npm run compile Compile typescript code to javascript (or "npm run watch")
npm run watch Watch for changes and compile typescript in the background
npm run build Compile typescript
Synthesize:
cdktf synth [stack] Synthesize Terraform resources from stacks to cdktf.out/ (ready for 'terraform apply')
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 stack
Test:
npm run test Runs unit tests (edit __tests__/main-test.ts to add your own tests)
npm run test:watch Watches the tests and reruns them on change
Upgrades:
npm run upgrade Upgrade cdktf modules to latest version
npm run upgrade:next Upgrade cdktf modules to latest "@next" version (last commit)
Use Providers:
You can add prebuilt providers (if available) or locally generated ones using the add command:
cdktf provider add "aws@~>3.0" null kreuzwerker/docker
You can find all prebuilt providers on npm: https://www.npmjs.com/search?q=keywords:cdktf
You can also install these providers directly through npm:
npm install @cdktf/provider-aws
npm install @cdktf/provider-google
npm install @cdktf/provider-azurerm
npm install @cdktf/provider-docker
npm install @cdktf/provider-github
npm install @cdktf/provider-null
You can also build any module or provider locally. Learn more https://cdk.tf/modules-and-providers
========================================================================================================
Note: You can always add providers using 'cdktf provider add' later on
? What providers do you want to use? aws
Checking whether pre-built provider exists for the following constraints:
provider: aws
version : latest
language: typescript
cdktf : 0.16.1
Found pre-built provider.
Adding package @cdktf/provider-aws @ 14.0.4
Installing package @cdktf/provider-aws @ 14.0.4 using npm.
Package installed.
また最後に使用するprovider
を聞かれるので、aws
を選択しておきます。
initが終わると、いろんなファイルが作成されます。
lambaの作成
まずはstep functionsで起動するlambadaを作成していきます。
今回はstep functionsのデプロイ方法中心に説明するためにlambdaはコンソール上から簡単に作成します。
作成したlambdaはこんな感じです。
(関数はデフォルトのままです)
CDK for Terraformでstep functionsを起動する
main.ts
にstep functionsの起動に必要なコードを記述していきます。
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import * as aws from '@cdktf/provider-aws'
// step functionsのassumeRoleのpolicy
const stepFunctionsAssumeRolePolicy = {
Version: '2012-10-17',
Statement: [
{
Action: 'sts:AssumeRole',
Principal: {
Service: 'states.amazonaws.com',
},
Effect: 'Allow',
},
],
}
// step functionsにアタッチするpolicy
const stepFunctionsPolicy = {
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Action: ['lambda:InvokeFunction'],
Resource: '*',
},
{
Effect: 'Allow',
Action: [
'xray:PutTraceSegments',
'xray:PutTelemetryRecords',
'xray:GetSamplingRules',
'xray:GetSamplingTargets',
],
Resource: '*',
},
],
}
// step functionsのASLを定義
const definition = {
StartAt: 'LambdaExec',
States: {
LambdaExec: {
Type: 'Task',
Resource:
'起動するlambdaのARN',
End: true,
},
}
}
class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
new aws.provider.AwsProvider(this, 'aws', {
region: 'ap-northeast-1',
})
// step functions実行用のroleを作成
const role = new aws.iamRole.IamRole(this, 'cdktf-test-step-functions-role', {
name: 'cdktf-test-step-functions-role',
assumeRolePolicy: JSON.stringify(stepFunctionsAssumeRolePolicy),
})
// policyの作成
const policy = new aws.iamPolicy.IamPolicy(this, 'cdktf-test-step-functions-policy', {
name: 'cdktf-test-step-functions-policy',
policy: JSON.stringify(stepFunctionsPolicy),
})
// step functionsの実行に必要なpolicyをアタッチ
new aws.iamRolePolicyAttachment.IamRolePolicyAttachment(
this,
'cdktf-test-step-functions-managed-policy',
{
policyArn: policy.arn,
role: role.name,
}
)
// step functionsをデプロイ
new aws.sfnStateMachine.SfnStateMachine(this, 'cdktf-test-state-machine', {
name: 'cdktf-test-state-machine',
definition: JSON.stringify(definition),
roleArn: role.arn,
})
}
}
const app = new App();
new MyStack(app, "cdktf-step-functions");
app.synth();
デプロイしてみる
デプロイコマンドを実行します。
$ cdktf deploy
terraformと同様、作成するリソースが出力されるので、リソースが想定したものかを確認します。
問題なければ、
❯ Approve Applies the changes outlined in the plan.
を選択することで、デプロイ完了です。
デプロイされているかの確認
コンソールでStep Functions
を開いてみます。
ステートマシンを確認すると、想定通りステートマシンが作成されています。
実際に実行もしてみると、前もって作成したlambdaが無事呼び出されていることを確認できました!
Discussion