Terraform最佳實踐

Terraform 又是什麼新工具

幫你建立刪除資源。它使用起來很是簡單,咱們但願用戶能把精力全都集中開發工做上,而不是考慮管理資源這種雜事上。html

我儘可能讓這篇文章通俗易懂,不管你是從事什麼工做,只要你的工做內容跟雲資源管理有一點點關係,都能從Terraform中受益git

最快的上手的方法永遠是先用一下試試,按照下面的方法去作:github


Step - 1  準備一些原料

  • Terraform 
    • 在官網下載一個不到15M大小的文件,下載完成之後解壓,並添加對應PATH,完成之後在命令行裏輸入 terraform 有反應則表明安裝成功
  • AccessKey / SecretKey
    • 準備 AccessKey SecretKey ,它們能夠在京東雲控制檯的帳戶欄下找到 。用於鑑別你的身份,建立你帳戶下的資源。


Step - 2  配置 Terraform

咱們會用一個文件用於描述咱們須要的資源, 在當前目錄下建立一個名叫 jdcloud.tf 的文件,並在這個文件裏寫入下面的內容:ubuntu

provier "jdcloud" {
    access_key = "your_access_key"
    secret_key = "your_secret_key"
    region = "cn-north-1"
}

resource "jdcloud_vpc" "local-name" {
  vpc_name = "my-vpc"
  cidr_block = "172.16.0.0/20"
  description = "terraform rules"
}複製代碼
  • 第一項 provider-jdcloud
    • 表明服務提供商是京東雲,寫下你的 AccessKey SecretKey 以及區域信息,它們用於鑑別你的身份,並在對應區域內建立你的資源
  • 第二項 resource-jdcloud-vpc
    • 表明咱們想建立一個京東雲下的VPC資源,寫下這個VPC的名稱以及CIDR,描述是選填項能夠不寫,就像在網頁上建立資源同樣

這份配置文件包含了身份信息以及資源信息,已是一份完整可用的配置文件了。api


Step - 3 初始化 Terraform

在配置文件中咱們聲明瞭一個新服務商 - 京東雲,爲了能使Terraform接入京東雲資源管理,Terraform須要去下載京東雲插件,這一切都是 Terraform 自動完成的,咱們只須要一個命令安全

$ terraform init

> Initializing provider plugins...

  Downloading plugin for provider "jdcloud" (0.0.1)...

  * provider.jdcloud: version = "~> 0.0"

  Terraform has been successfully initialized!複製代碼


Step - 4 建立資源

經過一個指令,Terraform會爲先爲你生成一個行動計劃,在本示例中則是建立出一個VPC, 等待你確認此次行動,輸入「yes」,纔會纔開始建立bash

$ terraform apply

> Terraform will perform the following actions:

  + jdcloud_vpc.jd-vpc-1
      id:          <computed>
      cidr_block:  "172.16.0.0/20"
      description: "terraform rules"
      vpc_name:    "my-vpc"

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?

  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

--------------------------------------------------
  Enter a value: yes
--------------------------------------------------

jdcloud_vpc.jd-vpc-1: Creating...
  cidr_block:  "" => "172.16.0.0/20"
  description: "" => "vpc1"
  vpc_name:    "" => "my-vpc-1"

---------------------------------------------------
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
---------------------------------------------------複製代碼

建立成功了,咱們能夠登錄控制檯查看這項資源是否被成功建立,果真是在這兒的網絡



Step - 5 修改資源

簡單來講,用戶須要去作的,只是在 jdcloud.tf 裏修改相應資源, 然後經過 terraform apply 便可完成修改,使用上當前的配置。架構

有的配置例如名稱,描述等是可供修改的。在terraform apply的時候會提示一項資源即將修改: app

$ terraform apply

> jdcloud_vpc.jd-vpc-1: Refreshing state... (ID: vpc-qdpipn8mn2)

  ~ jdcloud_vpc.jd-vpc-1
      vpc_name: "my-vpc" => "modified-name"

-------------------------------------------------------
Plan: 0 to add, 1 to change, 0 to destroy
-------------------------------------------------------

jdcloud_vpc.jd-vpc-1: Modifying... (ID: vpc-qdpipn8mn2)
  vpc_name: "my-vpc" => "modified-name"

--------------------------------------------------------
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
--------------------------------------------------------複製代碼


可是有些配置則是不能修改的,好比VPC的CIDR屬性在建立以後就不能修改,若是嘗試修改CIDR屬性,Terraform會爲你銷燬當前資源並重建一個。  在下面的日誌中 Terraform 會用-/+的方式提示你,terraform會先銷燬當前資源並重建,同時提示你 new resource required

$ terraform apply

> jdcloud_vpc.jd-vpc-1: Refreshing state... (ID: vpc-qdpipn8mn2)

-------------------------------------------------------
    -/+ jdcloud_vpc.jd-vpc-1 (new resource required)
-------------------------------------------------------
          id:          "vpc-qdpipn8mn2" => <computed> (forces new resource)
          cidr_block:  "172.16.0.0/20" => "172.16.0.1/20" (forces new resource)
          description: "vpc1" => "vpc1"
          vpc_name:    "modified-name" => "modified-name"

---------------------------------------------------------
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
---------------------------------------------------------複製代碼


爲何必定要用Terraform ?

