AWS

Aurora ServerlessのData APIを有効化してEC2/Lambdaから接続する

スポンサーリンク
Aurora ServerlessのData APIを有効化してEC2/Lambdaから接続する AWS
スポンサーリンク
スポンサーリンク

Aurora ServerlessのData APIを有効化してEC2(AWS CLI)とLambda(Boto3)から接続する

以下のページで、Aurora Serverlessの基本的な事項について取り上げました。

Aurora Serverless v1の特徴の1つに、Data APIがあります。

Aurora Serverless v1 の Data API を使用すると、Aurora Serverless v1 DB クラスターへのウェブサービスインターフェイスを操作できます。Data API は、DB クラスターへの永続的な接続を必要としません。代わりに、セキュア HTTP エンドポイントおよび AWS SDK との統合を利用できます。

Aurora Serverless v1 の Data API の使用

本ページでは、Data APIを使用して、EC2インスタンスおよびLambda関数からAurora Serverlessに接続します。

構築する環境

Diagram of connect Aurora Serverless from EC2/Lambda using Data API.

VPC内に3つのサブネットを作成します。
いずれもインターネットにアクセス不可なプライベートサブネットとします。

Aurora Serverlessを作成し、AZが異なる2つのサブネットと関連付けます。
MySQLタイプの最新のバージョンを指定します。
Data APIを有効化します。

EC2インスタンスを作成します。
Aurora Serverlessに接続するクライアントです。
OSは最新版のAmazon Linux 2とします。

SSM用のエンドポイントを作成します。
SSM Session Managerを使用して、EC2インスタンスにリモートアクセスするためです。

RDS Data用のエンドポイントも作成します。
Data APIを使用して、EC2インスタンスからAurora Serverlessに接続するためです。

VPC外にLambda関数を作成します。
こちらもAurora Serverlessに接続するクライアントです。
ランタイム環境にPython3.8を選択し、Function URLを有効化します。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

awstut-fa/059 at main · awstut-an-r/awstut-fa
Contribute to awstut-an-r/awstut-fa development by creating an account on GitHub.

テンプレートファイルのポイント解説

本ページはAurora ServerlessのData APIを有効化し、EC2/Lambdaから接続する方法を取り上げます。
Aurora Serverlessに関する基本的な事項については、冒頭にご紹介したページをご確認ください。

セキュリティグループ

Resources: InstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-InstanceSecurityGroup" GroupDescription: Deny All. VpcId: !Ref VPC DBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-DBSecurityGroup" GroupDescription: DBSecurityGroup. VpcId: !Ref VPC # SecurityGroupIngress: # - IpProtocol: tcp # FromPort: !Ref MySQLPort # ToPort: !Ref MySQLPort # SourceSecurityGroupId: !Ref InstanceSecurityGroup EndpointSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub "${Prefix}-EndpointSecurityGroup" GroupDescription: Allow HTTPS from InstanceSecurityGroup. VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: !Ref HTTPSPort ToPort: !Ref HTTPSPort SourceSecurityGroupId: !Ref InstanceSecurityGroup
Code language: YAML (yaml)

3つのセキュリティグループを定義します。

1つ目はEC2インスタンス用です。
冒頭でご紹介したページと同様に、今回の構成でも、インスタンスに対するインバウンド通信は発生しません。
ですから何もインバウンド通信を許可しません。

2つ目はAurora Serverless用です。
こちらも何もインバウンド通信を許可しません。
今回はData APIを使ってAurora Serverlessに接続するため、MySQLポートを解放する必要はありません。
またData APIでの接続はHTTPS通信によって実行されますが、この通信はAurora ServerlessからData API用エンドポイント向けにアウトバウンド通信のため、こちらもセキュリティグループで許可する必要はありません。

3つ目はVPCエンドポイント用です。
今回はSSM用およびRDS Data用で合計4つのエンドポイントを作成します。
いずれもインスタンスからのHTTPS通信が流れますので、それを反映する内容です。

