JAWS-UG CLI専門支部でのハンズオンを参考に、AWS CLIの復習として投稿します。
JAWS-UG CLI専門支部とは?
ユーザーグループにIAMポリシーを割り当てよう
1.今回の目的
AWS CLIで、「Administrators」というユーザーグループに、「Billing」というAWS管理のIAMポリシーを割り当てます。

私のアカウントでAWSマネジメントコンソールにログインし、IAMコンソールからユーザーグループ「Administrators」を見ると、今はカスタマー管理のポリシーが1つだけ割当たっている状態です。

IAMコンソールの左ウィンドウ「ポリシー」メニューから、IAMポリシー「Billing」を検索して見てみると、タイプ欄に「ジョブ機能」と書いてあります。

「職務機能のAWS管理ポリシー」というやつのようです。
SCSの教材で見かけたので、SCS受験する方は問題に出現するかもしれません。
◆(AWS公式docs)職務機能の AWS 管理ポリシー
2.前提条件
CloudShellとIAMに対してフル権限のあるユーザで実施してください。
実行ユーザに「IAMFullAccess」「AWSCloudShellFullAccess」とか「AdministratorAccess」などのポリシーが割当たっていれば実施可能ですが、権限が強すぎるユーザでの操作は危険ですので、MFAを設定するなどの対策を講じておいてください。
3.CloudShellの立ち上げ
AWSマネジメントコンソールのCloudShellアイコンをクリックしてCloudShellを開いていきます。

ようこそ的な画面は「Close」で閉じます。

CloudShellが立ち上がってきたら、コマンドを打ち込んでいきます。

