以下のような設定です。なお、[]内は実際には正しい値が入っています
RDS
- エンジン MySQL
- クラス db.t2.micro
- リソースID [db-xxxxxxxx]
- パブリックアクセシビリティ あり
- IAM db 認証 有効
- ホスト名 [rdshost]
事前に以下の作業を実施済み
mysql
1create database [dbname]; 2create user [dbuser] identified with AWSAuthenticationPlugin as 'RDS'; 3grant all privileges on [dbname].* to [dbuser] REQUIRE SSL;
Lambda
- 関数名 [funcname]
- ハンドラ lambda_function.lambda_handler
- 非VPC
- ロール service-role/[func-role-yyyyyy]
- メモリ 128MB
- タイムアウト 15分
Lambda環境変数
- DB_HOST [rdshost]
- DB_USER [dbuser]
- DB_NAME [dbname]
service-role/[func-role-yyyyyy]ロール設定
以下の4ポリシーをアタッチしています
- AWSLambdaVPCAccessExecutionRole 内容は以下の通りです
json
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Effect": "Allow", 6 "Action": [ 7 "logs:CreateLogGroup", 8 "logs:CreateLogStream", 9 "logs:PutLogEvents", 10 "ec2:CreateNetworkInterface", 11 "ec2:DescribeNetworkInterfaces", 12 "ec2:DeleteNetworkInterface" 13 ], 14 "Resource": "*" 15 } 16 ] 17}
- AmazonRDSDataFullAccess 内容は以下の通りです
json
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Sid": "SecretsManagerDbCredentialsAccess", 6 "Effect": "Allow", 7 "Action": [ 8 "secretsmanager:GetSecretValue", 9 "secretsmanager:PutResourcePolicy", 10 "secretsmanager:PutSecretValue", 11 "secretsmanager:DeleteSecret", 12 "secretsmanager:DescribeSecret", 13 "secretsmanager:TagResource" 14 ], 15 "Resource": "arn:aws:secretsmanager:*:*:secret:rds-db-credentials/*" 16 }, 17 { 18 "Sid": "RDSDataServiceAccess", 19 "Effect": "Allow", 20 "Action": [ 21 "dbqms:CreateFavoriteQuery", 22 "dbqms:DescribeFavoriteQueries", 23 "dbqms:UpdateFavoriteQuery", 24 "dbqms:DeleteFavoriteQueries", 25 "dbqms:GetQueryString", 26 "dbqms:CreateQueryHistory", 27 "dbqms:DescribeQueryHistory", 28 "dbqms:UpdateQueryHistory", 29 "dbqms:DeleteQueryHistory", 30 "dbqms:DescribeQueryHistory", 31 "rds-data:ExecuteSql", 32 "rds-data:ExecuteStatement", 33 "rds-data:BatchExecuteStatement", 34 "rds-data:BeginTransaction", 35 "rds-data:CommitTransaction", 36 "rds-data:RollbackTransaction", 37 "secretsmanager:CreateSecret", 38 "secretsmanager:ListSecrets", 39 "secretsmanager:GetRandomPassword", 40 "tag:GetResources" 41 ], 42 "Resource": "*" 43 } 44 ] 45}
- AWSLambdaBasicExecutionRole-zzzzzzz 内容は以下の通りです
json
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Effect": "Allow", 6 "Action": "logs:CreateLogGroup", 7 "Resource": "arn:aws:logs:ap-northeast-1:[accid]:*" 8 }, 9 { 10 "Effect": "Allow", 11 "Action": [ 12 "logs:CreateLogStream", 13 "logs:PutLogEvents" 14 ], 15 "Resource": [ 16 "arn:aws:logs:ap-northeast-1:[accid]:log-group:/aws/lambda/[funcname]:*" 17 ] 18 } 19 ] 20}
- ConnectToRDS 内容は以下の通りです
json
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Sid": "VisualEditor0", 6 "Effect": "Allow", 7 "Action": "rds-data:*", 8 "Resource": "*" 9 }, 10 { 11 "Sid": "VisualEditor1", 12 "Effect": "Allow", 13 "Action": [ 14 "rds-data:*", 15 "rds-data:connect" 16 ], 17 "Resource": "arn:aws:rds:ap-northeast-1:[accid]:dbuser:[db-xxxxxxxx]/[dbuser]" 18 } 19 ] 20}
Lambdaのプログラム
必要なライブラリおよび証明書は全てデプロイパッケージに入っています。
lambda_functions.py
python3
1import pymysql 2 3import db_connector 4 5def lambda_handler(event, context): 6 db_host = os.environ['DB_HOST'] 7 db_name = os.environ['DB_NAME'] 8 db_user = os.environ['DB_USER'] 9 try: 10 conn = db_connector.connect(db_host, db_user, db_name) 11 except pymysql.MySQLError as e: 12 return { 13 'statusCode': 500, 14 'body': json.dumps(e.args) 15 } 16 return { 17 'statusCode': 200, 18 'body': json.dumps('Hello, world') 19 }
db_connector.py
python3
1import logging 2import os 3 4import boto3 5import pymysql 6 7logger = logging.getLogger() 8logger.setLevel(logging.INFO) 9 10def connect(host, user, db, port=3306, region='ap-northeast-1'): 11 """Connect to database 12 """ 13 rds = boto3.client('rds',region_name=region) 14 passwd = rds.generate_db_auth_token(host, port, user) 15 logger.info('Token: ' + passwd) 16 return pymysql.connect( 17 host=host, 18 user=user, 19 passwd=passwd, 20 db=db, 21 connect_timeout=5, 22 ssl={ 23 'ca': '{}/rds-combined-ca-bundle.pem'.format( 24 os.environ['LAMBDA_TASK_ROOT']) 25 } 26 )
起きたこと
Lambdaの出力が以下のようになりました。
json
1{ 2 "statusCode": 500, 3 "body": "[1045, \"Access denied for user '[dbuser]'@'[exechost]' (using password: YES)\"]" 4}
アクセス権限がないってことです(パスワードが間違ってる)。
質問内容
どこをどう直せばよいのでしょうか?
15時34分追記
ConnectToRDSの権限を以下のように調整してもダメでした。
json
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Sid": "VisualEditor0", 6 "Effect": "Allow", 7 "Action": "rds-data:*", 8 "Resource": "*" 9 }, 10 { 11 "Sid": "VisualEditor1", 12 "Effect": "Allow", 13 "Action": [ 14 "rds-data:connect" 15 ], 16 "Resource": [ 17 "arn:aws:rds-db:ap-northeast-1:[accid]:dbuser:[db-xxxxxxxx]/[dbuser]" 18 ] 19 } 20 ] 21}
16時17分追記
さらに、以下のような変更を行ってもダメでした。
- AmazonRDSDataFullAccessをデタッチ
- ConnectToRDS権限を以下のように変更
json
1{ 2 "Version": "2012-10-17", 3 "Statement": [ 4 { 5 "Sid": "VisualEditor0", 6 "Effect": "Allow", 7 "Action": "rds-data:connect", 8 "Resource": "arn:aws:rds-db:ap-northeast-1:[accid]:dbuser:[db-xxxxxxxx]/[dbuser]" 9 } 10 ] 11}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。