【AWS】CloudformationでRDSと
1. 使用するサービス
(AWS)
- Cloudformation
- Lambda
- Subnet
- Security Group
- RDS
- RDS Proxy
2.概要
仕事でCloudformationを触る機会が増えたので備忘録として残します。最近グローバルリリースされたRDS Proxyを検索しても中々これといったCloudformationで作成した記事が無いので色々、調べた結果作成されたテンプレートを載せます。
3. 実装
3-1. 実装イメージ
各種セキュリティグループでアクセス制御します。RDSのパスワード等はSystem Managerに保管します。
3-2. テンプレート
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: Outputs the time Parameters: DBName: Description: "DB Name" Default: test Type: String Resources: TestFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: python3.8 CodeUri: ./test Role: !GetAtt TestRole.Arn VpcConfig: SecurityGroupIds: - !Ref TestLambdaSecurityGroup SubnetIds: - !Ref TestPubSubnet1a - !Ref TestPubSubnet1c Environment: Variables: RDSEndpoint: !GetAtt RDSProxyTest.Endpoint MasterUsername: !Sub '{{resolve:secretsmanager:${RDSTestInstanceRotationSecret}:SecretString:username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${RDSTestInstanceRotationSecret}:SecretString:password}}' DBName: !Ref DBName TestRole: Type: AWS::IAM::Role Properties: RoleName: "TestRole" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "lambda.amazonaws.com" Action: - "sts:AssumeRole" ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - arn:aws:iam::aws:policy/AmazonRDSFullAccess - arn:aws:iam::aws:policy/AmazonEC2FullAccess MaxSessionDuration: 3600 Path: "/" TestVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 Tags: - Key: "Name" Value: "TestVpc" TestPubSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: Ref: TestVPC CidrBlock: 10.0.1.0/24 AvailabilityZone: "ap-northeast-1a" Tags: - Key: "Name" Value: "TestPubSubnet1a" TestPubSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: Ref: TestVPC CidrBlock: 10.0.2.0/24 AvailabilityZone: "ap-northeast-1c" Tags: - Key: "Name" Value: "TestPubSubnet1c" TestPriSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: Ref: TestVPC CidrBlock: 10.0.3.0/24 AvailabilityZone: "ap-northeast-1a" Tags: - Key: "Name" Value: "TestPriSubnet1a" TestPriSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: Ref: TestVPC CidrBlock: 10.0.4.0/24 AvailabilityZone: "ap-northeast-1c" Tags: - Key: "Name" Value: "TestPriSubnet1c" TestLambdaSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Nothing VpcId: Ref: TestVPC Tags: - Key: "Name" Value: "TestLambdaSecurityGroup" TestRDSSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow mysql to client host VpcId: Ref: TestVPC Tags: - Key: "Name" Value: "TestRDSSecurityGroup" TestRDSSecurityIngress: Type: 'AWS::EC2::SecurityGroupIngress' Properties: GroupId: !Ref TestRDSSecurityGroup IpProtocol: tcp FromPort: 3306 ToPort: 3306 SourceSecurityGroupId: !GetAtt TestRDSProxySecurityGroup.GroupId TestRDSProxySecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow mysql to client host VpcId: Ref: TestVPC Tags: - Key: "Name" Value: "TestRDSProxySecurityGroup" TestRDSProxySecurityIngress: Type: 'AWS::EC2::SecurityGroupIngress' Properties: GroupId: !Ref TestRDSProxySecurityGroup IpProtocol: tcp FromPort: 3306 ToPort: 3306 SourceSecurityGroupId: !GetAtt TestLambdaSecurityGroup.GroupId TestDBInstance: Type: 'AWS::RDS::DBInstance' Properties: AllocatedStorage: 20 DBInstanceClass: db.t2.micro DBInstanceIdentifier: -rds-test DBName: !Ref DBName DBSubnetGroupName: !Ref TestDBSubnetGroup Engine: mysql EngineVersion: 5.7.22 MasterUsername: !Sub '{{resolve:secretsmanager:${RDSTestInstanceRotationSecret}:SecretString:username}}' MasterUserPassword: !Sub '{{resolve:secretsmanager:${RDSTestInstanceRotationSecret}:SecretString:password}}' PubliclyAccessible: false VPCSecurityGroups: - !GetAtt TestRDSSecurityGroup.GroupId TestDBSubnetGroup: Type: 'AWS::RDS::DBSubnetGroup' Properties: DBSubnetGroupDescription: TestDBSubnetGroup DBSubnetGroupName: TestDBSubnetGroup SubnetIds: - !Ref TestPriSubnet1a - !Ref TestPriSubnet1c RDSProxyTest: Type: 'AWS::RDS::DBProxy' Properties: Auth: - AuthScheme: SECRETS IAMAuth: DISABLED SecretArn: !Ref RDSTestInstanceRotationSecret EngineFamily: MYSQL DBProxyName: -proxy-test IdleClientTimeout: 120 RequireTLS: false RoleArn: !GetAtt SecretsManagerRole.Arn VpcSecurityGroupIds: - !Ref TestRDSProxySecurityGroup VpcSubnetIds: - !Ref TestPriSubnet1a - !Ref TestPriSubnet1c RDSProxyTargetGroupTest: Type: 'AWS::RDS::DBProxyTargetGroup' Properties: DBProxyName: !Ref RDSProxyTest DBInstanceIdentifiers: - !Ref TestDBInstance ConnectionPoolConfigurationInfo: ConnectionBorrowTimeout: 120 MaxConnectionsPercent: 100 MaxIdleConnectionsPercent: 100 TargetGroupName: default RDSTestInstanceRotationSecret: Type: 'AWS::SecretsManager::Secret' Properties: Description: 'This is my rds instance secret' GenerateSecretString: SecretStringTemplate: '{"username": "master"}' GenerateStringKey: "password" PasswordLength: 16 ExcludeCharacters: '"@/\' SecretRDSInstanceAttachment: Type: 'AWS::SecretsManager::SecretTargetAttachment' Properties: SecretId: !Ref RDSTestInstanceRotationSecret TargetId: !Ref TestDBInstance TargetType: 'AWS::RDS::DBInstance' SecretsManagerManagedPolicy: Type: 'AWS::IAM::ManagedPolicy' Properties: Description: "Get values from Secrets Manager" Path: / PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - "secretsmanager:GetResourcePolicy" - "secretsmanager:GetSecretValue" - "secretsmanager:DescribeSecret" - "secretsmanager:ListSecretVersionIds" Resource: !Ref RDSTestInstanceRotationSecret - Effect: Allow Action: - "kms:Decrypt" Resource: !Sub "*" Condition: StringEquals: kms:ViaService: !Sub "secretsmanager.${AWS::Region}.amazonaws.com" SecretsManagerRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - "rds.amazonaws.com" Action: - "sts:AssumeRole" Description: "Use for RDS Proxy" ManagedPolicyArns: - !Ref SecretsManagerManagedPolicy Path: /
何も問題なければこのテンプレートで一から作成されるはずです。
10〜15分くらいデプロイに時間かかると思います。