Aurora Serverless

Resources: DBCluster: Type: AWS::RDS::DBCluster Properties: DatabaseName: !Ref DBName DBClusterIdentifier: !Ref DBClusterIdentifier DBSubnetGroupName: !Ref DBSubnetGroup EnableHttpEndpoint: true Engine: !Ref DBEngine EngineMode: serverless EngineVersion: !Ref DBEngineVersion MasterUsername: !Ref DBMasterUsername MasterUserPassword: !Ref DBMasterUserPassword StorageEncrypted: true VpcSecurityGroupIds: - !Ref DBSecurityGroup
Code language: YAML (yaml)

ポイントはEnableHttpEndpointプロパティです。
Aurora ServerlessでData APIを有効化するためには、本プロパティに「true」を設定します。
この設定によってData API用のHTTPエンドポイントが用意されます。

他は特別な設定は不要です。

Secrets Manager

Resources: Secret: Type: AWS::SecretsManager::Secret Properties: Name: !Sub "${Prefix}-Secret" SecretString: !Sub '{"username":"${DBMasterUsername}","password":"${DBMasterUserPassword}"}'
Code language: YAML (yaml)

Data APIを使用してAurora Serverlessに接続するためには、Sercrets Managerを使用する必要があります。

Data API は AWS Secrets Manager に保存されたデータベース認証情報を使用するため、ユーザーは Data API の呼び出しで認証情報を渡す必要はありません。

Aurora Serverless v1 の Data API の使用

具体的には、Aurora DBクラスターを定義時に設定したマスターユーザーとパスワードに関する情報からシークレットを作成します。
SecretStringプロパティに、JSON形式でシークレット文字列を定義します。
2つの情報はそれぞれussername、passwordの値として設定します。

VPCエンドポイント

Resources: RDSDataEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref EndpointSecurityGroup ServiceName: !Sub "com.amazonaws.${AWS::Region}.rds-data" SubnetIds: - !Ref PrivateSubnet1 VpcEndpointType: Interface VpcId: !Ref VPC #S3Endpoint: # Type: AWS::EC2::VPCEndpoint # Properties: # RouteTableIds: # - !Ref PrivateRouteTable # ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" # VpcId: !Ref VPC
Code language: YAML (yaml)

Data APIを使用してAurora Serverlessに接続するためには、Data API用HTTPエンドポイント向けに通信を行います。
プライベートサブネット内のEC2インスタンスが、同エンドポイント向けに通信を行うためには、RDS Data用VPCエンドポイントを作成する必要があります。

詳細につきましては、以下のAWS公式ページをご確認ください。

Aurora Serverless v1 の Data API の使用 - Amazon Aurora
Aurora Serverless v1 の Data API を使用すると、 Aurora Serverless v1 DB クラスターへのウェブサービスインターフェイスを操作できます。Data API は、DB クラスターへの永続的な接続を必要としません。代わりに、セキュア HTTP エンドポイントおよび AWS ...

なお冒頭でご紹介したページとは異なり、S3用VPCエンドポイントは作成しません。
本エンドポイントは、プライベートサブネット上のインスタンスが、S3上に構築されたyumリポジトリにアクセスし、MySQLクライアントパッケージをインストールするために使用しました。
しかし今回はMySQL通信ではなく、HTTPS通信によってAurora Serverlessと通信します。
ですからクライアントパッケージは不要となり、本エンドポイントも不要となります。

EC2インスタンス

Resources: Instance: Type: AWS::EC2::Instance Properties: IamInstanceProfile: !Ref InstanceProfile ImageId: !Ref ImageId InstanceType: !Ref InstanceType NetworkInterfaces: - DeviceIndex: 0 SubnetId: !Ref PrivateSubnet GroupSet: - !Ref InstanceSecurityGroup #UserData: !Base64 | # #!/bin/bash -xe # yum update -y # yum install -y mariadb
Code language: YAML (yaml)

