この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。
はじめに
RDSのイベントについてもログで管理したいという思いから、EventBridgeを利用して、RDSのイベントが発生したログをCloudWatchLogsに出力するまでの構築をCFnで構築してみました。
構成図
①VPC作成
②RDS作成
③EventBridge及びCloudWatchLogs作成
上記順番で構築をしていきます。
ハンズオン
1.VPC作成
以前記載したブログCloudFormationを使ってVPC構築に沿って、VPCを構築していきます。
後続の作業でVPCのCIDRが必要になるので、Outputs
に下記追加部分
を足しておきます。
Outputs:
# VPC
VPC:
Value: !Ref VPC
Export:
Name: !Sub "${PJName}-vpc"
###追加部分##############################
VpcCidr:
Value: !Ref VpcCidr
Export:
Name: !Sub "${PJName}-vpc-cidr"
###ここまで###############################
2.RDS作成
検証用のMySQLを作成していきます。
そのためDBインスタンスクラスもdb.t2.micro
と最小限です。
ただし今後もテンプレートは活用できそうなので、拡張できるようパラメータなどの記載は多め。
AWSTemplateFormatVersion: "2010-09-09"
Description:
RDS for MySQL Create
# ------------------------------------------------------------#
# Metadatas
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Project Name Prefix"
Parameters:
- PJPrefix
- Label:
default: "RDS Configuration"
Parameters:
- DBInstanceName
- MySQLMajorVersion
- MySQLMinorVersion
- DBInstanceClass
- DBInstanceStorageSize
- DBInstanceStorageType
- DBName
- DBMasterUserName
- DBPassword
- MultiAZ
ParameterLabels:
DBInstanceName:
default: "DBInstanceName"
MySQLMajorVersion:
default: "MySQLMajorVersion"
MySQLMinorVersion:
default: "MySQLMinorVersion"
DBInstanceClass:
default: "DBInstanceClass"
DBInstanceStorageSize:
default: "DBInstanceStorageSize"
DBInstanceStorageType:
default: "DBInstanceStorageType"
DBName:
default: "DBName"
DBMasterUserName:
default: "DBUserName"
DBPassword:
default: "DBPassword"
MultiAZ:
default: "MultiAZ"
CopyTagsToSnapshot:
default: "CopyTagsToSnapshot"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
PJPrefix:
Type: String
Default: "cfn-inamura"
DBInstanceName:
Type: String
Default: "mysql"
MySQLMajorVersion:
Type: String
Default: "8.0"
MySQLMinorVersion:
Type: String
Default: "28"
AllowedValues: [ "31", "30", "28", "27", "26", "25", "23" ]
DBInstanceClass:
Type: String
Default: "db.t2.micro"
DBInstanceStorageSize:
Type: String
Default: "20"
DBInstanceStorageType:
Type: String
Default: "gp2"
DBName:
Type: String
Default: "db"
DBMasterUserName:
Type: String
Default: "dbuser"
NoEcho: true
MinLength: 1
MaxLength: 16
AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
ConstraintDescription: "must begin with a letter and contain only alphanumeric characters."
DBPassword:
Default: "dbpassword"
NoEcho: true
Type: String
MinLength: 8
MaxLength: 41
AllowedPattern: "[a-zA-Z0-9]*"
ConstraintDescription: "must contain only alphanumeric characters."
MultiAZ:
Default: "false"
Type: String
AllowedValues: [ "true", "false" ]
CopyTagsToSnapshot:
Default: "false"
Type: String
AllowedValues: [ "true", "false" ]
Resources:
# ------------------------------------------------------------#
# DBInstance MySQL
# ------------------------------------------------------------#
DBInstance:
Type: "AWS::RDS::DBInstance"
Properties:
DBInstanceIdentifier: !Sub "${PJPrefix}-${DBInstanceName}"
Engine: MySQL
EngineVersion: !Sub "${MySQLMajorVersion}.${MySQLMinorVersion}"
DBInstanceClass: !Ref DBInstanceClass
AllocatedStorage: !Ref DBInstanceStorageSize
StorageType: !Ref DBInstanceStorageType
DBName: !Ref DBName
MasterUsername: !Ref DBMasterUserName
MasterUserPassword: !Ref DBPassword
DBSubnetGroupName: !Ref DBSubnetGroup
PubliclyAccessible: false
MultiAZ: !Ref MultiAZ
PreferredBackupWindow: "18:00-18:30"
PreferredMaintenanceWindow: "sat:19:00-sat:19:30"
AutoMinorVersionUpgrade: false
DBParameterGroupName: !Ref DBParameterGroup
VPCSecurityGroups:
- !Ref RDSSecurityGroup
CopyTagsToSnapshot: !Ref CopyTagsToSnapshot
BackupRetentionPeriod: 7
Tags:
- Key: "Name"
Value: !Ref DBInstanceName
DeletionPolicy: "Delete"
# ------------------------------------------------------------#
# DBParameterGroup
# ------------------------------------------------------------#
DBParameterGroup:
Type: "AWS::RDS::DBParameterGroup"
Properties:
Family: !Sub "MySQL${MySQLMajorVersion}"
Description: !Sub "${PJPrefix}-${DBInstanceName}-parm"
# ------------------------------------------------------------#
# SecurityGroup for RDS(MySQL)
# ------------------------------------------------------------#
RDSSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: !ImportValue cfn-inamura-vpc
GroupName: !Sub "${PJPrefix}-${DBInstanceName}-sg"
GroupDescription: "-"
Tags:
- Key: "Name"
Value: !Sub "${PJPrefix}-${DBInstanceName}-sg"
# Rule
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: !ImportValue cfn-inamura-vpc-cidr
# ------------------------------------------------------------#
# DBSubnetGroup
# ------------------------------------------------------------#
DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupName: !Sub "${PJPrefix}-${DBInstanceName}-subnet"
DBSubnetGroupDescription: "-"
SubnetIds:
- !ImportValue cfn-inamura-private-subneta
- !ImportValue cfn-inamura-private-subnetc
# ------------------------------------------------------------#
# Output Parameters
# ------------------------------------------------------------#
Outputs:
#DBInstance
DBInstanceID:
Value: !Ref DBInstance
Export:
Name: !Sub "${PJPrefix}-${DBInstanceName}-id"
DBInstanceEndpoint:
Value: !GetAtt DBInstance.Endpoint.Address
Export:
Name: !Sub "${PJPrefix}-${DBInstanceName}-endpoint"
DBName:
Value: !Ref DBName
Export:
Name: !Sub "${PJPrefix}-${DBInstanceName}-dbname"
3.EventBridge、ログ出力先CloudwatchLogs作成
リソースポリシーを作成してEventBridgeに、CloudWatchlogsへログを出力させます。
当初はIAMロールをつくって、どうしたらいいのか分からずハマりました。
AWS公式:AWS::Logs::ResourcePolicy
AWSTemplateFormatVersion: "2010-09-09"
Description:
EventBridge gets RDS events and sends them to CloudWatchlogs
# ------------------------------------------------------------#
# Metadatas
# ------------------------------------------------------------#
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Project Name Prefix"
Parameters:
- PJPrefix
- Label:
default: "CloudWatchLogs Configuration"
Parameters:
- LogGroupName
- Label:
default: "EventBridge Configuration"
Parameters:
- EventBridgeRuleName
- TargetRDSName
ParameterLabels:
LogGroupName:
default: "LogGroupName"
EventBridgeRuleName:
default: "EventBridgeRuleName"
TargetRDSName:
default: "TargetRDSName"
# ------------------------------------------------------------#
# Input Parameters
# ------------------------------------------------------------#
Parameters:
PJPrefix:
Type: String
Default: "cfn-inamura"
LogGroupName:
Type: String
Default: "/aws/events/rdbevents"
EventBridgeRuleName:
Type: String
Default: "SendCloudWatchlogs"
TargetRDSName:
Type: String
Default: "cfn-inamura-mysql"
# ------------------------------------------------------------#
# ResourcePolicy
# ------------------------------------------------------------#
Resources:
ResourcePolicyForEventsToLogs:
Type: AWS::Logs::ResourcePolicy
Properties:
PolicyName: !Sub "${PJPrefix}-evb-resourcepolicy"
PolicyDocument: !Sub
- |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "${CloudWatchLogsLogGroupArn}"
}
]
}
- CloudWatchLogsLogGroupArn: !GetAtt RDSEventsLogGroup.Arn
# ------------------------------------------------------------#
# CloudWatchLogs
# ------------------------------------------------------------#
RDSEventsLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "${LogGroupName}"
# ------------------------------------------------------------#
# EventBridge
# ------------------------------------------------------------#
RDSEventsRule:
Type: AWS::Events::Rule
DependsOn: ResourcePolicyForEventsToLogs
Properties:
Name: !Sub "${PJPrefix}-evb-${EventBridgeRuleName}"
Description: "Get RDS events and send them to CloudWatchlogs"
State: ENABLED
EventPattern:
source:
- aws.rds
detail-type:
- "RDS DB Instance Event"
resources:
- !Sub "arn:${AWS::Partition}:rds:${AWS::Region}:${AWS::AccountId}:db:${TargetRDSName}"
Targets:
- Arn: !GetAtt RDSEventsLogGroup.Arn
Id: !Sub "RDSEventsLogGroup"
挙動の確認
①RDBを再起動する
②再起動後CloudWatchLogsの/aws/events/rdbevents
を確認すると、ログストリームに2つのログが確認できる。
・下記画面は、新しいタイムスタンプ詳細内容を表示したもので"Message": "DB instance restarted"
のイベント内容が確認できる。
③EventBridgeのモニタリング(CloudWatchメトリクス)でもオレンジ点で起動していることを確認できる。
さいごに
リソースポリシーの構築及び、CFnの書き方など勉強すべき部分は多々あるので、こういった構築の方法をを自分で考えながら手を動かして作っていくようにしていきます。
参考
CloudWatch Logsのリソースポリシー作成がCloudFormationに対応していた!