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, 但是實際上裡面還在慢慢斷開, 沒那麼快拆完...
沒有留言:
張貼留言