Data APIを使用して、Aurora Serverlessに接続するクライアントとしてのEC2インスタンスです。

先述の通り、MySQLクライアントは不要ですので、ユーザーデータを使用したパッケージのインストールは実行しません。

Lambda関数

Resources: Function: Type: AWS::Lambda::Function Properties: Environment: Variables: DBCLUSTER_ARN: !Ref DBClusterArn DBNAME: !Ref DBName DBTABLE: !Ref DBTableName REGION: !Ref AWS::Region SECRET_ARN: !Ref SecretArn Code: ZipFile: | import boto3 import json import os dbcluster_arn = os.environ['DBCLUSTER_ARN'] dbname = os.environ['DBNAME'] dbtable = os.environ['DBTABLE'] region = os.environ['REGION'] secret_arn = os.environ['SECRET_ARN'] sql = 'select * from {table};'.format(table=dbtable) client = boto3.client('rds-data', region_name=region) def lambda_handler(event, context): response = client.execute_statement( database=dbname, resourceArn=dbcluster_arn, schema='mysql', secretArn=secret_arn, sql=sql ) return { 'statusCode': 200, 'body': json.dumps(response, indent=2) } FunctionName: !Sub "${Prefix}-function" Handler: !Ref Handler Runtime: !Ref Runtime Role: !GetAtt FunctionRole.Arn
Code language: YAML (yaml)

Data APIを使用して、Aurora Serverlessに接続するクライアントとしてのLambda関数です。

インライン表記で実行するコードを定義します。
詳細については、以下のページをご確認ください。

Environmentプロパティで、環境変数として、DBクラスターやSecrets Managerシークレット等のパラメータを設定します。
コード内では、os.envrionで環境変数にアクセスします。

Boto3を使用して、RDS Data用クライアントオブジェクトを作成します。
execute_statementを実行して、Aurora Serverlessに接続します。
先述の各種パラメータを引数として渡します。
なお実行するSQL分ですが、特定のテーブル(Pets)内のテーブルを取得する内容です。
SQLの実行結果を関数の実行結果として返します。

Function URLを有効化します。
特定のURLからLambda関数を実行できる機能です。
Function URLの詳細については、以下のページをご確認ください。

IAMロール

Resources: InstanceRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: - ec2.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore FunctionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Principal: Service: - lambda.amazonaws.com ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole AuroraServerlessDataAPIPolicy: Type: AWS::IAM::Policy Properties: PolicyName: !Sub "${Prefix}-AuroraServerlessDataAPIPolicy" PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - secretsmanager:GetSecretValue Resource: - !Ref SecretArn - Effect: Allow Action: - rds-data:BatchExecuteStatement - rds-data:BeginTransaction - rds-data:CommitTransaction - rds-data:ExecuteStatement - rds-data:RollbackTransaction Resource: - !Ref DBClusterArn Roles: - !Ref FunctionRole - !Ref InstanceRole
Code language: YAML (yaml)

EC2インスタンスおよびLambda関数用のIAMロールを作成します。
両者に共通する権限は、IAMポリシーとして定義します。

ポイントは2つです。
1つ目はSecrets Managerへのアクセスです。
先述のシークレットにアクセスする権限を与えます。

2つ目はData APIを使用するための権限です。
先述のAurora Server DBクラスターに対して、SQLを実行するための最低限の権限を与えます。

なお今回の設定は以下のページを参考に設定しました。

