1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS CDK実行環境とRDSを作成してみた

Posted at

ご挨拶

最近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

環境作成

Cloud9
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」というファイルが作成されるのでこれを編集していきます。

作成したコード

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")

コード説明

データーベースエンジンバージョン指定

rds_setup_stack.py
        engine = rds.DatabaseInstanceEngine.mysql(
            version=rds.MysqlEngineVersion.VER_8_0_28
            )

DatabaseInstanceEngine
上記のメソッドでMySQLの8.0.28を使用するように指定します

インスタンスタイプ指定

rds_setup_stack.py
        instance_type = ec2.InstanceType.of(
            instance_class=ec2.InstanceClass.BURSTABLE2,
            instance_size=ec2.InstanceSize.SMALL
            )

InstanceType
上記のメソッドでインスタンスタイプを指定します

VPC指定

rds_setup_stack.py
        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.

以下のように記述すると正常に動きます

app.py
#!/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()

セキュリティグループ作成

rds_setup_stack.py
        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()で設定可能です

サブネットグループ作成

rds_setup_stack.py
        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_setup_stack.py
        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の出力

rds_setup_stack.py
        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インスタンスが作成されます

Cloud9
cdk bootstrap
cdk synth
cdk deploy

cdk bootstrapを実行するとCDKを使用するのに必要なIAMロールなどが作成されます
cdk synthを実行するとCloudFormationテンプレートが確認できます
cdk deployを実行するとリソースが作成されます。またスタック名を引数に設定することで設定したスタックだけをデプロイすることが可能です

後片付け

以下のコマンドを実行するとスタックが削除されます

Cloud9
cdk destroy

感想

CDKの場合リソースが自動で作成されていることがあるのでそこだけは注意する必要があると感じました。
がっつりCDKを使用したのは初めてでしたが今後もコードで管理したいといった要望が増えると思うので今後も学習を続けたいと思いました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?