redshift-data cliを利用して、sqlを実行する時に、認証方法としてAWS Secrets Managerを利用したいと思います。 Secrets Managerコンソール上で新たなシークレットを作成し、Redshiftのパスワードを自動ローテーションさせる設定までやってみました。
構成
Redshiftクラスターはbastionサーバーを利用し、外部からのアクセスを可能にし、パスワードを自動ローテーションさせるLambdaはNATゲートウェイでなはく、VPCエンドポイントを通すように設定しました。

シークレット作成と自動ローテーション設定
- 新たなシークレットを作成します。Redshiftクラスターのユーザー名とパスワードを入力し、対象クラスターを選びます。KMSキーはデフォルトを選びました。
- 自動ローテーションを有効にし、ローテーション間隔を入力し、新しいLambda関数を作成します。
しかし、自動作成されるCloudformationスタック作成に失敗しました。サブネットの数超過による失敗でした。
Properties validation failed for resource SecretsManagerRedshiftRotationSingleUser with message: #/VpcConfig/SubnetIds: expected maximum item count: 16, found: 20
手動で自動ローテーション再設定
失敗したCloudformationスタックを削除し、同じテンプレートでスタックを再度作成します。 パラメーターは失敗したスタックと同じ値を入力し、サブネットはLambdaを作成するサブネットを入力します。
Key | Value |
---|---|
kmsKeyArn | - |
excludeCharacters | :/@"'\ |
functionName | SecretsManagerRedshiftRotationLambda |
endpoint | https://secretsmanager.ap-northeast-1.amazonaws.com |
invokingServicePrincipal | secretsmanager.amazonaws.com |
vpcSecurityGroupIds | sg-0b3xxxcfa |
vpcSubnetIds | subnet-0e171673999462f90,subnet-0c21ae038cbe71f48 |
Cloudformationスタック作成が完了したら、シークレット自動ローテーション設定画面を開き、作成されたLambda関数を選択します。
Lambda実行失敗
Lambda関数に設定したSecurity GroupはRedshiftへ設定されたSecurity Groupと同じです。(自動でLambda関数が作成される場合もRedshiftクラスターと同様なSecurity Groupが設定されます。) Redshiftへ設定されているSecurity GroupはAWS Secrets Managerが作成するLambda関数のInboundアクセスの許可が必要です。
[ERROR] d352ae22-3b4b-4203-88cf-224160303d56 setSecret: Unable to log into database with previous, current, or pending secret of secret arn arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL
[ERROR] ValueError: Unable to log into database with previous, current, or pending secret of secret arn arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL
Security GroupへInboundアクセス追加
Redshift Security GroupへSecurity Group自身からRedshiftへアクセスできるようにInboundアクセスを追加
すぐにシークレットをローテーションさせるを実行
正常にパスワードが変更されました。
[INFO] 2021-07-26T00:49:43.267Z 71e0d30d-8017-402f-b4a0-2305320e8d86 createSecret: Successfully put secret for ARN arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL and version 1048bb1f-c616-4105-ac27-1508b53f8196.
[INFO] 2021-07-26T00:49:44.137Z e4b636ee-6db7-4657-829f-c6585c1a67c1 setSecret: Successfully set password for user awsuser in Redshift DB for secret arn arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL.
[INFO] 2021-07-26T00:49:44.476Z 44366043-316b-4494-8a30-67d3bad38883 testSecret: Successfully signed into Redshift DB with AWSPENDING secret in arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL.
[INFO] 2021-07-26T00:49:44.798Z 8253ea08-1bb1-4474-a669-699a51dfc795 finishSecret: Successfully set AWSCURRENT stage to version 1048bb1f-c616-4105-ac27-1508b53f8196 for secret arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL.
テストQueryを実行
作成されたシークレットを利用して、SQLを実行します。
テストユーザーにはAmazonRedshiftDataFullAccess
権限を付与しました。
aws redshift-data execute-statement \
--database dev \
--cluster-identifier test-redshift-cluster \
--secret-arn arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL \
--region ap-northeast-1 \
--sql "select * from sales limit 5;" \
--profile redshift
* 実行結果
{
"ClusterIdentifier": "test-redshift-cluster",
"CreatedAt": "2021-07-26T09:56:18.888000+09:00",
"Database": "dev",
"Id": "61c1630b-9676-4ed4-bb25-d73f92efee76",
"SecretArn": "arn:aws:secretsmanager:ap-northeast-1:xxxx:secret:dev/Demo/Redshift-8c3rDL"
}
Sql結果確認
aws redshift-data get-statement-result \
--id 61c1630b-9676-4ed4-bb25-d73f92efee76 \
--region ap-northeast-1 \
--profile redshift
* 実行結果
{
"Records": [
[
{
"longValue": 33095
},
{
"longValue": 36572
},
{
"longValue": 30047
},
{
"longValue": 660
},
{
"longValue": 2903
},
{
"longValue": 1827
},
{
"longValue": 2
},
{
"stringValue": "234.00"
},
{
"stringValue": "35.10"
},
{
"stringValue": "2008-01-01 09:41:06"
}
]
... 省略
],
"ColumnMetadata": [
{
"isCaseSensitive": false,
"isCurrency": false,
"isSigned": true,
"label": "salesid",
"length": 0,
"name": "salesid",
"nullable": 0,
"precision": 10,
"scale": 0,
"schemaName": "public",
"tableName": "sales",
"typeName": "int4"
}
... 省略
],
"TotalNumRows": 5
}