Aurora Serverless v1 の Data API の使用 - Amazon Aurora
Aurora Serverless v1 の Data API を使用すると、 Aurora Serverless v1 DB クラスターへのウェブサービスインターフェイスを操作できます。Data API は、DB クラスターへの永続的な接続を必要としません。代わりに、セキュア HTTP エンドポイントおよび AWS ...

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • EC2インスタンス:i-02b21e07f33a5074c
  • Lambda関数:fa-059-function
  • Lambda関数のFunction URL:https://7vgt4c3bmf7n3xp7htprqdhi5u0tfdms.lambda-url.ap-northeast-1.on.aws/
  • Aurora Serverlessに作成するデータベース名:testdb
  • Aurora Serverlessのデータベースに作成するテーブル名:Pets
  • Aurora Serverless DBクラスターのARN:arn:aws:rds:ap-northeast-1:[account-id]:cluster:fa-059-dbcluster
  • Secrets ManagerシークレットのARN:arn:aws:secretsmanager:ap-northeast-1:[account-id]:secret:fa-059-Secret-poaIGs

AWS Management ConsoleからもAurora Serverlessの作成状況を確認します。

Detail of Aurora Serverless 1.
Detail of Aurora Serverless 2.

正常にAurora Serverlessが作成されています。
そしてData APIが有効化されていることも確認できます。

動作確認

EC2インスタンス

準備が整いましたので、EC2インスタンスにアクセスします。
インスタンスへのアクセスはSSM Session Managerを使用します。

% aws ssm start-session --target i-02b21e07f33a5074c Starting session with SessionId: root-0815f8b32141bb9b4 sh-4.2$
Code language: Bash (bash)

SSM Session Managerの詳細につきましては、以下のページをご確認ください。

AWS CLIからData APIを使用して、Aurora Serverlessに接続します。
まずAurora ServerlessのデータベースにPetsテーブルを作成します。

sh-4.2$ aws rds-data execute-statement \ --resource-arn "arn:aws:rds:ap-northeast-1:[account-id]:cluster:fa-059-dbcluster" \ --schema "mysql" \ --secret-arn "arn:aws:secretsmanager:ap-northeast-1:[account-id]:secret:fa-059-Secret-poaIGs" \ --region ap-northeast-1 \ --sql "create table Pets(id varchar(200), type varchar(200), price float)" \ --database "testdb" { "numberOfRecordsUpdated": 0, "generatedFields": [] }
Code language: Bash (bash)

正常に実行されました。

次に作成したテーブルにレコードを追加します。

sh-4.2$ aws rds-data execute-statement \ --resource-arn "arn:aws:rds:ap-northeast-1:[account-id]:cluster:fa-059-dbcluster" \ --schema "mysql" \ --secret-arn "arn:aws:secretsmanager:ap-northeast-1:[account-id]:secret:fa-059-Secret-poaIGs" \ --region ap-northeast-1 \ --sql "insert into Pets values (111, 'dog', 123)" \ --database "testdb" { "numberOfRecordsUpdated": 1, "generatedFields": [] }
Code language: YAML (yaml)

こちらも正常に実行されました。

追加されたレコードを確認します。

sh-4.2$ aws rds-data execute-statement \ --resource-arn "arn:aws:rds:ap-northeast-1:[account-id]:cluster:fa-059-dbcluster" \ --schema "mysql" \ --secret-arn "arn:aws:secretsmanager:ap-northeast-1:[account-id]:secret:fa-059-Secret-poaIGs" \ --region ap-northeast-1 \ --sql "select * from Pets" \ --database "testdb" { "records": [ [ { "stringValue": "111" }, { "stringValue": "dog" }, { "doubleValue": 123.0 } ] ], "numberOfRecordsUpdated": 0 }
Code language: JavaScript (javascript)

保存されたレコードを取得することができました。

以上の通り、EC2インスタンスにおいて、Data APIを使用して、AWS CLIからAurora Serverlessに接続することができました。

Lambda関数

関数の実行はFunction URLにアクセスして行います。
以下が実行結果です。

Result of Aurora Serverless Data API.

こちらも正常に実行されました。

以上の通り、Lambda関数において、Data APIを使用して、Aurora Serverlessに接続することができました。

まとめ

Aurora ServerlessでData APIを有効化する方法を確認しました。

EC2インスタンスおよびLambda関数からData APIを使用する方法も確認しました。

タイトルとURLをコピーしました