AWS CDK学習の始め方
2022年末頃からAWS CDKを使い始め、その実用性に感動している。
IaCのコンセプトを体現しているなーと言う印象を受けた。
自習メモの他にもオンライン勉強会もぼちぼち拝見しているため、今後はそれらの覚え書きもしていきたい。
AWS CDK仕様まわり
CDK CLI
CLIツールcdk
と実装で使う各言語のライブラリは別々なので、バージョン不一致であればcdk
実行時にエラーで教えてくれる。
私はv0.2あたりのプレビューをインストールしっぱなしの環境でCDKを再開したので下記エラーが発生した。CLIを最新バージョンするだけでOK。
This CDK CLI is not compatible with the CDK library used by your application. Please upgrade the CLI to the latest version.
(Cloud assembly schema version mismatch: Maximum schema version supported is 22.0.0, but found 29.0.0)
ベストプラクティス色々
Stack
とConstruct
の扱いに関しては既に各所で共有されているが、一通りはAWSブログにまとまっているので一読がおすすめ。
「Constructのベストプラクティス」は正しい使い方に重要。
AWS CDKは言語ライブラリなので、CloudFormationとは段違いの自由度がある分、簡潔に維持する努力が必要でアプリ開発と同じ姿勢が必要になってくる。(CFnテンプレートの知識は使わないし忘れた方が良い)
個人的にはスタック間参照(CFnで言うOutputs
)から解放されるところが嬉しい。テンプレートが大きく育っても可読性を維持できそう。
SSMパラメータ使わずとも、大抵のケースでは(Pythonにおける@property
のように)Constructのクラス変数をイミュータブルに参照すればOutputsの代用に十分なはず。
学習ネタ
JAWS-UG CDK支部
一度参加したら面白かったのでまた参加しよう。
AWS CDK for LocalStack
AWS CDKをlocalstackで動作させれば学習環境に最適だな、と思って使い始めたら最初のbootstrap
でエラーに遭遇した。
--endpoint-url
の切り替えだけで動く想定だったが過去issueを見回っても解決できなかったため自分でissueに追加したところ、nodeバージョンに起因するIPv6の問題だったことが判明。
またipv6か...と言う気持ちはあるけれど解決策を調査&リリースしてくれたJoelさんにはすごく感謝している。issueあげて良い経験ができました。
実際に使っての感想
IaCとソースコードを分離しつつ一括管理できる
自分にIaCという概念が足りてなかったなーと実感できた。
例えばLambda関数をデプロイしたい場合、CFnテンプレートではCode
ステートメントを使ってテンプレート内にソースコードを埋め込む必要があった。(それが無理で個人的には一度も使ったことがない...)
AWS CDKではテンプレートもオブジェクトなのでソースコードを読み込んで引数に使えばOK、と言うシンプルさが通用する。
-
Construct
記述例: 構築リソースの定義
from aws_cdk import (
aws_lambda as lambda_,
aws_iam as iam,
)
from constructs import Construct
class Summarizer(Construct):
def __init__(self, scope: Construct, construct_id: str, **kwargs):
super().__init__(scope, construct_id, **kwargs)
lambda_role = iam.Role(self, "lambdaRole",
role_name="LambdaRole-dev",
assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
)
lambda_role.add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name('service-role/AWSLambdaBasicExecutionRole'))
with open('./src/index.py', 'r') as src:
src_code = src.read()
function = lambda_.CfnFunction(self, 'functionQuery',
code=lambda_.CfnFunction.CodeProperty(
# image_uri="imageUri",
# s3_bucket="s3Bucket",
# s3_key="s3Key",
# s3_object_version="s3ObjectVersion",
zip_file=src_code,
),
role=lambda_role.role_arn,
description='###',
environment=lambda_.CfnFunction.EnvironmentProperty(
variables={
'TZ': 'Asia/Tokyo',
}
),
# 後略
-
Stack
記述例: 構築リソースの順序やパラメータの定義
from aws_cdk import (
Stack,
Aws,
)
from constructs import Construct
from .database import DataBase
from .function import Summarizer
class CdkStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
accountId = Aws.ACCOUNT_ID
database = 'cdk_default'
tableName = 'table'
data_location = 's3://**'
glue_config = {
"db_name": database,
"table_name": tableName,
"location": data_location,
}
database = DataBaseCUR(self, "database", glue_config)
summarizer = Summarizer(self, "Query")
# 後略
開発者がインフラレイヤも管理しやすくする
現状ではSREチームがインフラレイヤをIaC構築しても、IaCごと開発チームに保守してもらうことは難しかった。巨大なプレーンテキストのテンプレート設定を理解してね、とも言いづらいし実際にデメリットも大きい。
AWS CDKのように一つの言語ライブラリになれば、ソースコードと同じ言語を採用してIaCを記述できて開発チーム自身がインフラレイヤを理解しやすくなる。
その段階に来たらSREチームはIaCを委任すれば良いが、SREの仕事としてはバリデーションなどの共通コンポーネントを実装することが重要になると感じている。
企業によっては自社サービスの共通機能(ex. 認証や決済)を内製化してプロダクト開発の品質と速度を上げる取り組みを見かけるので、AWS CDKによるIaC管理でも同様のアプローチは大切になりそう。
Discussion