Featured image of post Terraform簡介

Terraform簡介

什麼?原來可以把所有的環境設定變成程式碼?

簡介

Terrform是一個基礎設施即程式碼(Infrastructure as Code, IaC)的工具。透過Terraform,我們可以將設定環境以及基礎設施的流程,轉變成以程式碼的方式來進行設定。Terraform的一個好處是可以對應多元的環境,並且可以同時管理雲端以及地端的環境。同時,得利於以程式碼進行設定的風格,我們將可以把基礎設施的設定進行版本控制以及自動化。

安裝

MacOS

在MacOS,我們可以透過Homebrew來進行安裝:

  1. hashicorp/tap加入Homebrew的套件清單
1
brew tap hashicorp/tap
  1. 更新Homebrew並進行安裝
1
brew install hashicorp/tap/terraform

若是遇到提示Command Line Tool版本過舊,可以使用以下的指令更新:

1
softwareupdate -i "Command Line Tools for Xcode-16.0"

成功安裝後,可以嘗試執行terraform -help。若是安裝成功,將會出現幫助訊息。

1
2
3
4
5
6
7
8
9
$ terraform -help
Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
##...

Linux

我們可以透過以下步驟在Linux系統中安裝Terraform:

  1. 安裝必要的工具
1
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common
  1. 安裝HashiCorp的GPG簽章
1
2
3
wget -O- https://apt.releases.hashicorp.com/gpg | \
gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null
  1. 驗證簽章
1
2
3
gpg --no-default-keyring \
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
--fingerprint
  1. 將官方資源加入apt資源清單
1
2
3
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
  1. 更新並安裝Terraform
1
sudo apt-get install terraform

成功安裝後,可以嘗試執行terraform -help。若是安裝成功,將會出現幫助訊息。

1
2
3
4
5
6
7
8
9
$ terraform -help
Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
##...

Terraform x Docker 用Terraform來管理Docker的映像檔以及容器

接下來將示範如何使用Terraform來管理Docker映像檔案以及容器。在這個示範中,我們將會:

  1. 建立專案
  2. 設定專案以及所需要的Provider
  3. 設定映像檔以及容器資源
  4. 初始化、建立規劃並套用設定

建立專案

首先,我們需要先建立一個資料夾,名為terraform_demo。我們將會把這個示範中所使用的設定檔案存放在這個資料夾之下。

1
mkdir terraform_demo

基礎設定以及Provider

接下來,我們需要宣告需要的Provider,用以管理環境。Provider在Terraform生態中,由不同的團隊或是公司所提供,可以協助我們控管不同資源的工具。

建立provider.tf檔案,並加入以下內容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {
  host = "unix:///var/run/docker.sock"
}

在上方的設定中,我們將kreuzwerker/docker列為必須的provider,並指令了版本。並且我們設定了一個名為dockerprovider物件,並且指定host參數。

新增映像檔清單

接下來,我們將新增映像檔到我們的設定之中。

建立images.tf檔案,並加入以下內容:

1
2
3
resource "docker_image" "ubuntu" {
  name = "ubuntu:latest"
}

設定容器

接下來,我們將使用我們上一步驟所宣告的映像檔案,建立一個新的容器。

建立containers.tf檔案,並加入以下內容:

1
2
3
4
5
6
7
resource "docker_container" "test" {
  image = docker_image.ubuntu.image_id
  name  = "test"
  
  tty = true
  command = ["/bin/bash"]
}

初始化專案

在完成了上述準備後,我們可以進行專案的初始化。使用以下指令進行初始化:

1
terraform init

查看資源規劃

