【Terraform】aws_iam_policy_attachmentを使うとtfstate外のリソースにも影響を与える可能性

# これはなに？
Terraformを用いて、AWS環境のIAMロールとIAMポリシーのアタッチをする際に
<font color="Blue">[iam_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment)</font>を使用するとハマる罠があるのでその事象についてのメモです。


## 事象

例えばですが、下記の様な記述でIAMロールへIAMポリシーをアタッチしていると想定します。
```iam.tf
# ロール
resource "aws_iam_role" "lambda_role" {
  name               = "kurono-policy-test-role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

#ポリシー
data "aws_iam_policy" "kurono-policy-test-policy" {
  arn = "arn:aws:iam::123456789:policy/kurono-policy-test-policy"
}
resource "aws_iam_policy_attachment" "lambda-execute" {
  name       = "lambda-execute"
  roles      = [aws_iam_role.lambda_role.name]
  policy_arn = data.aws_iam_policy.kurono-policy-test-policy.arn
}

```
・そして、AWSコンソール側でTerraformと同じポリシー`kurono-policy-test-policy`をアタッチしたロール(`kurono-policy-test-role-2`)を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/cc8af9ae-f1e4-d4f6-d684-fbaf8533c2ae.png)

## apply前の状況
現状の構成としては以下の様になっているかと思います。
![aaaaaaa.drawio (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/75bee02e-a2d8-4674-00e9-5c71c2e7644f.png)



そして、環境を片付けようとして`terraform destroy`をします。
するとコンソール側で作成した`kurono-policy-test-role-2`からもポリシーをrevokeしようとします。
```
root@kurono2:~/terraform# terraform destroy
aws_iam_role.lambda_role: Refreshing state... [id=kurono-policy-test-role]
aws_iam_policy_attachment.lambda-execute: Refreshing state... [id=lambda-execute]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_iam_policy_attachment.lambda-execute will be destroyed
  - resource "aws_iam_policy_attachment" "lambda-execute" {
      - groups     = [] -> null
      - id         = "lambda-execute" -> null
      - name       = "lambda-execute" -> null
      - policy_arn = "arn:aws:iam::123456789:policy/kurono-policy-test-policy" -> null
      - roles      = [
          - "kurono-policy-test-role",
          - "kurono-policy-test-role-2",
        ] -> null
      - users      = [] -> null
    }
```
## apply後の状況
`kurono-policy-test-role`と同じポリシーを使っていたことにより、
`kurono-policy-test-role-2`からもポリシーがrevokeされてしまいました。
![aaaaaaa.drawio (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/41cd72f4-7b20-0103-10de-1f676356591e.png)



## 解決策

結論、<font color="Blue">[aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment)</font>を使いましょう。
<font color="Blue">[iam_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy_attachment)</font>では<font color="Red">他のメカニズム（他のTerraformリソースを含む）を介してアタッチされたポリシーを持つユーザー/ロール/グループでさえ、そのアタッチされたポリシーがこのリソースによって取り消される可能性がある</font>と記載があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435702/73cb1de7-d370-4ff4-700a-3b1a6b57f18e.png)

### 既に使用していて削除したい場合
terraform state rmを使用して、<font color="Blue">iam_policy_attachment</font>をtfstate外に移動してから、
`terraform destroy`してあげれば問題無く削除できます。