以下のような設定です。なお、[]内は実際には正しい値が入っています
RDS
- エンジン MySQL
- クラス db.t2.micro
- リソースID [db-xxxxxxxx]
- パブリックアクセシビリティ あり
- IAM db 認証 有効
- ホスト名 [rdshost]
事前に以下の作業を実施済み
create database [dbname];
create user [dbuser] identified with AWSAuthenticationPlugin as 'RDS';
grant 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 内容は以下の通りです
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"
],
"Resource": "*"
}
]
}
- AmazonRDSDataFullAccess 内容は以下の通りです
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SecretsManagerDbCredentialsAccess",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:PutResourcePolicy",
"secretsmanager:PutSecretValue",
"secretsmanager:DeleteSecret",
"secretsmanager:DescribeSecret",
"secretsmanager:TagResource"
],
"Resource": "arn:aws:secretsmanager:*:*:secret:rds-db-credentials/*"
},
{
"Sid": "RDSDataServiceAccess",
"Effect": "Allow",
"Action": [
"dbqms:CreateFavoriteQuery",
"dbqms:DescribeFavoriteQueries",
"dbqms:UpdateFavoriteQuery",
"dbqms:DeleteFavoriteQueries",
"dbqms:GetQueryString",
"dbqms:CreateQueryHistory",
"dbqms:DescribeQueryHistory",
"dbqms:UpdateQueryHistory",
"dbqms:DeleteQueryHistory",
"dbqms:DescribeQueryHistory",
"rds-data:ExecuteSql",
"rds-data:ExecuteStatement",
"rds-data:BatchExecuteStatement",
"rds-data:BeginTransaction",
"rds-data:CommitTransaction",
"rds-data:RollbackTransaction",
"secretsmanager:CreateSecret",
"secretsmanager:ListSecrets",
"secretsmanager:GetRandomPassword",
"tag:GetResources"
],
"Resource": "*"
}
]
}
- AWSLambdaBasicExecutionRole-zzzzzzz 内容は以下の通りです
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:[accid]:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:[accid]:log-group:/aws/lambda/[funcname]:*"
]
}
]
}
- ConnectToRDS 内容は以下の通りです
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "rds-data:*",
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"rds-data:*",
"rds-data:connect"
],
"Resource": "arn:aws:rds:ap-northeast-1:[accid]:dbuser:[db-xxxxxxxx]/[dbuser]"
}
]
}
Lambdaのプログラム
必要なライブラリおよび証明書は全てデプロイパッケージに入っています。
lambda_functions.py
import pymysql
import db_connector
def lambda_handler(event, context):
db_host = os.environ['DB_HOST']
db_name = os.environ['DB_NAME']
db_user = os.environ['DB_USER']
try:
conn = db_connector.connect(db_host, db_user, db_name)
except pymysql.MySQLError as e:
return {
'statusCode': 500,
'body': json.dumps(e.args)
}
return {
'statusCode': 200,
'body': json.dumps('Hello, world')
}
db_connector.py
import logging
import os
import boto3
import pymysql
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def connect(host, user, db, port=3306, region='ap-northeast-1'):
"""Connect to database
"""
rds = boto3.client('rds',region_name=region)
passwd = rds.generate_db_auth_token(host, port, user)
logger.info('Token: ' + passwd)
return pymysql.connect(
host=host,
user=user,
passwd=passwd,
db=db,
connect_timeout=5,
ssl={
'ca': '{}/rds-combined-ca-bundle.pem'.format(
os.environ['LAMBDA_TASK_ROOT'])
}
)
起きたこと
Lambdaの出力が以下のようになりました。
{
"statusCode": 500,
"body": "[1045, \"Access denied for user '[dbuser]'@'[exechost]' (using password: YES)\"]"
}
アクセス権限がないってことです(パスワードが間違ってる)。
質問内容
どこをどう直せばよいのでしょうか?
15時34分追記
ConnectToRDSの権限を以下のように調整してもダメでした。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "rds-data:*",
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"rds-data:connect"
],
"Resource": [
"arn:aws:rds-db:ap-northeast-1:[accid]:dbuser:[db-xxxxxxxx]/[dbuser]"
]
}
]
}
16時17分追記
さらに、以下のような変更を行ってもダメでした。
- AmazonRDSDataFullAccessをデタッチ
- ConnectToRDS権限を以下のように変更
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "rds-data:connect",
"Resource": "arn:aws:rds-db:ap-northeast-1:[accid]:dbuser:[db-xxxxxxxx]/[dbuser]"
}
]
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
0
自己解決しました。
ConnectToRDSポリシーの文字列が間違えていました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "rds-db:connect",
"Resource": "arn:aws:rds-db:ap-northeast-1:[accid]:[db-xxxxxxxx]/[dbuser]"
}
]
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる