🔖

AWS IAM Role/PolicyをTagで検索するShell Script

に公開

IAM Roleをtagを使って検索したかったのですが、Tag Edigorでは検索できないようです。bashで無理やり検索します。

やっていること

  • list-rolesでRole一覧を得る
    • このときtagは得られない
  • forでroleに対してget-roleしてtagでフィルタして値があるrole名だけを出力する

注意

  • 1Roleで3,4秒かかるので全Roleだとそれなりに時間がかかる

例 IAM Role

key: stage
value: dev
というタグがついているIAMロールを検索する。

query-role.sh
#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace  # optional

KEY=stage
VALUE=dev

for ROLE_NAME in $(aws iam list-roles --query 'Roles[].RoleName' --output text); do
  TAG_COUNT=$(aws iam get-role \
                --role-name "${ROLE_NAME}" \
                --query "length(Role.Tags[?Key=='${KEY}' && Value=='${VALUE}'] || [])" \
                --output text 2>/dev/null || echo 0)

  TAG_COUNT="${TAG_COUNT:-0}"

  if [ "${TAG_COUNT}" -gt 0 ]; then
    echo "${ROLE_NAME}"
  else
    # Else branch to avoid exit on [ ... ] returning exit code 1
    :
  fi
done

例 IAM Policy

key: stage
value: dev
というタグがついているIAMロールを検索する。

query-policy.sh
#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace

KEY=stage
VALUE=dev
# policy name filter pattern, one word, case-insensitibe
NAME_CONTAINS=

for POLICY_ARN in $(aws iam list-policies --query 'Policies[].Arn' --output text); do

  if [[ "$(echo "$POLICY_ARN" | awk '{print tolower($0)}')" == *"${NAME_CONTAINS}"* ]]; then
    :
  else
    continue
  fi

  TAG_COUNT=$(aws iam get-policy \
                --policy-arn "${POLICY_ARN}" \
                --query "length(Policy.Tags[?Key=='${KEY}' && Value=='${VALUE}'] || [])" \
                --output text 2>/dev/null || echo 0)

  TAG_COUNT="${TAG_COUNT:-0}"

  if [ "${TAG_COUNT}" -gt 0 ]; then
    echo "${POLICY_ARN}"
  else
    # Else branch to avoid exit on [ ... ] returning exit code 1
    :
  fi
done

Discussion