4.変数の設定
「IAM_GROUP_NAME」という変数に、ユーザーグループ名「Administrators」を設定します。(入力したらEnter)
IAM_GROUP_NAME='Administrators'
「IAM_POLICY_NAME」という変数に、今回割り当てたいIAMポリシー名「Billing」を設定します。
IAM_POLICY_NAME='Billing'
ヒアドキュメントで、変数に値が正しく入っているか確認します。
cat << END
#1.IAM_GROUP_NAME:"Administrators"
IAM_GROUP_NAME="${IAM_GROUP_NAME}"
#2.IAM_POLICY_NAME:"Billing"
IAM_POLICY_NAME="${IAM_POLICY_NAME}"
END
出力例
#1.IAM_GROUP_NAME:"Administrators"
IAM_GROUP_NAME="Administrators"
#2.IAM_POLICY_NAME:"Billing"
IAM_POLICY_NAME="Billing"
上下の文字列が同じであれば、変数に正しい値が格納されています。
(ちょっと脱線)ヒアドキュメントとはなんぞや
例えば上記の変数の中身を確認をする場合、ヒアドキュメントを使わないと
#1.IAM_GROUP_NAME:"Administrators"
echo ${IAM_GROUP_NAME}
#2.IAM_POLICY_NAME:"Billing"
echo ${IAM_POLICY_NAME}
とechoを連発する必要があります。
cat << END
ほにゃらら
ほにゃらら
END
といった感じで、cat << xxx ~ xxx の ~ の部分に表示させたい変数や文字列を記載することで、シンプルに記載できます。
xxxの部分はなんでもよいです。上記はENDと書きましたが、EXITやEOFなどでもOKです。
cat << LOVEAWSCLI
#1.IAM_GROUP_NAME:"Administrators"
IAM_GROUP_NAME="${IAM_GROUP_NAME}"
#2.IAM_POLICY_NAME:"Billing"
IAM_POLICY_NAME="${IAM_POLICY_NAME}"
LOVEAWSCLI
こんなのでもちゃんと表示されます。
続いてIAMポリシーのARNを取得します。
ARNとは「Amazon Resource Name」のことでAWSリソースを一意に識別するための記号のようなものです。ARNの構造は以下docsからご確認ください。
◆Amazon リソースネーム (ARN)
IAMポリシーの割り当てではIAMポリシーのARNが必要になるので、あらかじめ取得しておきます。
aws iam list-policiesコマンドを使用してARNを取得し、取得したARNを「IAM_POLICY_ARN」という変数に格納していきます。
IAM_POLICY_ARN=$(
aws iam list-policies \
--scope AWS \
--max-items 1000 \
--query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn" \
--output text \
) \
&& echo "${IAM_POLICY_ARN}"
出力例(5~10秒かかります)
arn:aws:iam::aws:policy/job-function/Billing
-
list-policies- 「IAM_POLICY_NAME」変数に格納されている「Billing」という名前のポリシーのARNを検索(リスト表示)します。
-
--scope-
結果のフィルタリングに使用するスコープです。
今回はAWS管理ポリシー(職務機能のポリシー)から目的の「Billing」を探せばよいので、スコープをAWSに設定しています。 -
その他設定可能な値
ALLAWSLocal
-
--scopeを使用しない場合は、自身で作成したポリシーも含めすべてのポリシー名から目的のARNを探すような挙動をするようです。なくても動きます。
-
-
--max-items (整数)- コマンドの出力で返されるアイテムの総数です。
現在AWS管理ポリシーの数が800くらいなので1000と指定しています。--max-itemsを指定しないで、かつカスタマー管理のポリシー数がすごくたくさんある場合、一回の検索では表示しきれず「NextToken」となってしまい、目的のARNを取得するのにもうひと手間かかるようです。(詳細はリファレンスをご確認ください…)
- コマンドの出力で返されるアイテムの総数です。
-
--query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn" \- 目的のARNをフィルタリングして抽出します。
-
Policies←IAMポリシーの中から -
[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn←該当のポリシー名をARNで抽出
(詳細はdocsをご参照ください…)
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-filter.html
-
- 目的のARNをフィルタリングして抽出します。
-
--output text- 出力をtext形式に設定しています。
--output json、--output yaml、--output yaml-streamなど他の出力形式を指定する場合挙動が少し異なるようですのでリファレンスでご確認ください。https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-filter.html
- 出力をtext形式に設定しています。
iamコマンドのリファレンスはこちらになります。その他のオプションもこちらからご確認ください。
◆iam
ヒアドキュメントで、「IAM_POLICY_ARN」という変数に目的のARNが格納できているか確認します。
cat << END
#IAM_POLICY_ARN:"arn:aws:iam::aws:policy/job-function/Billing"
IAM_POLICY_ARN="${IAM_POLICY_ARN}"
END
出力例
#IAM_POLICY_ARN:"arn:aws:iam::aws:policy/job-function/Billing"
IAM_POLICY_ARN="arn:aws:iam::aws:policy/job-function/Billing"
5.IAMポリシーのアタッチ
では実際にユーザーグループにIAMポリシーをアタッチしていきます。
aws iam attach-group-policy \
--group-name ${IAM_GROUP_NAME} \
--policy-arn ${IAM_POLICY_ARN}
※出力なし
-
attach-group-policy- IAMポリシーをユーザーグループに割り当てます。
-
--group-name- IAMポリシーを割り当てる対象のユーザーグループを指定します。
-
--policy-arn- 割り当てる対象のIAMポリシー(今回は「Billing」)を指定します。
IAMグループ"Administrators"にAWS管理ポリシー(職務機能のポリシー)"Billing"がアタッチされていることを確認します。
aws iam list-attached-group-policies \
--group-name ${IAM_GROUP_NAME} \
--query "AttachedPolicies[?PolicyName == \`${IAM_POLICY_NAME}\`].PolicyName" \
--output text
出力例
Billing
-
list-attached-group-policies- 指定されたユーザーグループに関連付けられているすべての管理対象ポリシーを一覧表示します。
-
--group-name- IAMポリシー一覧を表示させたい対象のユーザーグループを指定します。
-
--query "AttachedPolicies[?PolicyName == \`${IAM_POLICY_NAME}\`].PolicyName"- 目的のARNをフィルタリングして抽出します。
-
AttachedPolicies←アタッチされてるポリシーの中から -
[?PolicyName == \`${IAM_POLICY_NAME}\`].PolicyName←該当のポリシーの名前を抽出
-
- 目的のARNをフィルタリングして抽出します。
マネコンから見ると、ユーザーグループ「Administrators」の許可タブからAWS管理ポリシー(職務管理ポリシー)「Billing」が追加されたことがわかります。

IAMポリシーのデタッチはのちほど…(力尽き)
あとお恥ずかしながら、JMESPath構文の理解が浅く、出力をフィルタリングする部分が結構あやしいです。誤りがありましたらご指摘いただけますと幸いです。
参考資料