雲服務可謂是基礎架構即代碼 IaC (Infrastructure as Code)的最佳實踐,經過代碼來定義計算和網絡基礎設施,完成客戶所需。但是,你真的瞭解 IaC 嗎?若是一個公司採用基礎設施即代碼的方式的話,他有什麼樣的風險?mysql
本文將經過如下五點爲您詳細講解:git
什麼是 Terraformsql
Terraform 是一個安全、高效地部署、更改、版本化基礎設施和應用程序的工具,能夠用來管理多層次的資源。從上層的軟件配置到底層的網絡、系統配置均可以使用 Terraform 統一進行管理。docker
Terraform 用配置文件來描述一個應用。Terraform 會將配置文件與當前環境對比後,生成一個執行計劃,這個計劃會列出爲了達到配置文件中定義的狀態所須要執行的操做,而後執行計劃以達到指望的狀態。數據庫
Terraform 經過插件機制管理不一樣的資源提供者,以此來接入各類資源,如虛擬機,存儲,網絡和各類應用服務。編程
Infrastructure as Code後端
將基礎架構使用配置語法進行描述,這可讓數據中心的構建計劃能夠像其餘代碼同樣進行版本化和追蹤。瀏覽器
Execution Plans安全
Terraform有一個規劃步驟,它生成一個執行計劃。執行計劃顯示當您調用應用程序時 Terraform 將執行的操做。使用這個功能能夠保證操做基礎設施時不發生意外服務器
Resource Graph
Terraform 建立了一個全部資源的視圖。這使得 Terraform 能夠並行化沒有依賴的建立與修改。
所以,Terraform 能夠高效地構建基礎架構。操做人員也能更加了解環境的結構。
Change Automation
Terraform 會自動的分析什麼是須要修改的,從而避免了許多可能的人爲錯誤。
與 Terraform 相似的 Infrastructure as Code 工具大概有下面幾種:
下面將從幾個方面來講明 Terraform 與其餘工具對比的優點。
Chef、Puppet、Ansible、SaltStack 均可以稱爲配置管理工具,這些工具的主要目標是在已經存在的機器上安裝和管理軟件。
而 Terraform 和 CloudFormation 能夠稱爲編排工具,更注重於數據中心以及相關服務的高級抽象。他們的工做重點是建立資源而且引導進行初始化。
並且在如今的環境下,你們使用容器等服務,鏡像已經包括了軟件的安裝與配置。一旦你有了鏡像,你須要的是一些服務器去運行它。
對於提供服務器這種需求,編排工具會比配置管理工具更適合作此類工做。
Chef 和 Ansible 但願你去一步步編寫程序以達到最終所指望的狀態。
Terraform、CloudFormation、SaltStack、Puppet 但願你去聲明最終想要的資源與資源的狀態,工具自己會自動分析達到想要的狀態須要進行怎樣的操做。
在使用編程式語言時,工具不會獲取歷史的狀態,因此咱們須要考慮的更多以達到與以前版本的兼容。
而且使用編程式語言會致使代碼庫變得愈來愈龐大,不利於人們理解與代碼的複用。不過聲明式的語言的表達能力是較爲欠缺的,例如咱們須要基礎設施的滾動升級時,聲明式的語言是很難知足要求的。
爲此 Terraform 提供了一些基礎服務,例如輸入變量,輸出變量,在銷燬以前建立等。
Chef、Puppet、SaltStack 在默認狀況下都使用了客戶端服務器架構。客戶端(多是 Web UI 或 CLI 工具)是用來發出命令(例如「deploy X」)的東西。
這些命令到達一個服務器,它負責執行你的命令並存儲系統的狀態。要執行這些命令,服務器會與 agent 進行通訊,agent 必須在要配置的每一個服務器上運行,這有幾個缺點:
CloudFormation 也是客戶端/服務器架構,但 AWS 透明地處理全部的服務器細節,做爲最終用戶,您只須要考慮客戶端代碼。Ansible 客戶端則經過 SSH 直接鏈接到您的服務器。
Terraform 使用雲提供商 API 來配置基礎架構,所以除了您已經使用雲提供商以外,沒有新的身份驗證機制,而且不須要直接訪問您的服務器。
比較表格
應用場景 1
某應用使用了 Loadbalancer 進行 Instance 間的流量均衡處理,以增大吞吐率、擴大併發數、縮短延遲。
操做步驟:新建安全組、添加安全組規則、申請彈性公網 IP、建立負載均衡器、建立 Instance、在負載均衡器中添加負載均衡器監聽器、配置會話保持、添加健康檢查、在負載均衡器監聽器中添加後端……
應用場景 2
某應用須要隔離的網絡環境,須要將應用搭建在 VPC 網絡當中,架構以下:
操做步驟:
建立安全組、配置安全組、申請彈性公網 IP、建立 VPC、建立 vxnet、建立負載均衡器、配置負載均衡器、建立 Instance 等配置操做。
應用場景 3
隨着業務調整和業務量增大,須要增長更多的節點和集羣以承載更多的請求,此時須要對已有的資源進行擴容:
應用場景 4
隨着應用的不斷迭代,應用部署和發佈的成本也在增長,如何實現應用的快速部署和發佈:
上述場景的共性:
針對場景1、二:建立基礎設施
使用 Terraform,咱們能夠對基礎設施進行編碼,利用代碼來進行資源的增刪查改。
針對場景3、四:擴容和部署
修改資源代碼以改變基礎設施,並利用 privisioner 幫助運行部署腳本,完成擴容和部署。
快速和安全
利用代碼進行建立資源的速度能夠是人工點擊的幾倍甚至幾十倍。
任何人均可以隨時創建起一個環境
只要擁有基礎設施代碼的訪問權限,就能夠本身完成環境的建立,而不須要其餘團隊的幫助。
避免雪花服務器
人工配置環境可能會致使出現雪花服務器,而使用 Terraform 自動配置則不容易出現。
全部的環境使用相似的代碼
使用 Terraform 你能夠輕鬆的控制副本的數量,方便建立一個小的開發/測試環境,或者一個大的生產環境。
像對待應用代碼同樣對待基礎設施
方便不斷的改進基礎設施的代碼。享受版本管理工具的歷史查看、回滾、備份存儲等功能。
在部署以前驗證架構
對基礎設施代碼作靜態分析,能夠大大下降出錯的可能性。
追蹤基礎設施的變化。
若是在部署當中發生了錯誤,能夠快速恢復到上一個版本,審計人員也能夠經過歷史記錄進行審計。
快樂
這是一個很是重要可是常常被忽視的優勢。手動部署代碼和管理基礎架構是重複和乏味的。開發人員和系統管理員對這種工做感到不滿,由於它不涉及創造力,沒有挑戰,也沒有承認。
除非你部署失敗了,否則沒有人會關注你。
這形成了一個壓力和不愉快的環境。Terraform 提供了一個更好的選擇,容許計算機作他們最擅長的(自動化執行)和開發人員來作他們最擅長的(編碼)。
1.Terraform 及 terraform-provider-qingcloud 安裝
安裝 Terraform
咱們首先安裝 Terraform,咱們須要進到 Terraform 的官網找到適合的軟件包進行下載。
下載 Terraform 後,解壓壓縮包。壓縮包中有一個名爲 Terraform 的文件,咱們只須要這個二進制文件就可使用 Terraform 了。
最後一步是設置 Terraform 的 PATH。如何在 Linux 和 Mac 中設置 PATH 能夠參考這個頁面, 如何在 Windows 當中設置 PATH 能夠參考這個頁面。
驗證 Terraform 安裝
在安裝完 Terraform 以後,咱們能夠打開一個新的終端來驗證 Terraform 安裝成功了。
執行 terraform -v 能夠看到相似下面的輸出:
安裝 terraform-provider-qingcloud
terraform-provider-qingcloud 一樣是以二進制文件進行發佈,咱們能夠到 Github 上找到適合的軟件包進行下載。
下載並解壓之後會有一個二進制文件。
在 Linux 以及 Mac 當中咱們須要將這個二進制文件放到 ~/.terraform.d/plugins/ 當中。在 Windows 當中把這個二進制文件放到用戶的「Application Data」目錄下的 terraform.d/plugins/ 當中。
2.Terraform 使用-以 wordpress 爲例
下面咱們以 wordpress 爲例演示如何使用 Terraform 在青雲中從零開始部署一整套環境。部署下圖中所示的基礎設施及軟件資源。
例子源碼請單擊「閱讀原文」查看。
注意:使用 terraform apply 會建立實際的資源,可能會產生一些費用。
理解配置文件
Terraform 全部的配置文件以 tf 做爲後綴名。在執行相關命令時,Terraform 會自動加載當前目錄下的 *.tf 文件。
Terraform 的配置文件是 HashiCorp 公司的 HCL 語言。
Terraform init
與 git 相似,咱們須要在 Terraform 項目的根目錄運行 terraform init 去初始化項目。
在初始化項目的時候,Terraform 會解析目錄下的*.tf文件並加載相關的 provider 插件。在 wordpress 文件夾下運行 terraform init 會看到相似下面的輸出:
驗證 Terraform init
在 wordpress 文件夾下運行 terraform -v 會獲得相似下面的輸出:
指定 Provider
在 ./provider.tf 文件咱們指定了 Provider,QingCloud 的 Provider 須要 access_key 與 secret_key 進行調用 API,key 能夠在 QingCloud Web 控制檯進行申請。
zone 指定了資源會在哪一個區中進行建立,默認爲 Pek3a 區。
理解 Resource
HCL 語言是一種聲明式語言,即在 *.tf 文件中聲明瞭咱們所指望的資源狀態。
咱們在 ./modules/qingcloud/qingcloud.tf 文件當中指定了咱們想要的資源以及他們的狀態。
在定義的資源的時候咱們能夠在一個資源當中引用其餘資源的字段,Terraform 會自動解析這些引用而且按順序進行建立。
在上面的這一小段代碼當中,qingcloud_security_group_rule 爲資源的名稱,須要 Provider 支持特定的資源。
ssh-wordpress-in 爲資源的別名,是在這個項目當中惟一的。
上面咱們建立了一個類型爲 qingcloud_security_group_rule 的資源,也就是一個防火牆規則資源。
在這個資源中咱們指定了防火牆的 ID,以及規則的協議、優先級、動做、方向以及端口範圍。
注意:在建立資源 qingcloud_keypair.foo 的時候咱們是上傳用戶的 >~/.ssh/id_rsa.pub 文件,
這個公鑰須要用戶本身去生成,具體生成方法能夠參考文檔 一樣咱們在使用 provisioner 安裝軟件環境時使用了 ~/.ssh/id_rsa 做爲私鑰進行了遠程鏈接,若是須要修改的話請自行修改配置文件。
在整個例子的源碼當中,咱們分別建立了下列資源:
若是須要獲取更多有關 terraform 基本操做的信息,能夠參考官方文檔的 Getting Started 部分。
獲取更多資源的使用信息,能夠查看 terraform-qingcloud-provider 的文檔
利用 Built-in Functions 避免手工操做
在建立 resource qingcloud_keypair 的時候,咱們使用了 Terraform 的內置函數去幫助獲取文件 ~/.ssh/id_rsa.pub 的內容。從而避免了咱們手工複製粘貼。
Terraform 內置了許多函數幫助用戶解決一些常見操做,若是須要獲取更多的信息,請參考官方文檔。
使用 Provisioners 進行環境配置
Provisioners 能夠在資源建立/銷燬時在本地/遠程執行腳本。
Provisioners 一般用來引導一個資源,在銷燬資源前完成清理工做,進行配置管理等。
Provisioners 擁有多種類型能夠知足多種需求,如:文件傳輸(file),本地執行(local-exec),遠程執行(remote-exec)等 Provisioners 能夠添加在任何的 resource 當中:
在 example 當中,咱們使用了 null_resource 和 provisioner 完成了 qingcloud_instance 上安裝 docker 並啓動 wordpress 與 mysql。在 null_resource.run_docker_wordpress 當中,咱們指定了 depends_on 參數,保證了在 mysql 已經啓動成功後再啓動 wordpress。
執行 Terraform plan 查看 Terraform 計劃
Terraform plan 命令用於輸出執行計劃。除非明確禁用,Terraform 會調用 refresh 方法從新查詢當前資源的狀態。
完成狀態刷新後,Terraform 會自動分析要進行的操做以達到配置文件中所須要的狀態,並把分析的結果輸出出來。在 vpc_one_instance 文件夾下執行 Terraform plan 會獲得相似下面的結果:
使用 module 進行代碼的組織管理
Terraform 中的模塊是以組的形式管理不一樣的 Terraform 配置。模塊用於在 Terraform 中建立可重用組件,以及用於基本代碼組織。每個 module 均可以定義本身的 input 與 output,方便代碼進行模塊化組織。
在例子當中咱們將配置文件分紅了兩個 module 進行處理:module qingcloud 負責在qingcloud 建立所須要的基礎設施資源。module wordpress 負責在建立好的虛機當中安裝 docker 而且啓動 wordpress 與 mysql。
其中須要安裝 wordpress 的機器信息是經過 input 傳入進來的,而傳入進來的 input 其實是 module qingcloud的output。經過 input 與 output,咱們將兩個模塊鏈接到了一塊兒。在 ./module.tf 當中,咱們調用了兩個 module 指定了兩個 module 的參數傳遞關係。
使用 Terraform apply 提交資源建立及配置
Terraform apply 命令用於應用所需的更改以達到所需的配置狀態。爲了更加方便的獲得咱們所關注的輸出結果,可使用 output 單獨輸出部分字段。如在 ./module.tf 當中,咱們單獨獲取了 module.wordpress 的 public_ip:
填寫 provider.tf 中的 access_key 與 secret_key 後,咱們使用 terraform apply 能夠完成資源的建立與配置。
注意:在 example 中是根據文件來獲取 SSH key,在您機器上可能不存在此文件,請您自行建立 SSH key。
咱們會在輸出的結尾獲取到相似下圖的輸出:
打開瀏覽器,輸入 output的IP,能夠看到 wordpress 已經正常運行:
多層應用的部署
通常來說應用都是分爲 N 層架構的,而咱們的例子是一個很是典型的二層應用,分別是業務邏輯層的 wordpress 和數據層的 mysql。
Terraform 確保數據庫層在 Web 服務器啓動前可用。這得益於 Terraform 能夠自動的去解析資源之間的關係,保證了有依賴關係的各層能夠按順序進行建立。
多雲環境的部署
人們一般將基礎架構分佈在多個雲中以提升容錯性。經過僅使用單個區域或雲提供商,容錯受限於該提供商的可用性。進行多雲部署能夠更好地恢復地區或整個提供商的損失。
Terraform 是與雲無關的,咱們可使用不一樣的 provider 實現多雲環境的部署。而且能夠將一個項目拆分爲多個 module 實現代碼的複用。
前面的例子當中,咱們分爲了兩個 module,其中 module wordpress 是不依賴於雲環境的 module,咱們能夠在不一樣雲提供商中複用這個 module。
在同一個項目中一樣可使用多個提供者,甚至還能處理多個雲當中的依賴關係。這能夠幫助用戶建立大型的雲基礎架構。
軟件定義網絡的配置
軟件定義網絡(SDN)在數據中心中愈來愈流行,它爲用戶提供了更多的控制權,同時也帶來了人爲管理負擔。通常來說 SDN 分爲控制層與轉發層。
Terraform 能夠編寫 SDN 的配置文件,這些配置能夠由 Terraform 自動調用控制層的接口生效。這些配置文件是能夠進行版本化的。
例如,QingCloud VPC 是一種很是典型的 SDN,這種資源咱們是能夠利用 Terraform 進行管理,完成控制層的配置。
一次性測試環境
使用 Terraform 測試環境是能夠被編碼的,這些配置文件能夠在 QA、開發等團隊中進行分享,能夠極大減小開發測試團隊重複準備環境的負擔,減小人爲錯誤,提升工做效率。
而且 Terraform 能夠一鍵的進行資源的建立與刪除,這能夠幫助咱們快速的建立測試環境,完成使用後能夠進行及時的刪除。