AWSのIAMユーザをCLIで作ったり削除する【削除自動化スクリプト追記】

# <!--【tipsメモ】AWSのIAMユーザをCLIで作ったり削除したり -->

## 本稿の内容

AWS CLIを用いてIAMユーザの新規作成、また削除を行います。

IAMのマネジメントコンソールでポチポチしている作業を自動化・コード化したいときのためのメモ。
【追加】-> 削除する際はいろいろなアタッチされた要素を削除しなければいけません。その要素たちの有無の判断が必要なため、単に削除CLIを羅列しても必要十分な動きをしてくれません。なので極力usernameの入力だけでそのユーザに紐づく各要素を走査しデタッチしてくれる、一回のボタンぽちーでうごくBash、PowerShell、ついでにPythonのスクリプトも載せてみました。


## 前提・環境

- IAMユーザを新規に\<YOUR_NAME\>というIDで作成し、IAMグループ\<YOUR_GROUP\>に追加する。また、初期パスワードとして\<YOUR_PASSWORD\>を設定する。
- マネジメントコンソールへのユーザーアクセスを提供するオプションを有効化する。
- 初期のカスタムパスワードを設定し、初回サインイン時に更新を行わせる。
- **本稿ではPoewrshellで実行しています**。AWS-CLIのバージョンが同じならAWS-CLI上の操作は同じだと思いますが、削除でjsonの変数を使っている箇所は適宜対応してもらう必要があります。
- aws-cli/2.9.0 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
- aws-cliの基本的なconfigやcredentialsは設定済みでIAM操作の権限も持っているものとする。

# 基本的なIAMユーザのCLI操作

## ユーザ作成の流れ

単純に1コマンドで作るぜと行きたいところですが、実際に使えるようにするにはいろいろとアタッチする必要があります。ユーザ作成の場合、スクリプト化する時はこれらのベタ張りでも大丈夫です。

```powershell
aws iam create-user --user-name <YOUR_NAME>
aws iam create-access-key --user-name <YOUR_NAME>
aws iam create-login-profile --user-name <YOUR_NAME> --password 'YOUR_PASSWORD' --password-reset-required
aws iam attach-user-policy --user-name <YOUR_NAME> --policy-arn arn:aws:iam::aws:policy/IAMUserChangePassword
aws iam add-user-to-group --user-name <YOUR_NAME> --group-name <YOUR_GROUP>
```

