どういう状態か
何のコマンドでも以下のようになる。
$ aws lambda list-functions An error occurred (AccessDeniedException) when calling the ListFunctions operation: User: arn:aws:iam::111111111111:mfa/username is not authorized to perform: lambda:ListFunctions on resource: * with an explicit deny
確認したのは
- IAMに権限はある
- ~/.aws/{credentials,config} はある
原因
MFA(多要素認証)エラーだった
調べ方
IAM Policy Simulatorコンソールが公式に用意されているので、こちらで調べる
(iam policyはaws iam simulate-principal-policyでも通常調べる事もできるが、この場合は同じくAccessDeniedExceptionになる)
https://policysim.aws.amazon.com/
こんな感じで機能、使いたいポリシーを選択、Run Simulationを押すと詳細な原因が表示されるAccessDeniedExceptionになる)

結果
{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"iam:ChangePassword",
"iam:GetAccountPasswordPolicy",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
この結果を調べると以下のページから
The DenyAllExceptListedIfNoMFA statement denies access to every action in all AWS services, except a few listed actions, but only if the user is not signed in with MFA.
MFAで認証していないとエラーだとわかる。
対応方法
以下のサイトを参照に一時認証情報を作成する
aws sts get-session-token --serial-number arn:aws:iam::111111111111:mfa/username --token-code 【MFAトークン】
{ "Credentials": { "AccessKeyId": "AAA", "SecretAccessKey": "bbb", "SessionToken": "ccc", "Expiration": "2021-08-03T03:24:32+00:00" } }
これを ~/.aws/credentialsへ設定
[mfa] aws_access_key_id = AAA aws_secret_access_key = bbb
~/.aws/config 側へregionなども設定しておく
そして最初のコマンドを --profile 付きでたたくと結果が表示されるようになる
$ aws lambda list-functions --profile mfa
{
"Functions": [
...省略
MFAの設定を簡略化する
この辺の設定をもう少し簡単に、またsessionを自動更新するには以下のツールを使う
詳しくはREADME.mdにあるが簡単にメモしておくと
~/.aws/credentialsの[default]->[default-long-term]に変更- コマンドを実行して、あとは支持に従ってmfaコードを入力
$ aws-mfa --duration 1800 arn:aws:iam::111111111111:mfa/username INFO - Validating credentials for profile: default WARNING - Your existing credentials are missing or invalid, obtaining new credentials. Enter AWS MFA code for device [arn:aws:iam::111111111111:mfa/username] (renewing for 1800 seconds): INFO - Fetching Credentials - Profile: default, Duration: 1800 INFO - Success! Your credentials will expire in 1800 seconds at: 2021-08-07 14:13:08+00:00
これで--profile なしでMFA有りのaws cliを使えるようになり、指定の --duration で自動でsessionを更新してくれるようになる