Terraform 助力 ECS 實例借助 RAM 管理阿裏雲產品
眾所周知,不論以怎樣的方式訪問阿裏雲產品的 API,擁有賬號完整權限的密鑰AK(Access Key ID 和 Access Key Secret,簡稱 AK)是必不可少的參數。因此,對 AK 的有效管理是每個調用阿裏雲 API 的應用程序首先需要解決的問題。
對於部署在 ECS 實例上的應用程序而言,為了方便對 AK 的管理,通常需要將 AK 保存在應用程序的配置文件中或 ECS 實例的環境變量中,如此一來,無疑增加了 AK 管理的複雜性,降低了 AK 的安全性和靈活性。除此之外,對於多 Region 一致性部署應用的場景而言,AK 往往會隨著鏡像以及基於鏡像創建的實例擴散出去,此時,將不得不更新鏡像和逐台重新部署實例,從而應用部署的複雜度也將隨之增加。
麵對以上困境,我們可借助於 RAM 角色功能,將 RAM 角色 和 ECS 實例關聯起來,使得實例內部的應用程序可以通過 STS 臨時憑證(由係統自動生成和更新,詳見 RAM And STS)訪問其他雲產品的 API。應用程序無需管理 STS 臨時憑證,直接通過實例元數據 URL 即可獲取。同時,通過對 RAM 角色和授權策略的管理,可以達到不同實例對不同雲產品或相同雲產品具有各自訪問權限的目的。
值得注意的是,每個 RAM 角色可同時被授權多個策略,通常我們的做法是為某一角色逐個授權相應的策略,同時,對於已有的 ECS 實例,我們需要逐台綁定某一角色,如何實現對 RAM 角色的自動化管理,授權策略的靈活設置以及為角色批量綁定 ECS 實例呢?本文將借助於自動化運維工具 Terraform 給出最佳的實踐方案。
正如上圖所示,基於 Terraform 實現了 RAM Role,Policy以及 ECS 實例的創建,為 Role 配置 Policy,並將配置後的 Role 掛載到 ECS 實例上,進而幫助實例上的應用程序訪問阿裏雲的其他雲服務。
本文將以 ECS 實例借助於 RAM 角色訪問 OSS 服務為例,向大家展示如何基於 Terraform 實現從 RAM 角色的創建,授權策略的設置到ECS 實例的綁定以及如何在綁定了 RAM 角色的 ECS 實例上利用 Python 訪問 OSS 服務的。
定義 RAM 角色
首先編寫 Terraform 模板,定義 RAM Role:
resource "alicloud_ram_role" "role" {
name = "EcsRamRoleTest"
services = ["ecs.aliyuncs.com"]
description = "Test role for ECS and access to OSS."
force = true
}
模板定義了一個 RAM Role:EcsRamRoleTest,並為該角色配置了一個受信雲服務 ECS,表示該角色為一個服務角色,受信雲服務 ECS 可以扮演該角色。其中,設置 force = true
表示在通過 Terraform 釋放該 Role 時會強製解除與該 Role 相關聯的所有關係。
定義 RAM 授權策略
接下來在模板中定義 RAM Policy:
resource "alicloud_ram_policy" "policy" {
name = "EcsRamRolePolicyTest"
statement = [
{
effect = "Allow"
action = ["oss:Get*", "oss:List*"]
resource = [ "*" ]
}
]
description = "Test role policy for ECS and access to OSS."
force = true
}
模板定義了一個自定義的授權策略 EcsRamRoleTest
,並為該 Policy 中聲明了 OSS 隻讀權限的策略。和 RAM Role 類似,設置 force = true
表示在通過 Terraform 釋放該 Policy 時會強製解除與該 Policy 相關聯的所有關係。
為 RAM 角色授權策略
在定義好 RAM Role 和 Policy 之後,接下來需要將 Policy 跟 Role 進行綁定,為 Role 進行策略授權:
resource "alicloud_ram_role_policy_attachment" "role-policy" {
policy_name = "${alicloud_ram_policy.policy.name}"
role_name = "${alicloud_ram_role.role.name}"
policy_type = "${alicloud_ram_policy.policy.type}"
}
模板利用將創建好的 Policy 綁定到 Role 上,使得 Role 具有訪問某種雲產品服務的權限。
定義 ECS 實例
接下來基於 Terraform 創建一個 ECS 實例,用來綁定 Role 和部署應用:
resource "alicloud_vpc" "vpc" {
name = "vpc_for_ecs_role"
cidr_block = "172.16.0.0/12"
}
resource "alicloud_vswitch" "vswitch" {
name = "subnet_for_ecs_role"
vpc_id = "${alicloud_vpc.vpc.id}"
cidr_block = "172.16.0.0/21"
availability_zone = "cn-beijing-a"
}
resource "alicloud_security_group" "sg" {
name = "sg_for_ecs_role"
vpc_id = "${alicloud_vpc.vpc.id}"
}
resource "alicloud_security_group_rule" "22_rule" {
security_group_id = "${alicloud_security_group.sg.id}"
type = "ingress"
policy = "accept"
port_range = "22/22"
ip_protocol = "tcp"
nic_type = "intranet"
priority = 1
cidr_ip = "0.0.0.0/0"
}
resource "alicloud_instance" "instance" {
# cn-beijing
vswitch_id = "${alicloud_vswitch.vswitch.id}"
image_id = "ubuntu_140405_32_40G_cloudinit_20161115.vhd"
availability_zone = "cn-beijing-a"
# series III
instance_type = "ecs.n4.large"
system_disk_category = "cloud_efficiency"
internet_charge_type = "PayByTraffic"
internet_max_bandwidth_out = 20
allocate_public_ip = true
security_groups = ["${alicloud_security_group.sg.id}"]
instance_name = "instance_for_role"
password = "Test12345"
}
因為 ECS 實例 RAM 角色目前隻支持 VPC 網絡的實例,所以模板創建了一個 VPC 環境下的 ECS Instance,實例的鏡像是 ubuntu_140405_32_40G_cloudinit_20161115.vhd
, 規格是ecs.n4.large
,通過allocate_public_ip = true
為該實例分配了公網 IP,並為其設置了 20M 的帶寬。 在創建 instance 的同時,還新建了 VPC, VSwitch 和安全組資源。為了可以遠程連接 ECS 實例,為安全組創建了入方向的安全組規則,打開了 SSH 協議需要的 22 端口。
為 ECS 實例配置 RAM 角色
在完成 ECS 實例的創建和 RAM Role 的配置之後,接下來需要將 RAM Role 和 ECS 實例進行綁定,以幫助實例上的應用可以直接訪問其他雲資源:
resource "alicloud_ram_role_attachment" "attach" {
role_name = "${alicloud_ram_role.role.name}"
instance_ids = ["${alicloud_instance.instance.*.id}"]
}
定義 OSS Bucket
為了更好的測試結果,我們可通過 Terraform 新建一個 OSS Bucket,並為該 Bucket 上傳兩個 Object:
resource "alicloud_oss_bucket" "bucket" {
bucket = "my-bucket-for-ram-role-test"
acl = "public-read"
}
resource "alicloud_oss_bucket_object" "content-1" {
bucket = "${alicloud_oss_bucket.bucket.bucket}"
key = "object-content-key-1"
content = "some words for test oss object content 1."
}
resource "alicloud_oss_bucket_object" "content-2" {
bucket = "${alicloud_oss_bucket.bucket.bucket}"
key = "object-content-key-2"
content = "some words for test oss object content 2."
}
如上所示,模板定義了一個 OSS Bucket:"my-bucket-for-ram-role-test" 和兩個 OSS Object,分別為:"object-content-key-1" 和 "object-content-key-2".
訪問 ECS 實例並測試
接下來,我們登錄到 ECS 實例上借助於 Python 訪問 OSS 服務來測試 Role 以及 Policy 生效。具體步驟如下:
- 遠程連接 ECS 實例
-
獲取 STS 臨時憑證
訪問 https://100.100.100.200/latest/meta-data/ram/security-credentials/\ 即可獲取 STS 臨時憑證,其中<RAM-Role-Name>
表示 RAM 角色名稱,在這裏我們將其設置為 “EcsRamRoleTest”。
運行結果如下:root@iZ2XXXXXXXXX:~# curl https://100.100.100.200/latest/meta-data/ram/security-credentials/EcsRamRoleTest { "AccessKeyId" : "STS.LS6XXXXXXXXXXXXXXXXuW", "AccessKeySecret" : "HCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXeAm", "Expiration" : "2017-08-18T13:17:39Z", "SecurityToken" : "CAIXXXXXXXXXXXXXXXXqq/etTxxxxxxxxxxxx6Mv/lXXXXXXXXXGW1", "LastUpdated" : "2017-08-18T07:17:39Z", "Code" : "Success" }
結果顯示,我們使用了
curl
命令成功地獲取到了STS
憑證,由此表明 RAM Role 已經與 ECS 實例綁定成功。 基於臨時憑證,使用 Python SDK 訪問 OSS
本示例中,我們基於 STS 臨時憑證使用 Python SDK 列舉實例所在地域的 OSS Bucket 裏的 2 個對象。具體測試步驟如下:
* 執行如下命令,安裝 OSS Python SDK
$ sudo pip install oss2
* 執行下述命令進行測試,其中:
* oss2.StsAuth 中的 3 個參數分別對應於上述 STS 裏的 AccessKeyId、AccessKeySecret 和 SecurityToken。
* oss2.Bucket 中後 2 個參數是 Bucket 的名稱和 Endpoint。本示例中,Bucket 名稱為 `my-bucket-for-ram-role-test`,Endpoint 為 `oss-cn-beijing.aliyuncs.com`。
示例輸出結果如下:
root@iZ2XXXXXXXXX:~# python
Python 2.7.6 (default, Oct 26 2016, 20:32:47)
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import oss2
>>> from itertools import islice
>>> auth = oss2.StsAuth("STS.LS6XXXXXXXXXXXXXXXXuW", "HCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXeAm", "CAIXXXXXXXXXXXXXXXXqq/etTxxxxxxxxxxxx6Mv/lXXXXXXXXXGW1")
>>> bucket = oss2.Bucket(auth, "oss-cn-beijing.aliyuncs.com", "my-bucket-for-ram-role-test")
>>> for b in islice(oss2.ObjectIterator(bucket), 2):
... print(b.key)
...
object-content-key-1
object-content-key-2
>>>
以上的運行結果顯示,將 RAM Role 與 ECS 實例成功綁定後,ECS 實例可利用 STS
臨時憑證成功地實現對 OSS 服務的訪問,由此驗證了整個運行流程的正確性。
寫在最後
本文借助 RAM 角色訪問雲服務的功能,基於 Terraform 向大家展示了如何快速的實現 RAM 角色的創建,授權策略的設置,ECS 實例的創建以及綁定 RAM Role 等一係列操作,並通過測試驗證了整個流程的有效性。
作為一個自動化運維工具,Terraform 的出現大大降低了資源編排的複雜度,簡化了基礎設施資源及其環境的搭建流程,同時對資源模板的版本化管理更是為基礎設施資源的持續管理提供了方案,正如本文所展示的,當我們需要使用 OSS 的其他權限,或者訪問其他雲產品,或者讓更多的 ECS 實例具有同樣的權限的時候,隻需要對如上的模板做一些適當的變更,如為 Policy 設置更多更豐富的 "statement",在 alicloud_instance
中設置 "count" 參數實現對 ECS 實例的平滑擴容等,然後隻需運行一條簡單的命令terraform apply
即可實現對原資源的快速升級和變更,省時又省力。
目前,麵向阿裏雲的 Terraform Provider 仍在不斷的發展和完善中,歡迎大家使用和提供寶貴的意見和建議。以下是相關參考資料,歡迎大家查閱。
Terraform Provider Github 地址:https://github.com/alibaba/terraform-provider
Terraform Provider Document:Github: https://github.com/alibaba/terraform-provider-docs
Terraform Provider Package:https://github.com/alibaba/terraform-provider/releases
ECS 實例元數據獲取 STS 臨時憑證指南: https://www.alibabacloud.com/help/zh/doc-detail/49122.htm?spm=a3c0i.o54579zh.a3.7.4131bb5bwgOONE
備注:本文所涉及到的模板,可通過附件下載和使用。
最後更新:2017-08-19 01:33:06