From ade28d500ee751c124ce7400b9d6f975277084d7 Mon Sep 17 00:00:00 2001 From: Justin Plock Date: Sat, 9 May 2020 10:49:40 -0400 Subject: [PATCH] Improve example to launch RDS in the VPC --- example/package.json | 8 +-- example/resources/iam_cf.yml | 24 ++++---- example/resources/rds_cf.yml | 77 ++++++++++++++++--------- example/resources/secretsmanager_cf.yml | 6 +- 4 files changed, 69 insertions(+), 46 deletions(-) diff --git a/example/package.json b/example/package.json index 616e0355..1bfa1c51 100644 --- a/example/package.json +++ b/example/package.json @@ -16,11 +16,11 @@ "test": "sls invoke -f rds" }, "devDependencies": { - "aws-sdk": "2.656.0", - "serverless": "1.67.3", + "aws-sdk": "2.673.0", + "serverless": "1.70.0", "serverless-vpc-plugin": "smoketurner/serverless-vpc-plugin#master", - "serverless-webpack": "5.3.1", - "webpack": "4.42.1", + "serverless-webpack": "5.3.2", + "webpack": "4.43.0", "webpack-node-externals": "1.7.2" } } diff --git a/example/resources/iam_cf.yml b/example/resources/iam_cf.yml index b3db0d36..f2fecc95 100644 --- a/example/resources/iam_cf.yml +++ b/example/resources/iam_cf.yml @@ -1,29 +1,29 @@ --- Resources: ExampleLambdaRole: - Type: "AWS::IAM::Role" + Type: 'AWS::IAM::Role' Properties: - RoleName: "${self:service}-${self:provider.stage}-${self:provider.region}-ExampleLambdaRole" + RoleName: '${self:service}-${self:provider.stage}-${self:provider.region}-ExampleLambdaRole' AssumeRolePolicyDocument: Statement: - Effect: Allow Principal: - Service: "lambda.amazonaws.com" - Action: "sts:AssumeRole" + Service: 'lambda.amazonaws.com' + Action: 'sts:AssumeRole' Policies: - PolicyName: ExampleLambdaPolicy PolicyDocument: Statement: - Effect: Allow - Action: "secretsmanager:GetSecretValue" + Action: 'secretsmanager:GetSecretValue' Resource: !Ref DBSecret - Effect: Allow Action: - - "rds-data:BatchExecuteStatement" - - "rds-data:BeginTransaction" - - "rds-data:CommitTransaction" - - "rds-data:ExecuteStatement" - - "rds-data:RollbackTransaction" - Resource: "*" + - 'rds-data:BatchExecuteStatement' + - 'rds-data:BeginTransaction' + - 'rds-data:CommitTransaction' + - 'rds-data:ExecuteStatement' + - 'rds-data:RollbackTransaction' + Resource: '*' ManagedPolicyArns: - - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole" + - 'arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole' diff --git a/example/resources/rds_cf.yml b/example/resources/rds_cf.yml index 66b9e9eb..dfcf3b9c 100644 --- a/example/resources/rds_cf.yml +++ b/example/resources/rds_cf.yml @@ -1,48 +1,73 @@ --- Resources: + DBClusterParameterGroup: + Type: 'AWS::RDS::DBClusterParameterGroup' + Properties: + Description: 'Aurora PostgreSQL 10 Parameter Group' + Family: aurora-postgresql10 + Parameters: + rds.force_ssl: 1 + + DBSecurityGroup: + Type: 'AWS::EC2::SecurityGroup' + Properties: + GroupDescription: 'RDS Database Access' + SecurityGroupIngress: + - Description: 'Allow inbound PostgreSQL access from Lambda' + FromPort: 5432 + IpProtocol: tcp + SourceSecurityGroupId: !GetAtt LambdaExecutionSecurityGroup.GroupId + ToPort: 5432 + VpcId: !Ref VPC + DBCluster: Type: 'AWS::RDS::DBCluster' + DeletionPolicy: Snapshot Properties: DatabaseName: ${self:custom.databaseName} DBClusterIdentifier: '${self:service}-${self:provider.stage}' - DBSubnetGroupName: - Ref: RDSSubnetGroup + DBClusterParameterGroupName: !Ref DBClusterParameterGroup + DBSubnetGroupName: !Ref RDSSubnetGroup EnableHttpEndpoint: true Engine: aurora-postgresql EngineMode: serverless - EngineVersion: '11.4' + EngineVersion: '10.7' # Data API only supports PostgreSQL 10.7 https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.regions MasterUsername: - 'Fn::Join': - - '' - - - '{{resolve:secretsmanager:' - - Ref: DBSecret - - ':SecretString:username}}' + !Join ['', ['{{resolve:secretsmanager:', !Ref DBSecret, ':SecretString:username}}']] MasterUserPassword: - 'Fn::Join': - - '' - - - '{{resolve:secretsmanager:' - - Ref: DBSecret - - ':SecretString:password}}' + !Join ['', ['{{resolve:secretsmanager:', !Ref DBSecret, ':SecretString:password}}']] + ScalingConfiguration: + AutoPause: true + MaxCapacity: 2 + MinCapacity: 2 + SecondsUntilAutoPause: 300 # 5 minutes StorageEncrypted: true Tags: - Key: Name - Value: - 'Fn::Join': - - '-' - - - Ref: 'AWS::StackName' - - rds + Value: !Join ['-', [!Ref 'AWS::StackName', rds]] + UseLatestRestorableTime: true + VpcSecurityGroupIds: + - !Ref DBSecurityGroup + + DBVpcEndpoint: + Type: 'AWS::EC2::VPCEndpoint' + Properties: + PrivateDnsEnabled: true + ServiceName: !Join ['.', ['com.amazonaws', !Ref 'AWS::Region', 'rds-data']] + SecurityGroupIds: + - !Ref LambdaEndpointSecurityGroup + SubnetIds: + - !Ref AppSubnet1 + - !Ref AppSubnet2 + - !Ref AppSubnet3 + VpcEndpointType: Interface + VpcId: !Ref VPC Outputs: DBClusterAddress: Description: RDS Cluster Address - Value: - 'Fn::GetAtt': - - DBCluster - - 'Endpoint.Address' + Value: !GetAtt DBCluster.Endpoint.Address DBClusterPort: Description: RDS Cluster Port - Value: - 'Fn::GetAtt': - - DBCluster - - 'Endpoint.Port' + Value: !GetAtt DBCluster.Endpoint.Port diff --git a/example/resources/secretsmanager_cf.yml b/example/resources/secretsmanager_cf.yml index 2b41e9f3..4af405f3 100644 --- a/example/resources/secretsmanager_cf.yml +++ b/example/resources/secretsmanager_cf.yml @@ -14,8 +14,6 @@ Resources: DBClusterSecretTargetAttachment: Type: 'AWS::SecretsManager::SecretTargetAttachment' Properties: - SecretId: - Ref: DBSecret - TargetId: - Ref: DBCluster + SecretId: !Ref DBSecret + TargetId: !Ref DBCluster TargetType: 'AWS::RDS::DBCluster'