ご挨拶
最近CDKを使用してWordPress用RDSを作成する機会があったので記事として残しておきます。
参考資料
Working with the AWS CDK in Python
AWS CDK Python Reference
環境
CDK実行環境:Cloud9
CDKバージョン:2.22.0 (build 1db4b16)
言語:Python
OS:Ubuntu Server 18.04 LTS
インスタンスタイプ:t3.small
環境作成
mkdir rds-setup
cd rds-setup
cdk init app --language python
source .venv/bin/activate
python -m pip install -r requirements.txt
上記のコマンドを実行すると「rds_setup」というディレクトリに「rds_setup_stack.py」というファイルが作成されるのでこれを編集していきます。
作成したコード
from aws_cdk import (
Stack,
aws_ec2 as ec2,
aws_rds as rds,
CfnOutput
)
from constructs import Construct
class RdsSetupStack(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
engine = rds.DatabaseInstanceEngine.mysql(
version=rds.MysqlEngineVersion.VER_8_0_28
)
instance_type = ec2.InstanceType.of(
instance_class=ec2.InstanceClass.BURSTABLE2,
instance_size=ec2.InstanceSize.SMALL
)
default_vpc = ec2.Vpc.from_lookup(
self,
"default_vpc",
is_default=True
)
security_groups = ec2.SecurityGroup(
self,
"rds_sg",
vpc=default_vpc,
security_group_name="rds_sg"
)
security_groups.add_ingress_rule(
peer=ec2.Peer.ipv4("172.31.0.0/16"),
connection=ec2.Port.tcp(3306),
)
subnet_group = rds.SubnetGroup(
self,
"private_subnet_group",
description="for private subnets",
vpc=default_vpc,
subnet_group_name="private_subnet_group",
vpc_subnets=ec2.SubnetType.PRIVATE_ISOLATED
)
db_instance = rds.DatabaseInstance(
self,
"db_instance",
storage_encrypted=True,
engine=engine,
database_name="wordpress",
instance_type=instance_type,
vpc=default_vpc,
auto_minor_version_upgrade=False,
instance_identifier="wordpress",
publicly_accessible=False,
security_groups=[security_groups],
subnet_group=subnet_group
)
db_endpoint = CfnOutput(self, "db_endpoint", value=db_instance.instance_endpoint.hostname, export_name="endpoint")
db_secret = CfnOutput(self, "db_secret", value=db_instance.secret.secret_full_arn, export_name="secret")
コード説明
データーベースエンジンバージョン指定
engine = rds.DatabaseInstanceEngine.mysql(
version=rds.MysqlEngineVersion.VER_8_0_28
)
DatabaseInstanceEngine
上記のメソッドでMySQLの8.0.28を使用するように指定します
インスタンスタイプ指定
instance_type = ec2.InstanceType.of(
instance_class=ec2.InstanceClass.BURSTABLE2,
instance_size=ec2.InstanceSize.SMALL
)
InstanceType
上記のメソッドでインスタンスタイプを指定します
VPC指定
default_vpc = ec2.Vpc.from_lookup(
self,
"default_vpc",
is_default=True
)
Vpc
上記のメソッドでデフォルトのVPCを指定します
注意点としてはapp.pyのenv引数にアカウントIDとリージョンを指定しないとエラーが発生します (アカウントIDは環境によって変更してください)
jsii.errors.JSIIError: Cannot retrieve value from context provider vpc-provider since account/region are not specified at the stack level. Configure "env" with an account and region when you define your stack.See https://docs.aws.amazon.com/cdk/latest/guide/environments.html for more details.
以下のように記述すると正常に動きます
#!/usr/bin/env python3
import os
import aws_cdk as cdk
from rds_setup.rds_setup_stack import RdsSetupStack
app = cdk.App()
RdsSetupStack(app, "RdsSetupStack",
env=cdk.Environment(account='アカウントID', region='ap-northeast-1')
)
app.synth()
セキュリティグループ作成
security_groups = ec2.SecurityGroup(
self,
"rds_sg",
vpc=default_vpc,
security_group_name="rds_sg"
)
security_groups.add_ingress_rule(
peer=ec2.Peer.ipv4("172.31.0.0/16"),
connection=ec2.Port.tcp(3306),
)
SecurityGroup
上記のメソッドでRDSに設定するセキュリティグループを作成します
ec2.Peer.ipv4()はVPCのCIDRにすることでVPC内からはアクセスが可能になります
ここにセキュリティグループIDを追加する場合はec2.Peer.security_group_id()で設定可能です
サブネットグループ作成
subnet_group = rds.SubnetGroup(
self,
"private_subnet_group",
description="for private subnets",
vpc=default_vpc,
subnet_group_name="private_subnet_group",
vpc_subnets=ec2.SubnetType.PRIVATE_ISOLATED
)
SubnetGroup
上記のメソッドでサブネットグループを作成します
ec2.SubnetType.PRIVATE_ISOLATEDでプライベートサブネットが選択されます
RDSインスタンス作成
rds.DatabaseInstance(
self,
"db_instance",
storage_encrypted=True,
engine=engine,
database_name="wordpress",
instance_type=instance_type,
vpc=default_vpc,
auto_minor_version_upgrade=False,
instance_identifier="wordpress",
publicly_accessible=False,
security_groups=[security_groups],
subnet_group=subnet_group
)
DatabaseInstance
上記のメソッドでRDSインスタンスを作成します
注意点としてはstorage_encrypted=Trueにしている時は使用できないインスタンスタイプがあること、パスワードとユーザー名がAWS Secrets Managerに保存されることくらいだと思います
暗号化できないインスタンスタイプ
AWS Secrets Managerに保存したくない場合はCfnDBInstanceを使用して作成することで可能になります
エンドポイント、シークレットARNの出力
db_endpoint = CfnOutput(self, "db_endpoint", value=db_instance.instance_endpoint.hostname, export_name="endpoint")
db_secret = CfnOutput(self, "db_secret", value=db_instance.secret.secret_full_arn, export_name="secret")
CfnOutput
上記のメソッドでパラメータを出力しています
こうすることで他のスタックから参照することが可能になります
他のスタックから参照する場合は以下のように記載すると使用できます
db_endpoint = Fn.import_value("endpoint")
デプロイ
以下のコマンドを順番に実行するとRDSインスタンスが作成されます
cdk bootstrap
cdk synth
cdk deploy
cdk bootstrapを実行するとCDKを使用するのに必要なIAMロールなどが作成されます
cdk synthを実行するとCloudFormationテンプレートが確認できます
cdk deployを実行するとリソースが作成されます。またスタック名を引数に設定することで設定したスタックだけをデプロイすることが可能です
後片付け
以下のコマンドを実行するとスタックが削除されます
cdk destroy
感想
CDKの場合リソースが自動で作成されていることがあるのでそこだけは注意する必要があると感じました。
がっつりCDKを使用したのは初めてでしたが今後もコードで管理したいといった要望が増えると思うので今後も学習を続けたいと思いました。