2024年6月6日 星期四

AWS - IAM Role with Policy

AWS 的 IAM Role 跟 Policy 有兩種連接方式:
- Role 內嵌 Policy.
- Role 和 Policy 是各自建立, 然後再接起來(attach)用.

以 Policy 編修來說, 前者就只能在 portal 上面 CRUD, 後者在 Policy 本身的 portal 介面還可以看 permission 檢查, 歷次編修版本與控管, 相同的 Policy 還可以接到多個 Role 共用, 後來我也盡量都用後者.

不過後者在 Terraform 的寫作上有需要注意的地方, 一般寫法如下:
resource "aws_iam_policy" "this" {} resource "aws_iam_role" "this" {} resource "aws_iam_role_policy_attachment" "this" { depends_on = [ aws_iam_role.this, aws_iam_policy.this ] }

在 terraform apply 的時候不成問題, 但是在 terraform destroy 會發生 race condition: Policy 還沒從 Role 拆出來, 上面這個寫法會造成 aws_iam_policy 跟 aws_iam_role 同時進行 destroy, 在刪除 aws_iam_policy 就會噴錯誤訊息, 說 Policy 還接在 Role 上面所以不能被砍掉.

雖然再執行一次 terraform destroy 就過了(錯誤是在砍 aws_iam_policy 的時候噴的, 但同時砍 aws_iam_role 的動作是有被完成), 但是這樣對於砍站跑路就不夠徹底順暢.

簡單解決的方式就是在 aws_iam_role 裡面加一個 depends_on aws_iam_policy:
resource "aws_iam_role" "this" { ... depends_on = [ aws_iam_policy.this ] }

這樣子在 destroy 的時候, aws_iam_role 就會先被刪除(無論 Policy 拆出來了沒), 再刪除 aws_iam_policy 就不會卡住了.

然後第一個方式在 Terraform 有個地雷, Role 內嵌 Policy 大概是這樣寫:
resource "aws_iam_role" "this" { ... inline_policy { name = "Role-foobar-Policy" ... } }
當不要用 inline_pocily 的時候, 把這段刪除成這樣:
resource "aws_iam_role" "this" { ... }

然後 terraform apply 的時候, diff 並沒有出現 - 掉 inline_policy 這塊的訊息, 實際上 Terraform 真的沒做這個刪除, 在 portal 是還看得到 inline_policy 的存在, 得在這邊手動砍掉才算沒了.


AWS IAM 有好幾個拆連接的動作會產生 race condition, 表面上 API 回應 ok, 但是實際上裡面還在慢慢斷開, 沒那麼快拆完...

沒有留言:

張貼留言