この記事はセゾン情報システムズ Advent Calendar 2021 20日目の記事です。
#はじめに
AWS CDKはCloudFromation(cfn)のテンプレートをプログラミング言語で記述でき、
AWS CDKのコマンドでcfnのスタックの作成・更新・削除が行えるツールです。
https://aws.amazon.com/jp/cdk/
今回はWindows環境でAWS CDKとpythonを使用しVPCを構築してみようと思います。
そして、contextオプションを使用し、環境ごとにAWSリソースの値が異なる場合でも1つのソースコードで管理する方法を記載したいと思います。
cdkの導入方法は以下を参照してください。
https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/getting_started.html#getting_started_prerequisites
AWS CDKはバージョン2を使用します
>cdk version
2.2.0 (build 4f5c27c)
バージョン2はいろいろ便利になってるぽいです(詳細は割愛します)
https://aws.amazon.com/jp/about-aws/whats-new/2021/12/aws-cloud-development-kit-cdk-generally-available/
#VPC構築
それではさっそくVPC, Internet Gateway, NAT Gateway, Route Table, Subnetを作成していきたいと思います。
まず、適当にディレクトリを作成します。
>mkdir cdk-python& cd cdk-python
以下に従いコマンドを実行します(ログは長いので割愛)
https://cdkworkshop.com/30-python/20-create-project/100-cdk-init.html
>cdk init sample-app --language python
>.venv\Scripts\activate.bat
>pip install -r requirements.txt
cdk init実行後、.\cdk_python\cdk_python_stack.py
が作成されていると思うので以下の様に編集します。
※ちょうどよいテンプレがgithubに公開されていたのでコピってきました。
from constructs import Construct
from aws_cdk import (
Duration,
Stack,
#--- 追加 ---#
CfnOutput,
aws_ec2 as ec2
#------------#
)
class CdkPythonStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# 追加
self.vpc = ec2.Vpc(self, "VPC",
max_azs=2,
cidr="10.10.0.0/16",
# configuration will create 3 groups in 2 AZs = 6 subnets.
subnet_configuration=[ec2.SubnetConfiguration(
subnet_type=ec2.SubnetType.PUBLIC,
name="Public",
cidr_mask=24
), ec2.SubnetConfiguration(
subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT,
name="Private",
cidr_mask=24
), ec2.SubnetConfiguration(
subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
name="DB",
cidr_mask=24
)
],
# nat_gateway_provider=ec2.NatProvider.gateway(),
nat_gateways=2,
)
CfnOutput(self, "Output",
value=self.vpc.vpc_id)
#
以下のコマンドを実行し、CDKが利用するAWSリソースのデプロイを行います。
>cdk bootstrap
⏳ Bootstrapping environment aws://xxxxxxxxxxxx/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
:
:
✅ Environment aws://xxxxxxxxxxxx/ap-northeast-1 bootstrapped.
そして以下のコマンドを実行すると以下のcfnスタックが作成され、VPC等が構築されます
>cdk deploy
cdk-python: deploying...
[0%] start: Publishing ba4c2213578cfb0be75daf9d51461445e472292a2bbd872eb77a62059bf4412a:current_account-current_region
[100%] success: Published ba4c2213578cfb0be75daf9d51461445e472292a2bbd872eb77a62059bf4412a:current_account-current_region
cdk-python: creating CloudFormation changeset...
:
:
✅ cdk-python
Outputs:
cdk-python.Output = vpc-0ab9bd1270543add2
Stack ARN:
arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/cdk-python/262f5400-600d-11ec-967e-0a27860de79b
AWSコンソールにログインしcfnを確認するとスタックが作成されており、
VPC, Internet Gateway, NAT Gateway, Route Table, Subnetが作成されます、めちゃ便利!
削除する際はcdk destroy
で作成したリソースをすべて削除できます。
ちなみに、cdk synth
コマンドでcfnのテンプレの生成もできます
#context活用
開発をしていると、開発用環境、ステージング環境、本番環境といった複数環境構築することがあると思います。
環境ごとにリソース名を変えたい、VPCのCIDR変えたい、、、etc.
でも環境ごとにファイルを管理したくない、という場合活躍します。
contextはcdk.json
またはcdkコマンド実行時の--context
オプションでキーと値を指定することで使用できます。
今回はcdk.json
と--context
オプション両方を活用していきます。
cdk.json
はcdk init
実行時に自動で作成されているのでそれに以下の値を追加します
:
(略)
:
"context": {
# 追加
"dev": {
"envName": "develop",
"cidr": "10.10.0.0/16"
},
"stg": {
"envName": "staging",
"cidr": "10.20.0.0/16"
}
#
}
}
以下のコマンドを実行することでcontextで設定した値を参照できます.
>cdk context
Context found in cdk.json:
┌───┬─────┬──────────────────────────────────────────────────┐
│ # │ Key │ Value │
├───┼─────┼──────────────────────────────────────────────────┤
│ 1 │ dev │ { "envName": "develop", "cidr": "10.10.0.0/16" } │
├───┼─────┼──────────────────────────────────────────────────┤
│ 2 │ stg │ { "envName": "staging", "cidr": "10.20.0.0/16" } │
└───┴─────┴──────────────────────────────────────────────────┘
また、--contextオプションを指定し、その時だけcontextを設定することもできます。
>cdk context --context env=dev
Context found in cdk.json:
┌───┬─────┬──────────────────────────────────────────────────┐
│ # │ Key │ Value │
├───┼─────┼──────────────────────────────────────────────────┤
│ 1 │ dev │ { "envName": "develop", "cidr": "10.10.0.0/16" } │
├───┼─────┼──────────────────────────────────────────────────┤
│ 2 │ env │ "dev" │
├───┼─────┼──────────────────────────────────────────────────┤
│ 3 │ stg │ { "envName": "staging", "cidr": "10.20.0.0/16" } │
└───┴─────┴──────────────────────────────────────────────────┘
>cdk context --context env=stg
Context found in cdk.json:
┌───┬─────┬──────────────────────────────────────────────────┐
│ # │ Key │ Value │
├───┼─────┼──────────────────────────────────────────────────┤
│ 1 │ dev │ { "envName": "develop", "cidr": "10.10.0.0/16" } │
├───┼─────┼──────────────────────────────────────────────────┤
│ 2 │ env │ "stg" │
├───┼─────┼──────────────────────────────────────────────────┤
│ 3 │ stg │ { "envName": "staging", "cidr": "10.20.0.0/16" } │
└───┴─────┴──────────────────────────────────────────────────┘
contextの値を取り出すときは、pythonの場合self.node.try_get_context(key)
を使用します。
上記を踏まえ、cdk_python_stack.py
を以下の様に修正します
:
(略)
:
class CdkPythonStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# 追加・修正箇所
envKey = self.node.try_get_context("env")
envValue = self.node.try_get_context(envKey)
self.vpc = ec2.Vpc(self, "VPC-"+envValue["envName"],
max_azs=2,
cidr=envValue["cidr"],
#
:
(略)
:
以下のコマンドを実行し、AWSコンソールから作成されたリソースを確認します。
>cdk deploy --context env=stg
- VPCを例に確認
stagingという値がリソース名に追加されており、CIDRも10.20.0.0/16になっておりcontextで設定した値が使用されております。
これで環境ごとにファイルを用意する必要がなくなりますね。
以下にAPIの情報が載っており、もちろんVPC以外にもAWSリソースの作成は行えます。
サンプルもあり、Python以外の言語でも使用できるので今後活用していければなと思います。
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html