概要
AWSをwebから初めて使うときって特に気になりませんが、少し慣れてくると
「これいちいち所望のアプリ見に行って設定直すのめんどくせえ、、、!!!!」、と思いませんか?(思いますよね???)
lambdaとS3を連携したりとかよくあると思うんですが、毎回どのlambdaだっけとか探すのめんどくさい。
これってなんとかならないの〜??
ってことで今回はAWS CDKを使って設計をコード化してまとめてAWSにあげてみます。
コードでインフラストラクチャを定義できるようになりましょう!
初心者用なので、「とりあえずそれっぽく」を軸に話します。
イメージはこんな感じ。
AWS CDK
そもそもAWSCDKとは?となる人もいるので公式から説明を拝借。
AWS Cloud Development Kit (AWS CDK) は、使い慣れたプログラミング言語を使用してクラウドアプリケーションリソースを定義するためのオープンソースのソフトウェア開発フレームワークです。
要は自分の得意なプログラミング言語を使用して、アプリリソースを定義できちゃいますということ。
リソースの塊1つ1つはcloudformationにstackとしてデプロイされます!
公式リファレンスのmoduleを確認してみると
Language | Package |
---|---|
TypeScript | aws-cdk-lib |
Python | aws_cdk |
Java | software.amazon.awscdk |
Go | github.com/aws/aws-cdk-go/awscdk/v2 |
.NET | Amazon.CDK |
上記言語で主に使用できるようです。
今回は、npmでCDKをインストールした後、python形式でlambda,S3をそれぞれ作成してみようと思います。
注意
AWSアカウントの発行、AWS-CLIの設定は既に行なっているものして話を進めます。
インストール
まずは以下のコマンドを実行します。
$ npm install -g aws-cdk
インストールが正しく行われているか確認してみます。
$ cdk --version
2.37.1 (build f15dee0)
version情報が正しく出ていればokです。
注意
AWS CDKにはv1,v2の公開があり、本記事ではv2を使用しています。
ネットの他記事情報はv1,v2の情報が混在しておりますので、自身でさらに学ぶ場合には注意が必要です。
プロジェクトの作成
空のディレクトリを作成して、移動します。
ディレクトリ名はそのままcdkのプロジェクト名になります。
$ mkdir project-name
$ cd project-name
対象のディレクトリに移動したら、cdk init
でプロジェクトを作成します。
$ cdk init --language python
今回使用言語はpythonにしました。
--language
以降を適宜使用したい言語に変更すれば、所望の言語でプロジェクトを作成できます。
作成されるプロジェクトの構成を以下に示しました。
.
├── project-name
│ ├── project-name_stack.py
│ └── __init__.py
├── README.md
├── app.py
├── cdk.json
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests
├── __init__.py
└── unit
├── __init__.py
└── test_project-name_stack.py
pythonの仮想環境にはaws-cdk関連は入っていませんので、pipでinstallします。
既にプロジェクト作成時にrequirements.txt
が作成されていますので、こちらに沿ってインストールしましょう。
(.venv) $ pip install -r requirements.txt
aws-cdk-lib
constructs
がpip listで確認できれば成功です。
(.venv) $ pip list
Package Version
----------------- --------
aws-cdk-lib 2.37.1
constructs 10.1.92
(以下省略)
s3を書く
AWSのアプリケーションを作成していきます。
まずは手始めにs3を作成します。
AWSCDKではプロジェクト1つの塊をスタックとして管理します。
初期状態ではstackの定義は以下の通りです。
from aws_cdk import (
# Duration,
Stack,
# aws_sqs as sqs,
)
from constructs import Construct
class ProjectNameStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# The code that defines your stack goes here
# example resource
# queue = sqs.Queue(
# self, "20220830QiitaTestPjQueue",
# visibility_timeout=Duration.seconds(300),
# )
各アプリケーションを作成するためには、aws_cdk
ライブラリから要素をimportする必要があります。
今回はaws_s3
をimportして作成します。(見やすいように初期のコメント削除しました。)
from aws_cdk import (
Stack,
aws_s3 as _s3,
RemovalPolicy
)
from constructs import Construct
class ProjectNameStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# S3の設定
bucket = _s3.Bucket(
self,"ProjectxxxBucket",
bucket_name="project-xx-bucket",
removal_policy=RemovalPolicy.DESTROY, # スタック削除時、自動的にバケットを削除
)
Bucketの中に必要な設定を行うことで、所望のs3を作成することができます。
今回はバケット名をproject-xx-bucketとし、 スタック削除時、自動的にバケットを削除するように設定しました。
このほかにもライフタイムのルールや、ポリシーの設定なども可能です。
注意
詳細な設定はAPIリファレンスを読み解く必要があります。
lambdaを作成する
次にlambdaを作成してみます。
s3と同様に今回はaws_lambda
をimportして作成します。
from aws_cdk import (
Stack,
aws_s3 as _s3,
RemovalPolicy,
aws_lambda as _lambda,
)
from constructs import Construct
class ProjectNameStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
(省略)
# lambdaの設定
my_function = _lambda.Function(
self,"ProjectxxxLambda",
function_name="project-xxx-function",
runtime=_lambda.Runtime.PYTHON_3_9, # 使用するランタイムの設定(今回はpython3.9)
code=_lambda.Code.from_asset("lambda"), # lambdaで動かすコードのありか
handler="testcode.handler_test", # handlerの設定
)
runtime
でlambdaで使用するランタイムを設定します。今回はpython3.9にしました。
code
では実際にlambdaに入れ込むコードのフォルダの場所を記述します。
handler
はcodeで示したコード類の中で、どのファイルのメソッドをhandlerにするか示します。
今回はtestcode.pyのhandler_testメソッドがhandlerになります。lambdaは起動後このhandlerを動作させます。
次にプロジェクトディレクトリ直下にlambdaで実行するコードを作成します。
$ mkdir lambda
$ cd lambda
$ touch testcode.py
def handler_test(event, context):
print('Hello World')
コード内のメソッドをhandlerとして機能させるにはevent
context
の2つを引数で受け取ります。
deployする
AWS環境にdeployします
初回のみ
初回のみ以下コマンドを実行します。
$ cdk bootstrap
この操作により、デプロイプロセスの際に使用される CloudFormation のテンプレートやアセットを保存するための S3 バケットが作成されるようです。
現状コードと実際のAWSの差分の確認
$ cdk diff
現状と比較して、その差分を検出してコンソールに表示してくれます。
以下は初回実行時の例です
$ cdk diff
Stack QiitaPjStack
IAM Statement Changes
┌───┬─────────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼─────────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤
│ + │ ${ProjectxxxLambda/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
└───┴─────────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼─────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${ProjectxxxLambda/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)
Parameters
[+] Parameter BootstrapVersion BootstrapVersion:
(省略)
Conditions
[+] Condition CDKMetadata/Condition CDKMetadataAvailable:
(省略)
Resources
(省略)
Other Changes
(省略)
環境にデプロイする
差分を確認して、問題なければdeployします。
初回はDo you wish to deploy these changes (y/n)?
と質問されます。
$ cdk deploy
問題なければ、AWSコンソールからデプロイしたアプリケーションが確認できるはずです。
CloudFormation
S3
lambda
削除する
最後にdeployした環境を削除してみます。
$ cdk destroy
削除不可の要素がなければ、コマンドは実行されます。
CloudFormation等を確認して、アプリケーションがないことを確認できます。
まとめ
コードでインフラストラクチャを定義できるようになりました!!やったね!
とは言いつつ、設定やアプリの連携はさらに知識が必要なので鍛錬を怠らないようにしていきたいですね。