MySQL 5.6 マイナーバージョン 5.6.34 以降、MySQL 5.7 マイナーバージョン 5.7.16 以降、Amazon Aurora 1.10 以降 で対応している。
ただし、1秒間あたりの接続開始の認証回数が20回と少ないため、アクセスの多いシステムでは採用できない。
IAM データベース認証の制限
Lambda をVPC内に入れてしまうと、接続まで時間がかかるため、それを回避するために使ったりする。
1. RDS で Mysql を起動
パブリックアクセスを有効にする代わりに、SSL接続することになる。
2. Mysql にユーザーを作る
RDS 作成時の Root ユーザーで、IAM 用のユーザーを作る。
プラグインを有効にしユーザーを作成
CREATE USER 'iam_user'@'%' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';
SSL 接続を強制する
GRANT SELECT,INSERT,UPDATE,DELETE ON dbdayo.* to 'iam_user'@'%' REQUIRE SSL;
3. IAM Policy を作成
作ったポリシーは、Roleなどにアタッチする。
太字の部分は固定値です。rds-db の部分も、これで間違いなく、Webコンソール上はエラーが出るが、あなたが正しい。
arn:aws:rds-db:{RDSのリージョン}:{AWS アカウントID}:dbuser:{RDSのリソースID}/{DBのUser名}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:ap-northeast-1:1234567890:dbuser:db-AAAAARRRRRR/iam_user"
]
}
]
}
4. Lambda や EC2 にRole を関連付ける
作ったPolicyをRoleにアタッチして、さらにそのRoleをLambdaやEC2に関連付ける。
5a. EC2などからプログラムで接続
RDS_HOST = 'dbdayo.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com'
RDS_USER = 'iam_user'
RDS_REGION = 'ap-northeast-1'
def lambda_handler(event, context):
rds = boto3.client('rds')
password = rds.generate_db_auth_token(
DBHostname=RDS_HOST,
Port=3306,
DBUsername=RDS_USER
)
conn = mysql.connector.connect(
user=RDS_USER,
password=password,
host=RDS_HOST,
database='mysql',
charset='utf8',
ssl_verify_cert=True,
ssl_ca='rds-combined-ca-bundle.pem'
)
5b. EC2からコマンドで接続する
aws rds generate-db-auth-token でパスワードを生成している、認証部分がポイント
mysql -u iam_user -h dbdayo.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
-p`aws rds generate-db-auth-token --hostname dbdayo.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com \
--port 3306 \
--username iam_user \
--region ap-northeast-1` \
--ssl-ca=rds-combined-ca-bundle.pem \
--enable-cleartext-plugin