在專案完成初始化後,我們將可以使用plan指令來查看哪一些資源將會被建立或是刪除。執行terraform plan指令,可以注意到Terraform提供了一個計劃內容。其計劃新增一個docker_container.test 資源,以及docker_image.ubuntu資源。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
$ terraform plan                                                                                                    ─╯

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # docker_container.test will be created
  + resource "docker_container" "test" {
      + attach                                      = false
      + bridge                                      = (known after apply)
      + command                                     = (known after apply)
      + container_logs                              = (known after apply)
      + container_read_refresh_timeout_milliseconds = 15000
      + entrypoint                                  = (known after apply)
      + env                                         = (known after apply)
      + exit_code                                   = (known after apply)
      + hostname                                    = (known after apply)
      + id                                          = (known after apply)
      + image                                       = (known after apply)
      + init                                        = (known after apply)
      + ipc_mode                                    = (known after apply)
      + log_driver                                  = (known after apply)
      + logs                                        = false
      + must_run                                    = true
      + name                                        = "test"
      + network_data                                = (known after apply)
      + read_only                                   = false
      + remove_volumes                              = true
      + restart                                     = "no"
      + rm                                          = false
      + runtime                                     = (known after apply)
      + security_opts                               = (known after apply)
      + shm_size                                    = (known after apply)
      + start                                       = true
      + stdin_open                                  = false
      + stop_signal                                 = (known after apply)
      + stop_timeout                                = (known after apply)
      + tty                                         = false
      + wait                                        = false
      + wait_timeout                                = 60

      + healthcheck (known after apply)

      + labels (known after apply)
    }

  # docker_image.ubuntu will be created
  + resource "docker_image" "ubuntu" {
      + id          = (known after apply)
      + image_id    = (known after apply)
      + name        = "ubuntu:latest"
      + repo_digest = (known after apply)
    }

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

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.

套用設定

當檢查完terraform plan所提出的計畫,並確認沒有問題之後,我們就可以使用terraform apply來將計劃付諸實行,套用至系統之中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
$ terraform apply                                                                                                   ─╯

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
  + create

Terraform will perform the following actions:

  # docker_container.test will be created
  + resource "docker_container" "test" {
      + attach                                      = false
      + bridge                                      = (known after apply)
      + command                                     = [
          + "/bin/bash",
        ]
      + container_logs                              = (known after apply)
      + container_read_refresh_timeout_milliseconds = 15000
      + entrypoint                                  = (known after apply)
      + env                                         = (known after apply)
      + exit_code                                   = (known after apply)
      + hostname                                    = (known after apply)
      + id                                          = (known after apply)
      + image                                       = "sha256:c22ec0081bf1bc159b97b27b55812319e99b710df960a16c2f2495dc7fc61c00"
      + init                                        = (known after apply)
      + ipc_mode                                    = (known after apply)
      + log_driver                                  = (known after apply)
      + logs                                        = false
      + must_run                                    = true
      + name                                        = "test"
      + network_data                                = (known after apply)
      + read_only                                   = false
      + remove_volumes                              = true
      + restart                                     = "no"
      + rm                                          = false
      + runtime                                     = (known after apply)
      + security_opts                               = (known after apply)
      + shm_size                                    = (known after apply)
      + start                                       = true
      + stdin_open                                  = false
      + stop_signal                                 = (known after apply)
      + stop_timeout                                = (known after apply)
      + tty                                         = true
      + wait                                        = false
      + wait_timeout                                = 60

      + healthcheck (known after apply)

      + labels (known after apply)
    }

  # docker_image.ubuntu will be created
  + resource "docker_image" "ubuntu" {
      + id          = (known after apply)
      + image_id    = (known after apply)
      + name        = "ubuntu:latest"
      + repo_digest = (known after apply)
    }

Plan: 2 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:

需要注意的是,terraform apply指令會要求你輸入yes來作為最終確認,否則將不會執行。

檢查結果

我們可以透過docker ps來檢查我們所設定的容器是否正常的被啟動了:

1
2
3
4
$ docker ps                                                                             

CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
8a2571ef83e7   c22ec0081bf1   "/bin/bash"   3 seconds ago   Up 3 seconds             test

可以注意到有一個名為test的容器被建立,這代表我們的示範正常的運作了。

結語

在這篇文章中,我們簡單介紹了如何安裝並使用Terraform來管理環境中的Docker映像檔以及容器。後續我們將會示範如何使用Terraform來建立多個模組,病控管多個不同的環境。

comments powered by Disqus
使用 Hugo 建立
主題 StackJimmy 設計