在剛剛的例子中咱們只是建立一個簡單的資源,terraform看似平平無奇。只是作了一些全部SDK都能作的事。可是在實際生產中咱們的結構每每是比較複雜的環境,VPC / 子網 / 雲主機 / 路由等等穿插交織在一塊兒,相互依賴。

這種狀況下,就算只是想調整一個VPC的網段都是一件很是複雜的事。首先咱們須要理清有哪些資源建在這個VPC上,除去重建的步驟,理清脈絡就是一件很是頭痛的事。

Terraform 真正的威力在於【生成執行計劃】的步驟上 。 當前的雲端架構會被存在本地的 terraform.tfstate的文件裏。 當配置文件被修改的時候,它會馬上計算出當前的架構,與你指望達到的狀態之間的差別。並告訴你有哪些資源只是修改一下屬性便可,哪些則須要刪除重建。 等待你確認以後纔開始執行。

因而用戶就避免了繁瑣的」理清脈絡的過程「,能夠將工做重心放在開發工做上,而不是理清繁瑣的依賴關係。 經過 terraform apply 確認一下,等待執行完成便可。


Terraform是怎麼識別依賴關係的? 

事實上,除了直接寫,你還能夠經過"引用"的方式代表這個屬性的值,在一些場景下巧妙的引用會爲你省下不少時間,咱們以構建一臺雲主機爲例,爲了節省空間咱們省略了一些細節

resource "jdcloud_subnet" "my-subnet" {
    ... 
}
resource "jdcloud_network_security_group" "my-sg" {
    ... 
}

resource "jdcloud_instance" "my-vm" {

  ...
  image_id = "${var.ubuntu_image}"
  password = "${var.vm_password}"
  subnet_id = "${jdcloud_subnet.my-subnet.id}"
  security_group_ids = ["${jdcloud_network_security_group.my-sg.id}"]
  ...
}複製代碼
  • 咱們先是建立了一個名爲"my-subnet"的子網資源  +  "my-sg"的安全組資源
  • ${ jdcloud_subnet.my-subnet.id }  -  經過引用的方式說明這臺雲主機將會構建在名爲my-subnet的子網上。 類似的,這臺雲主機還會使用名爲 my-sg 的安全組

因而 terraform 便獲得了一組依賴關係 :  雲主機 my-vm 依賴 my-sg & my-subnet ,下次若是my-subnet 面臨刪除重建,terraform會提示你它會先重建構建在它之上的 my-vm

以此類推,子網:  my-subnet 可能也構建在另外一個VPC資源上,相互依賴的網絡就這樣被構建出來,若是你嘗試刪除VPC, terraform 會計算出全部同時也須要刪除的資源


成爲開發者是一件很難的事情嗎

大家Terraform支持XX資源嗎?

這個問題的答案是: 只要有SDK就是支持的,想要在 terraform 上管理一項新品類的資源,你只須要準備好SDK便可,接下來咱們以 VPC 爲例介紹如何引入一項新資源

1. 定義資源的屬性

Schema: map[string]*schema.Schema{

     "vpc_name": {                                                                                                                                                 
        Type:     schema.TypeString,
        Required: true,
     },

     "cidr_block": {
        Type:     schema.TypeString,
        Required: true,
        ForceNew: true,
     },

     "description": {
        Type:     schema.TypeString,
        Optional: true,
     },
},
複製代碼

  • 定義VPC資源的三種屬性: vpc_name / cidr_block / description 爲 string類型
  • 設定 vpc_name + cidr_block 爲必填項: Required = true
  • 設定 description 爲選填項 : Optional = true
  • 設定 cidr_block 爲不可修改字段,修改則致使刪除重建: ForceNew = true


2. 定義資源的增刪改查函數

func resourceVpcCreate(d *schema.ResourceData, m interface{}) error {

    config := m.(*JDCloudConfig)
    vpcName := d.Get("vpc_name").(string)
    req := apis.NewCreateVpcRequest(config.Region, vpcName)
    conn := client.NewVpcClient(config.Credential)

    if _, ok := d.GetOk("cidr_block"); ok {
        req.AddressPrefix = GetStringAddr(d, "cidr_block")
    }

    if _, ok := d.GetOk("description"); ok {
        req.Description = GetStringAddr(d, "description")
    }

    resp,err := conn.CreateVpc(req)    
    if err != nil {
        return e
    }

    return resourceVpcRead(d, m)
}複製代碼

以上是VPC的建立函數,每當terraform認爲須要建立VPC需求的時候,就會調用函數

  • 函數參數
    •  d 能夠理解爲用戶填寫的jdcloud.tf 裏面包含了咱們須要的配置
    • m 則是用戶身份信息等,用於建立客戶端
  • 第一步:  咱們須要從用戶填寫的 jdcloud.tf 中讀回建立 VPC 所須要的 vpc_name + cidr_block + description 信息
  • 第二步:  生成一個建立VPC的請求,並使用客戶端發送,若是返回的 error 不爲空則表明建立失敗,系統不會記錄下這筆資源,不然爲空,系統會在當前狀態裏記錄下這個資源,建立完成
  • 類似的咱們能夠作到讀,改,刪函數,只要咱們能拿出相對應的SDK來配合terraform對雲資源的修改便可


推薦閱讀

Terraform X 京東雲插件 - 更多資源的示例

Terraform X 京東雲插件 - Github , 關注咱們,一塊兒開發

Terraform X 京東雲插件 - 使用手冊

Terraform官網文檔,更詳細,介紹Terraform是怎麼工做的

相關文章
相關標籤/搜索