forked from ksmin23/my-aws-cdk-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
151 lines (131 loc) · 5.99 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
# vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab
import os
import aws_cdk as cdk
from aws_cdk import (
Stack,
aws_ec2,
aws_logs,
aws_rds,
aws_secretsmanager
)
from constructs import Construct
class AuroraMysqlStack(Stack):
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
#XXX: For creating this CDK Stack in the existing VPC,
# remove comments from the below codes and
# comments out vpc = aws_ec2.Vpc(..) codes,
# then pass -c vpc_name=your-existing-vpc to cdk command
# for example,
# cdk -c vpc_name=your-existing-vpc syth
#
# vpc_name = self.node.try_get_context("vpc_name") or "default"
# vpc = aws_ec2.Vpc.from_lookup(self, "ExistingVPC",
# is_default=True,
# vpc_name=vpc_name)
#XXX: To use more than 2 AZs, be sure to specify the account and region on your stack.
#XXX: https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_ec2/Vpc.html
vpc = aws_ec2.Vpc(self, "AuroraMySQLVPC",
max_azs=3,
gateway_endpoints={
"S3": aws_ec2.GatewayVpcEndpointOptions(
service=aws_ec2.GatewayVpcEndpointAwsService.S3
)
}
)
sg_use_mysql = aws_ec2.SecurityGroup(self, 'MySQLClientSG',
vpc=vpc,
allow_all_outbound=True,
description='security group for mysql client',
security_group_name='default-mysql-client-sg'
)
cdk.Tags.of(sg_use_mysql).add('Name', 'default-mysql-client-sg')
sg_mysql_server = aws_ec2.SecurityGroup(self, 'MySQLServerSG',
vpc=vpc,
allow_all_outbound=True,
description='security group for mysql',
security_group_name='default-mysql-server-sg'
)
sg_mysql_server.add_ingress_rule(peer=sg_use_mysql, connection=aws_ec2.Port.tcp(3306),
description='default-mysql-client-sg')
sg_mysql_server.add_ingress_rule(peer=sg_mysql_server, connection=aws_ec2.Port.all_tcp(),
description='default-mysql-server-sg')
cdk.Tags.of(sg_mysql_server).add('Name', 'default-mysql-server-sg')
rds_subnet_group = aws_rds.SubnetGroup(self, 'MySQLSubnetGroup',
description='subnet group for mysql',
subnet_group_name='aurora-mysql',
vpc_subnets=aws_ec2.SubnetSelection(subnet_type=aws_ec2.SubnetType.PRIVATE_WITH_EGRESS),
vpc=vpc
)
rds_engine = aws_rds.DatabaseClusterEngine.aurora_mysql(version=aws_rds.AuroraMysqlEngineVersion.VER_3_01_0)
#XXX: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Reference.html#AuroraMySQL.Reference.Parameters.Cluster
rds_cluster_param_group = aws_rds.ParameterGroup(self, 'AuroraMySQLClusterParamGroup',
engine=rds_engine,
description='Custom cluster parameter group for aurora-mysql8.x',
parameters={
# For Aurora MySQL version 3, Aurora always uses the default value of 1.
# 'innodb_flush_log_at_trx_commit': '2',
'slow_query_log': '1',
# Removed from Aurora MySQL version 3.
# 'tx_isolation': 'READ-COMMITTED',
'wait_timeout': '300',
'character-set-client-handshake': '0',
'character_set_server': 'utf8mb4',
'collation_server': 'utf8mb4_unicode_ci',
'init_connect': 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci',
#'binlog_format': 'ROW' #XXX: Turn on binlog
}
)
#XXX: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Reference.html#AuroraMySQL.Reference.Parameters.Instance
rds_db_param_group = aws_rds.ParameterGroup(self, 'AuroraMySQLDBParamGroup',
engine=rds_engine,
description='Custom parameter group for aurora-mysql8.x',
parameters={
'slow_query_log': '1',
# Removed from Aurora MySQL version 3.
# 'tx_isolation': 'READ-COMMITTED',
'wait_timeout': '300',
'init_connect': 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'
}
)
db_cluster_name = self.node.try_get_context('db_cluster_name')
#XXX: aws_rds.Credentials.from_username(username, ...) can not be given user specific Secret name
# therefore, first create Secret and then use it to create database
db_secret_name = self.node.try_get_context('db_secret_name')
#XXX: arn:{partition}:{service}:{region}:{account}:{resource}{sep}}{resource-name}
db_secret_arn = 'arn:aws:secretsmanager:{region}:{account}:secret:{resource_name}'.format(
region=cdk.Aws.REGION, account=cdk.Aws.ACCOUNT_ID, resource_name=db_secret_name)
db_secret = aws_secretsmanager.Secret.from_secret_partial_arn(self, 'DBSecretFromArn', db_secret_arn)
rds_credentials = aws_rds.Credentials.from_secret(db_secret)
db_cluster = aws_rds.DatabaseCluster(self, 'Database',
engine=rds_engine,
credentials=rds_credentials, # A username of 'admin' (or 'postgres' for PostgreSQL) and SecretsManager-generated password
instance_props={
'instance_type': aws_ec2.InstanceType.of(aws_ec2.InstanceClass.BURSTABLE3, aws_ec2.InstanceSize.MEDIUM),
'parameter_group': rds_db_param_group,
'vpc_subnets': {
'subnet_type': aws_ec2.SubnetType.PRIVATE_WITH_EGRESS
},
'vpc': vpc,
'auto_minor_version_upgrade': False,
'security_groups': [sg_mysql_server]
},
instances=2,
parameter_group=rds_cluster_param_group,
cloudwatch_logs_retention=aws_logs.RetentionDays.THREE_DAYS,
cluster_identifier=db_cluster_name,
subnet_group=rds_subnet_group,
backup=aws_rds.BackupProps(
retention=cdk.Duration.days(3),
preferred_window="03:00-04:00"
)
)
cdk.CfnOutput(self, 'DBClusterEndpoint', value=db_cluster.cluster_endpoint.socket_address, export_name='DBClusterEndpoint')
cdk.CfnOutput(self, 'DBClusterReadEndpoint', value=db_cluster.cluster_read_endpoint.socket_address, export_name='DBClusterReadEndpoint')
app = cdk.App()
AuroraMysqlStack(app, "AuroraMySQLStack", env=cdk.Environment(
account=os.environ["CDK_DEFAULT_ACCOUNT"],
region=os.environ["CDK_DEFAULT_REGION"]))
app.synth()