😑
#05 AWS CDKの準備(2023.10)
1. はじめに
CDKを使ってRDSまわりの環境を準備した時のメモです。
RDS構築に必要なネットワーク関連のStackを記載しています。
CDKで構築した環境の上に、SAMとCloud9使い、動作確認用のアプリを構築しています。
セットアップ対象のバージョン
- nvm 0.39.0
- python 3.11.2
- pip 23.2.1
- aws-cli 1.29.20
- cdk 2.82.0
今回、WSL2からコマンドを実行しています。
WSL2を初めて構築する人は参考にしてください。
#01 WSLを使った作業環境を準備した時のメモ(2023.10)
First CDK
AWS CDKはじめてのアプリを参照してデプロイ環境を整えます。
command
$ aws sts get-caller-identity --query 'Account' --output text // 操作アカウントの確認
$ aws configure get region // リージョン確認
$ npm install -g aws-cdk
$ cdk --version
$ mkdir my-project
$ cd my-project
$ cdk init app --language python
$ tree -L 1
.
├── README.md
├── app.py
├── cdk.json
├── my_project
│ ├── __init__.py
│ └── my_project_stack.py
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests
$ source .venv/bin/activate
$ python -m pip install -r requirements.txt
CDKスクリプト作成
my_project_stack.py を書き換えます。
サンプルの内容
-
RDSのインストールと、RDSをデプロイする先のネットワークをセットアップします。
-
サブネットは、PRIVATE_WITH_NATを選択しています。
- PUBLIC: 公開用パブリックセグメント利用- PRIVATE_WITH_NAT: プライベートセグメントだが、NATを通して外部に接続可能
- PRIVATE_ISOLATED: プライベートセグメント(外部接続不可) ※今回未使用
-
max_azs=2 … AZゾーンを二つにデプロイします。
-
nat_gateways=1 … NATGATEWAYを有効にしています。
-
サブネットマスク: /24 ※AWS/16を推奨
-
セキュリティグループ: EC2,RDSのそれぞれ作成
-
cdk.RemovalPolicy.DESTROY: CDKコマンドから削除を許可する。
-
allow_all_outbound=False : 全てのアウトバンドをブロックする
-
DBにはアカウント:rootでアクセスします。パスワードは、AWSマネージド画面から設定する
-
STACKファイル(my_project_stack.py)
python
from aws_cdk import (
Duration,
aws_ec2 as ec2,
aws_rds as rds
)
from constructs import Construct
import aws_cdk as cdk
class RdsStack(cdk.Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
#------------------------------
# region CONSTRUCT COMMON TAG
cdk.Tags.of(scope).add("owner", "SAM SUN")
cdk.Tags.of(scope).add("start", "20230101")
cdk.Tags.of(scope).add("end", "20231231")
cdk.Tags.of(scopt).add("purpose", "FIRST CDK")
#------------------------------
# endregion
#------------------------------
#region VPC & Subnet
my_vpc = ec2.Vpc(self, "Vpc",
vpc_name="my-vpc",
cidr="10.0.0.0/16",
max_azs=2,
nat_gateways=1,
subnet_configuration=[
ec2.SubnetConfiguration(
name="my-public",
cidr_mask=24,
subnet_type=ec2.SubnetType.PUBLIC
),
ec2.SubnetConfiguration(
name="my-private",
cidr_mask=24,
subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT
)
]
# DB Subnet
my_dbsubnet = rds.SubnetGroup(self, "DBSubnet",
vpc=my_vpc,
description="Subnet Group for RDS",
removal_policy=cdk.RemovalPolicy.DESTROY,
subnet_group_name="my-private",
vpc_subnets=ec2.SubnetSelection(
subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT
)
)
#endregion
#------------------------------
#------------------------------
# region Security Group
Security Group(EC2)
my_sg_ec2 = ec2.SecurityGroup(self, "SgEC2",
vpc=my_vpc,
security_group_name="my-sg-ec2",
description="Security Group for EC2",
allow_all_outbound=False
)
# Security Group(RDS)
my_sg_rds = ec2.SecurityGroup(self, "SgRDS",
vpc=my_vpc,
security_group_name="my-sg-rds",
description="Security Group for RDS",
allow_all_outbound=False
)
#------------------------------
# endregion Security Group
#------------------------------
# region DB SETUP
#DB Instance Engine
my_dbengine = rds.DatabaseInstanceEngine.mysql(
version=rds.MysqlEngineVersion.VER_8_0_28
)
# Database Credential
my_secret_rds = rds.DatabaseSecret(self, "RdsSecret",
username="root",
secret_name="my-secret-rds"
)
my_credentials_rds = rds.Credentials.from_secret(
secret=my_secret_rds
)
# RDS
my_rds = rds.DatabaseInstance(self, "Rds",
vpc=my_vpc,
engine=my_dbengine,
instance_type=ec2.InstanceType.of(
ec2.InstanceClass.BURSTABLE2,
ec2.InstanceSize.SMALL
),
instance_identifier="my-rds",
multi_az=True,
publicly_accessible=False,
removal_policy=cdk.RemovalPolicy.DESTROY,
security_groups=[my_sg_rds],
subnet_group=my_dbsubnet,
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT),
credentials=my_credentials_rds,
allocated_storage=20,
backup_retention=Duration.days(0),
delete_automated_backups=True,
deletion_protection=False,
port=3306
)
# Add Allow Connection to RDS
my_rds.connections.allow_from(my_sg_ec2, ec2.Port.tcp(3306))
#------------------------------
# endregion
- デプロイコマンド
command
$ cdk bootstrap
---
Bootstrapping environment aws://************/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
Environment aws://************/ap-northeast-1 bootstrapped.
---
$ cdk deploy
動作確認用アプリケーション作成
mysqlを利用した時のメモをアップしました。
作業メモ#05 mysql準備
動作確認用アプリケーション(Lamda)作成
my_project_stack.py を書き換えます。
import json
import sys
import os
import mysql.connector
DB_USER = "user"
DB_PASSWORD = "123456789Aa#"
DB_HOST = "xxxxxxxx.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com"
DB_NAME = "sample"
DB_PORT = "3306"
conn = mysql.connector.connect(
host=DB_HOST,
port=DB_PORT,
user=DB_USER,
password=DB_PASSWORD,
database=DB_NAME
)
cur = conn.cursor(buffered=True)
def lambda_handler(event, context):
try:
sql_str = 'select * from student;'
cur.execute(sql_str)
cur.close()
res = {"message": "Success"}
return {
'statusCode': 200,
'body': "Success"
}
except Exception as e:
cur.close()
print(e)
return {
'statusCode': 403,
'body': "No Stuent found"
}
Discussion