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 証明書をダウンロードする ( rds-combined-ca-bundle.pem )
- セキュリティーグループは、0.0.0.0/0 などに変える。
パブリックアクセスを有効にする代わりに、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