今天遇到同事在用 EC2 時因為用錯 IAM Role 要改成正確的 IAM Role 出現錯誤訊息「The association iip-assoc-080ac67c0d1b2ad10 is not the active association」
先講怎麼解這個問題
正常狀況下 EC2 是可以正常切換不同 IAM Role,這沒問題。
但在這個 case 是:
- Role-CodeDeploy:舊 IAM Role 的 trust policy 是 Principal from service “codedeploy.amazonaws.com”
- Role-EC2:新 IAM Role 的 trust policy 是 Principal from service “ec2.amazonaws.com”
就這樣看起來會有問題是正常的,直接聯想是 EC2 就沒有權限可以用 Principal = codedeploy 的 IAM Role,這樣的使用情境是錯誤的,但應該可以 unattach 吧
但不管是 change Role 或是 unattach Role 都會出現錯誤:
「The association iip-assoc-080ac67c0d1b2ad10 is not the active association」
然後這台 EC2 的 Role 就這樣卡住了 ….
為了追根究柢的精神所以深入調查 (其實可以砍掉 EC2 重建就好啦)
首先我先參考這篇「動態修改 EC2 的 Role」了解 API 怎麼處理 EC2 和 Role 的關係,裡面有提到要 Attach Role 給 EC2 需要 iam-instance-profile 和 association-id
錯誤 1
首先 iam-instance-profile 是 IAM 提供給 instance 用的 profile,如果沒有建立 iam-instance-profile 你的 EC2 就沒有辦法 Attach Role (Manager console 也選不到),在這個 case 上因為我在 SOP 文件多寫了 create iam-instance-profile 這段,所以讓 EC2 可以選到 Principal codedeploy 的 Role。
接下來用 describe-iam-instance-profile-associations 這個 API 去查看 EC2 iam-instace-profile
$ aws ec2 describe-iam-instance-profile-associations
錯誤 2
把 EC2 和 iam-instance-profile 關聯起來後會產生 association-id,當你查看 EC2 的 iam-instance-profile 的時候會有一個 “State”,這就是你把 iam-instance-profile 和 EC2 關聯的 “狀態”,一般是 associated 或 disassociating,但是當 錯誤 1 產生後因為 EC2 沒有權限能用 Role-CodeDeploy,所以 State 一直呈現 “associating” 然後關聯不起來 … 所以就出現了 “卡住” 的狀況
遇到這個狀況只能 Call API 去把 iam-instance-profile 給 disassociate
如果用 awscli 的話可以用 disassociate-iam-instance-profile 這隻 API
$ aws ec2 disassociate-iam-instance-profile --association-id iip-assoc-028dc7a63c3be0dc1 { "IamInstanceProfileAssociation": { "InstanceId": "i-0b203dd32223333", "State": "disassociating", "AssociationId": "iip-assoc-028dc7a63c3be0dc1", "IamInstanceProfile": { "Id": "ABCDEFGHIJKLMNOPQ", "Arn": "arn:aws:iam::0123456789:instance-profile/Role_CodeDeploy-Profile" } } }
由於 IAM 是透過 SQS 來處理 Job,所以在一開始更換 Role-EC2 這個動作雖然失敗了,但他還是有留在 SQS (只要時效還在),所以當 State 沒有 lock 後 Role-EC2 就自動 Attach 上 EC2 了!