0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IAM アクセスアドバイザーからIAMポリシーを作る

Last updated at Posted at 2024-06-10

概要

IAMユーザーグループのアクセスアドバイザーから直近1年にアクセスしたサービスのアクションを持つIAMポリシーを作成します。

jqコマンドで完結できるのが一番いいのですが、心が折れたのでPythonプログラムで実装しています。

結論

STEP1 : アドバイザーの情報を一覧を取得(CLI)

JOBID=`aws iam generate-service-last-accessed-details \
--granularity ACTION_LEVEL \
--arn arn:aws:iam::xxxxxxxxxx:group/hogehoge --output text`
aws iam get-service-last-accessed-details --job-id $JOBID > input.json

STEP2 : PythonプログラムでIAMポリシーを作成

リソースまでは絞れなさそうなので*固定としています。
また、6144文字の制限を超えるポリシーは作成できないのでその考慮も必要です。

import json
from datetime import datetime, timedelta, timezone

# JSONファイルの読み込み
with open('input.json', 'r') as f:
    data = json.load(f)

# 直近1年間の日時を取得
one_year_ago = datetime.now(timezone.utc) - timedelta(days=365)


def is_within_last_year(date_str):
    date = datetime.fromisoformat(date_str.replace('Z', '+00:00'))
    return date >= one_year_ago


# IAMポリシーのテンプレート
policy_template = {"Version": "2012-10-17", "Statement": []}

# ポリシーを保存するリスト
policies = []

for service in data['ServicesLastAccessed']:
    if 'TrackedActionsLastAccessed' in service:
        actions = [
            action['ActionName']
            for action in service['TrackedActionsLastAccessed']
            if 'LastAccessedTime' in action
            and is_within_last_year(action['LastAccessedTime'])
        ]
        if actions:
            statement = {
                "Effect": "Allow",
                "Action": [
                    f"{service['ServiceNamespace']}:{action}" for action in actions
                ],
                "Resource": "*",
            }
            policy_template["Statement"].append(statement)

            # ポリシーのサイズをチェックし、超えた場合は新しいポリシーを作成
            policy_str = json.dumps(policy_template)
            if len(policy_str) > 6144:
                # 現在のポリシーを保存
                policies.append(policy_template.copy())
                # 新しいポリシーを開始
                policy_template["Statement"] = [statement]

# 最後のポリシーも追加
if policy_template["Statement"]:
    policies.append(policy_template.copy())

# 各ポリシーをファイルに保存
for idx, policy in enumerate(policies):
    with open(f'iam_policy_{idx+1}.json', 'w') as f:
        json.dump(policy, f, indent=4)

print(f'{len(policies)}個のIAMポリシーファイルが生成されました。')

コマンドライン引数にして1回の処理にする

pythonをちょっと修正してコマンドを繋げるだけですが、JOB生成に時間がかかるのでsleepを挟んでいる点に注意です。

JOBID=`aws iam generate-service-last-accessed-details \
--granularity ACTION_LEVEL \
--arn arn:aws:iam::xxxxxxxxxx:group/hogehoge --output text` \
&& sleep 10 \
&& aws iam get-service-last-accessed-details --job-id $JOBID > input.json \
&& python index.py input.json

生成途中のjsonファイルの中身

{
    "JobStatus": "IN_PROGRESS",
    "JobCreationDate": "2024-06-10T22:23:59.288000+00:00",
    "IsTruncated": false
}

修正したPythonコード

import json
from datetime import datetime, timedelta, timezone
import sys

# コマンドライン引数を取得
args = sys.argv

input_json_path = args[1]

# JSONファイルの読み込み
with open(input_json_path, 'r') as f:
    data = json.load(f)

以下は同じ

作成したIAMポリシーの例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "access-analyzer:ListAnalyzers",
                "access-analyzer:ListPolicyGenerations",
                "access-analyzer:ValidatePolicy"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "account:ListRegions"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "acm:ListCertificates"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "amplify:CreateApp",
                "amplify:CreateBranch",
                "amplify:DeleteApp",
                "amplify:GetApp",
                "amplify:GetBranch",
                "amplify:GetDomainAssociation",
                "amplify:GetJob",
                "amplify:ListApps",
                "amplify:ListBackendEnvironments",
                "amplify:ListBranches",
                "amplify:ListDomainAssociations",
                "amplify:ListJobs",
                "amplify:ListWebHooks",
                "amplify:StartJob",
                "amplify:UpdateApp"
            ],
            "Resource": "*"
        },
        (中略)
        {
            "Effect": "Allow",
            "Action": [
                "cognito-sync:GetBulkPublishDetails",
                "cognito-sync:GetCognitoEvents",
                "cognito-sync:GetIdentityPoolConfiguration",
                "cognito-sync:ListDatasets"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "compute-optimizer:GetEnrollmentStatus"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "config:DescribeConfigurationRecorderStatus",
                "config:DescribeConfigurationRecorders"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "dax:DescribeClusters"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "devops-guru:GetResourceCollection",
                "devops-guru:SearchInsights"
            ],
            "Resource": "*"
        }
    ]
}

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?