:::note info
"**IAMUserChangePassword**"はAWSの[マネージドポリシー](https://docs.aws.amazon.com/ja_jp/aws-managed-policy/latest/reference/IAMUserChangePassword.html)なので、ARN内にユーザIDは不要
:::

## ユーザ削除の流れ

ユーザを削除するときもそのユーザを指定して関連する全部を消せればよいのですが、現状では作成の逆順を追って逐一デタッチしていかないとエラーになります。またここで記述した内容は最小要件のユーザなので、MFAやSSHキーなどもっとアタッチされたものが多い場合は以下のページを参考に適宜削除してください。
[参考：アカウントからユーザーを削除するには (AWS CLI)](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_users_manage.html#id_users_deleting_cli)

```powershell
aws iam remove-user-from-group --user-name <YOUR_NAME> --group-name <YOUR_GROUP>
aws iam delete-login-profile --user-name <YOUR_NAME>
$accesskeys_json = aws iam list-access-keys --user-name <YOUR_NAME> | ConvertFrom-Json
$target_accesskey = $accesskeys_json.AccessKeyMetadata.AccessKeyId
aws iam delete-access-key --user-name <YOUR_NAME> --access-key $target_accesskey
aws iam delete-user --user-name <YOUR_NAME>
```

:::note warn
削除するにはシークレットアクセスキー等もすべて削除する必要がありますが、当該キーのIDはjsonで返ってきます。そのjsonを変数に入れID値部分のみを抜き取って削除してあげます。Powershell以外のCLIではjqを使うなど適宜処理を修正するか、目視でアクセスキー値を確認し指定してください（自動化するなら目視以外の処理をしましょう）。また、アクセスキーなどが複数ある場合は処理をもう少し高度化しないといけません。
:::

## 参考：list-access-keysのフォーマット
```powershell
aws iam list-access-keys --user-name YOUR_NAME
{
    "AccessKeyMetadata": [
        {
            "UserName": "YOUR_NAME",
            "AccessKeyId": "XXXXXXXXXXXXXXXXXXXXXXXXXXX",
            "Status": "Active",
            "CreateDate": "2023-4-22T07:25:52+00:00"
        }
    ]
}

$accesskeys_json = aws iam list-access-keys --user-name YOUR_NAME | ConvertFrom-Json
$target_accesskey = $accesskeys_json.AccessKeyMetadata.AccessKeyId
echo $target_accesskey
XXXXXXXXXXXXXXXXXXXXXXXXXXX
```
# 削除作業の完全自動化スクリプト

ここからはIAMユーザ削除の完全自動化について記します。[アカウントからユーザーを削除するには (AWS CLI)](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_users_manage.html#id_users_deleting_cli)のページをもとに各作業を順番にオブジェクトの有無を確認し、該当するものがあればデタッチしていくという内容になります。2023年6月時点で、実際にユーザを削除する前に9つのステップを踏む必要があります。

|  No  |  実施作業  |
| ---- | ---- |
|  1 |  ユーザーのパスワード（使用していた場合）を削除します. |
|  2 |  ユーザーのアクセスキーを削除します (使用していた場合)。 |
| 3 | ユーザーの署名証明書を削除します。認証情報を削除すると、完全に削除され、復元できないことに注意してください。|
|4| ユーザーの SSH パブリックキーを削除します (使用していた場合)。|
|5|ユーザーの Git 認証情報を削除します。|
|6|ユーザーの 多要素認証 (MFA) デバイスを無効にします (使用していた場合)。|
|7|ユーザーのインラインポリシーを削除します。|
|8|ユーザーにアタッチされているすべての管理ポリシーをデタッチします。|
|9|すべてのユーザーグループからユーザーを削除します。|
|10|ユーザーを削除。|

:::note warn
以下の削除自動化スクリプトは権限を持ったユーザで実行したら実際に選択や確認など無く削除されます。もし利用される場合は適切な管理のもと運用してください。そうでなくともAWSの権限管理はしっかりやりましょう。
これらのスクリプトは広く一般的に公開されたドキュメントや基礎的知識で作成されており、本スクリプトで生じたいかなるトラブル、被害、損失等に対して一切責任を負いかねるのでご了承ください。
:::

## Bash Scriptでのiam_user削除自動化

\<username>に削除したいiam_userを設定してください。
削除の際にデタッチしなければいけない要素を逐次存在するか確認し、存在すればデタッチしていくbashでのスクリプトです。

```bash:aws_delete_iam_user.sh
#!/bin/bash

# Set the username of the IAM user to delete
username="<YOUR_NAME>"

# Delete the user's password
aws iam delete-login-profile --user-name $username

# Delete the user's access keys
accessKeys=$(aws iam list-access-keys --user-name $username)
accessKeyIds=$(echo $accessKeys | jq -r '.AccessKeyMetadata[].AccessKeyId')
for accessKeyId in $accessKeyIds; do
    aws iam delete-access-key --access-key-id $accessKeyId --user-name $username
done

# Delete the user's signing certificate
signingCertificates=$(aws iam list-signing-certificates --user-name $username)
certificateIds=$(echo $signingCertificates | jq -r '.Certificates[].CertificateId')
for certificateId in $certificateIds; do
    aws iam delete-signing-certificate --certificate-id $certificateId --user-name $username
done

# Delete the user's SSH public key
sshPublicKeys=$(aws iam list-ssh-public-keys --user-name $username)
sshPublicKeyIds=$(echo $sshPublicKeys | jq -r '.SSHPublicKeys[].SSHPublicKeyId')
for sshPublicKeyId in $sshPublicKeyIds; do
    aws iam delete-ssh-public-key --ssh-public-key-id $sshPublicKeyId --user-name $username
done

# Delete the user's Git credentials
serviceSpecificCredentials=$(aws iam list-service-specific-credentials --user-name $username)
serviceSpecificCredentialIds=$(echo $serviceSpecificCredentials | jq -r '.ServiceSpecificCredentials[].ServiceSpecificCredentialId')
for serviceSpecificCredentialId in $serviceSpecificCredentialIds; do
    aws iam delete-service-specific-credential --service-specific-credential-id $serviceSpecificCredentialId --user-name $username
done

# Deactivate and delete the user's MFA device
mfaDevices=$(aws iam list-mfa-devices --user-name $username)
serialNumbers=$(echo $mfaDevices | jq -r '.MFADevices[].SerialNumber')
for serialNumber in $serialNumbers; do
    aws iam deactivate-mfa-device --serial-number $serialNumber --user-name $username
    aws iam delete-virtual-mfa-device --serial-number $serialNumber
done

# Delete the user's inline policies
inlinePolicies=$(aws iam list-user-policies --user-name $username)
policyNames=$(echo $inlinePolicies | jq -r '.PolicyNames[]')
for policyName in $policyNames; do
    aws iam delete-user-policy --policy-name $policyName --user-name $username
done

# Detach the user's managed policies
managedPolicies=$(aws iam list-attached-user-policies --user-name $username)
policyArns=$(echo $managedPolicies | jq -r '.AttachedPolicies[].PolicyArn')
for policyArn in $policyArns; do
    aws iam detach-user-policy --policy-arn $policyArn --user-name $username
done

# Remove the user from all groups
groups=$(aws iam list-groups-for-user --user-name $username)
groupNames=$(echo $groups | jq -r '.Groups[].GroupName')
for groupName in $groupNames; do
    aws iam remove-user-from-group --group-name $groupName --user-name $username)
done

# Finally, delete the IAM user
aws iam delete-user --user-name $username

echo "Successfully deleted IAM user: ${username}"
```


## PowerShell Scriptでのiam_user削除自動化

\<username>に削除したいiam_userを設定してください。
削除の際にデタッチしなければいけない要素を逐次存在するか確認し、存在すればデタッチしていくPowerShellでのスクリプトです。

```powershell:aws_delete_iam_user.ps1
# Set the username of the IAM user to delete
$username = "<YOUR_NAME>"

# "1. ユーザーのパスワード（使用していた場合）を削除します。"
Write-Output "Delete the user's password"
aws iam delete-login-profile --user-name $username

# "2. ユーザーのアクセスキーを削除します (使用していた場合)。"
Write-Output "Delete the user's access keys"
$accessKeys = aws iam list-access-keys --user-name $username | ConvertFrom-Json
foreach ($key in $accessKeys.AccessKeyMetadata) {
    aws iam delete-access-key --access-key-id $key.AccessKeyId --user-name $username
}

# "3. ユーザーの署名証明書を削除します。"
Write-Output "Delete the user's signing certificate"
$signingCertificates = aws iam list-signing-certificates --user-name $username | ConvertFrom-Json
foreach ($cert in $signingCertificates.Certificates) {
    aws iam delete-signing-certificate --certificate-id $cert.CertificateId --user-name $username
}

# "4. ユーザーの SSH パブリックキーを削除します (使用していた場合)。"
Write-Output "Delete the user's SSH public key"
$sshPublicKeys = aws iam list-ssh-public-keys --user-name $username | ConvertFrom-Json
foreach ($key in $sshPublicKeys.SSHPublicKeys) {
    aws iam delete-ssh-public-key --ssh-public-key-id $key.SSHPublicKeyId --user-name $username
}

# "5. ユーザーの Git 認証情報を削除します。"
Write-Output "Delete the user's Git credentials"
$serviceSpecificCredentials = aws iam list-service-specific-credentials --user-name $username | ConvertFrom-Json
foreach ($cred in $serviceSpecificCredentials.ServiceSpecificCredentials) {
    aws iam delete-service-specific-credential --service-specific-credential-id $cred.ServiceSpecificCredentialId --user-name $username
}

# "6. ユーザーの 多要素認証 (MFA) デバイスを無効にします (使用していた場合)。"
Write-Output "Deactivate and delete the user's MFA device"
$mfaDevices = aws iam list-mfa-devices --user-name $username | ConvertFrom-Json
foreach ($device in $mfaDevices.MFADevices) {
    aws iam deactivate-mfa-device --serial-number $device.SerialNumber --user-name $username
    aws iam delete-virtual-mfa-device --serial-number $device.SerialNumber
}

# "7. ユーザーのインラインポリシーを削除します。"
Write-Output "Delete the user's inline policies"
$inlinePolicies = aws iam list-user-policies --user-name $username | ConvertFrom-Json
foreach ($policyName in $inlinePolicies.PolicyNames) {
    aws iam delete-user-policy --policy-name $policyName --user-name $username
}

# "8. ユーザーにアタッチされているすべての管理ポリシーをデタッチします。"
Write-Output "Detach the user's managed policies"
$managedPolicies = aws iam list-attached-user-policies --user-name $username | ConvertFrom-Json
foreach ($policy in $managedPolicies.AttachedPolicies) {
    aws iam detach-user-policy --policy-arn $policy.PolicyArn --user-name $username
}

# "9. すべてのユーザーグループからユーザーを削除します。"
Write-Output "Remove the user from all groups"
$groups = aws iam list-groups-for-user --user-name $username | ConvertFrom-Json
foreach ($group in $groups.Groups) {
    aws iam remove-user-from-group --group-name $group.GroupName --user-name $username
}

# "10. ユーザーを削除します。"
Write-Output "Finally, delete the IAM user"
aws iam delete-user --user-name $username

Write-Output "Successfully deleted IAM user: $($username)"

```

## Python Scriptでのiam_user削除自動化

\<username>に削除したいiam_userを設定してください。
削除の際にデタッチしなければいけない要素を逐次存在するか確認し、存在すればデタッチしていくPythonでのスクリプトです。
Pythonを使う場合はboto3のライブラリのインストールが必要なのでご注意ください。

```Python:aws_delete_iam_user.py
import boto3

# Set the username of the IAM user to delete
username = "<YOUR_NAME>"

# Create an IAM client
iam = boto3.client('iam')

# Delete the user's password
try:
    iam.delete_login_profile(UserName=username)
except iam.exceptions.NoSuchEntityException:
    pass

# Delete the user's access keys
access_keys = iam.list_access_keys(UserName=username)
for access_key in access_keys['AccessKeyMetadata']:
    iam.delete_access_key(UserName=username, AccessKeyId=access_key['AccessKeyId'])

# Delete the user's signing certificate
signing_certificates = iam.list_signing_certificates(UserName=username)
for cert in signing_certificates['Certificates']:
    iam.delete_signing_certificate(UserName=username, CertificateId=cert['CertificateId'])

# Delete the user's SSH public key
ssh_public_keys = iam.list_ssh_public_keys(UserName=username)
for key in ssh_public_keys['SSHPublicKeys']:
    iam.delete_ssh_public_key(UserName=username, SSHPublicKeyId=key['SSHPublicKeyId'])

# Delete the user's Git credentials
service_specific_credentials = iam.list_service_specific_credentials(UserName=username)
for cred in service_specific_credentials['ServiceSpecificCredentials']:
    iam.delete_service_specific_credential(UserName=username, ServiceSpecificCredentialId=cred['ServiceSpecificCredentialId'])

# Deactivate and delete the user's MFA device
mfa_devices = iam.list_mfa_devices(UserName=username)
for device in mfa_devices['MFADevices']:
    iam.deactivate_mfa_device(UserName=username, SerialNumber=device['SerialNumber'])
    iam.delete_virtual_mfa_device(SerialNumber=device['SerialNumber'])

# Delete the user's inline policies
inline_policies = iam.list_user_policies(UserName=username)
for policy_name in inline_policies['PolicyNames']:
    iam.delete_user_policy(UserName=username, PolicyName=policy_name)

# Detach the user's managed policies
managed_policies = iam.list_attached_user_policies(UserName=username)
for policy in managed_policies['AttachedPolicies']:
    iam.detach_user_policy(UserName=username, PolicyArn=policy['PolicyArn'])

# Remove the user from all groups
groups = iam.list_groups_for_user(UserName=username)
for group in groups['Groups']:
    iam.remove_user_from_group(GroupName=group['GroupName'], UserName=username)

# Finally, delete the IAM user
iam.delete_user(UserName=username)

print(f"Successfully deleted IAM user: {username}")
```