2023年8月12日土曜日

TerraformをAlmaLinuxにインストールして簡単な動作確認をしてみた

Terraformは、HashiCorp社にて開発された各種プラットフォームのITインフラの設定をIaC (Infrastructure as code)にて設定可能とするOSSツールとなる。

今回は、TerraformをAlmaLinuxにインストールし、簡単な動作確認を行う手順を記載する。

環境

環境は以下の通り。

  • OS : AlmaLinux 9.2
  • Terraform : v1.5.2

Terraformインストール手順

1. HashiCorpのレポジトリ追加

TerraformはHashicorpのリポジトリで公開されている。yum-config-managerコマンドを使って、以下の通りリポジトリの追加を行う。

# dnf install yum-utils -y
# yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

2. Terraformインストール

dnfを用いてTerraformをインストールする。gitperlの各種ライブラリが依存関係パッケージとして、大量にインストールされる。

# dnf install terraform
メタデータの期限切れの最終確認: 0:00:16 前の 2023年07月07日 21時12分38秒 に実施しました。
依存関係が解決しました。
====================================================================================================================================================
 パッケージ                                 アーキテクチャー           バージョン                               リポジトリー                  サイズ
====================================================================================================================================================
インストール:
 terraform                                  x86_64                     1.5.2-1                                  hashicorp                      21 M
依存関係のインストール:
 emacs-filesystem                           noarch                     1:27.2-8.el9_2.1                         appstream                     7.9 k
 git                                        x86_64                     2.39.3-1.el9_2                           appstream                      61 k
 git-core                                   x86_64                     2.39.3-1.el9_2                           appstream                     4.2 M
 git-core-doc                               noarch                     2.39.3-1.el9_2                           appstream                     2.6 M
 perl-AutoLoader                            noarch                     5.74-480.el9                             appstream                      21 k
 perl-B                                     x86_64                     1.80-480.el9                             appstream                     179 k
 perl-Carp                                  noarch                     1.50-460.el9                             appstream                      29 k
 perl-Class-Struct                          noarch                     0.66-480.el9                             appstream                      22 k

~(中略)~

 perl-subs                                  noarch                     1.03-480.el9                             appstream                      12 k
 perl-vars                                  noarch                     1.05-480.el9                             appstream                      13 k
弱い依存関係のインストール:
 perl-IO-Socket-SSL                         noarch                     2.073-1.el9                              appstream                     216 k
 perl-Mozilla-CA                            noarch                     20200520-6.el9                           appstream                      12 k
 perl-NDBM_File                             x86_64                     1.15-480.el9                             appstream                      22 k

トランザクションの概要
====================================================================================================================================================
インストール  68 パッケージ

ダウンロードサイズの合計: 34 M
インストール後のサイズ: 123 M
これでよろしいですか? [y/N]: y

~(以下略)~

インストール後、Terraformのバージョンを確認しておこう。

# terraform -v
Terraform v1.5.2
on linux_amd64
+ provider registry.terraform.io/kreuzwerker/docker v3.0.2

3. terraformコマンドのTab補完を使えるようにする

Terraformを使用する際は、その名の通りterraformコマンドを使用する。その際にTab補完を使えるよう、以下の通りコマンドを実行する。

# touch ~/.bashrc
# terraform -install-autocomplete
# source ~/.bashrc

実行後の~/.bashrcは以下の通り。最終行にTab補完用のコマンドが実行されるようになっている。

~/.bashrc

# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific environment
if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]
then
    PATH="$HOME/.local/bin:$HOME/bin:$PATH"
fi
export PATH

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

complete -C /usr/bin/terraform terraform   # <- ★追加される

これによって、例えばterraform a[TAB]とキーを入力すれば、terraform applyのコマンドが補完されるようになる。

# terraform apply   <- ★Tabで補完されるようになる

Terraform動作確認 (Docekrコンテナ作成)

ここからは、公式サイトで公開されている以下のチュートリアル通りに確認作業を進める。

前提として、事前にTerraformを導入したOSにDockerをインストールすること。Dockerのインストール手順は以下を参照いただきたい。

1. 作業用ディレクトリ作成

Terraformでは、作業用ディレクトリを作成し、そこに*.tfという拡張子を持つファイルにてTerraformのコードを記載する。Terraformコマンドはtfファイルのコードを解釈し、必要な一時ファイル等をディレクトリ内に作成し、各プラットフォームに対して操作を行う。

今回は以下の通りディレクトリを作成する。

# mkdir learn-terraform-docker-container
# cd learn-terraform-docker-container

2. tfファイルを作成

作成したディレクトリ内にmain.tfというファイルを作成し、以下の通り記述する。

main.tf

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0.1"
    }
  }
}

provider "docker" {}

resource "docker_image" "nginx" {
  name         = "nginx"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.image_id
  name  = "tutorial"

  ports {
    internal = 80
    external = 8000
  }
}

3. Terraform初期化 (terraform init)

Terraformを初期化するため、terraform initコマンドを実行する。このコマンドを実行すると、プロバイダと呼ばれるプラットフォームとのインタフェースとなるファイルが.terraformディレクトリにダウンロードされる。使用するプロバイダによってはかなり容量が大きいため注意しよう(例えばAWSのプロバイダであれば400MB程度)。

# terraform init

Initializing the backend...

Initializing provider plugins...
- Finding kreuzwerker/docker versions matching "~> 3.0.1"...
- Installing kreuzwerker/docker v3.0.2...
- Installed kreuzwerker/docker v3.0.2 (self-signed, key ID BD080C4571C6104C)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

なお、Terraformで使用可能なプロバイダは、以下URLから確認できる。

4. Terraform実行前確認 (terraform plan)

実行前に実行内容を確認するため、terraform planコマンドを実行する。

# 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.nginx will be created
  + resource "docker_container" "nginx" {
      + 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                                        = "tutorial"
      + 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

      + ports {
          + external = 8000
          + internal = 80
          + ip       = "0.0.0.0"
          + protocol = "tcp"
        }
    }

  # docker_image.nginx will be created
  + resource "docker_image" "nginx" {
      + id           = (known after apply)
      + image_id     = (known after apply)
      + keep_locally = false
      + name         = "nginx"
      + 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.

5. Terraform実行 (terraform apply)

Terraformの処理をするため、terraform applyコマンドを実行する。

# 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.nginx will be created
  + resource "docker_container" "nginx" {
      + 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                                        = "tutorial"
      + 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

      + ports {
          + external = 8000
          + internal = 80
          + ip       = "0.0.0.0"
          + protocol = "tcp"
        }
    }

  # docker_image.nginx will be created
  + resource "docker_image" "nginx" {
      + id           = (known after apply)
      + image_id     = (known after apply)
      + keep_locally = false
      + name         = "nginx"
      + 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: yes   <- ★yesを入力

docker_image.nginx: Creating...
docker_image.nginx: Creation complete after 9s [id=sha256:021283c8eb95be02b23db0de7f609d603553c6714785e7a673c6594a624ffbdanginx]
docker_container.nginx: Creating...
docker_container.nginx: Creation complete after 1s [id=c70291e91ade2fef0b1051a92a7a7e657d9b32c8bf63cafb7e5a3a4b7449bca2]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

6. 実行後確認

実行後にDockerコンテナとコンテナイメージの状況を確認すると、NGINXのコンテナイメージがダウンロードされ、コンテナとして起動していることがわかる。

# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                  NAMES
c70291e91ade   021283c8eb95   "/docker-entrypoint.…"   27 seconds ago   Up 26 seconds   0.0.0.0:8000->80/tcp   tutorial

# docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    021283c8eb95   4 days ago   187MB

NGINXコンテナは8000番ポートで接続できる。実際に接続すると、NGINXのウェルカムページが表示された。

7. Dockerコンテナ削除 (terraform destroy)

Terraformで作成したDockerコンテナを削除するため、terraform destroyコマンドを実行する。

# terraform destroy
docker_image.nginx: Refreshing state... [id=sha256:021283c8eb95be02b23db0de7f609d603553c6714785e7a673c6594a624ffbdanginx]
docker_container.nginx: Refreshing state... [id=c70291e91ade2fef0b1051a92a7a7e657d9b32c8bf63cafb7e5a3a4b7449bca2]

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

Terraform will perform the following actions:

  # docker_container.nginx will be destroyed
  - resource "docker_container" "nginx" {
      - attach                                      = false -> null
      - command                                     = [
          - "nginx",
          - "-g",
          - "daemon off;",
        ] -> null
      - container_read_refresh_timeout_milliseconds = 15000 -> null
      - cpu_shares                                  = 0 -> null
      - dns                                         = [] -> null
      - dns_opts                                    = [] -> null
      - dns_search                                  = [] -> null
      - entrypoint                                  = [
          - "/docker-entrypoint.sh",
        ] -> null
      - env                                         = [] -> null
      - group_add                                   = [] -> null
      - hostname                                    = "c70291e91ade" -> null
      - id                                          = "c70291e91ade2fef0b1051a92a7a7e657d9b32c8bf63cafb7e5a3a4b7449bca2" -> null
      - image                                       = "sha256:021283c8eb95be02b23db0de7f609d603553c6714785e7a673c6594a624ffbda" -> null
      - init                                        = false -> null
      - ipc_mode                                    = "private" -> null
      - log_driver                                  = "json-file" -> null
      - log_opts                                    = {} -> null
      - logs                                        = false -> null
      - max_retry_count                             = 0 -> null
      - memory                                      = 0 -> null
      - memory_swap                                 = 0 -> null
      - must_run                                    = true -> null
      - name                                        = "tutorial" -> null
      - network_data                                = [
          - {
              - gateway                   = "172.17.0.1"
              - global_ipv6_address       = ""
              - global_ipv6_prefix_length = 0
              - ip_address                = "172.17.0.2"
              - ip_prefix_length          = 16
              - ipv6_gateway              = ""
              - mac_address               = "02:42:ac:11:00:02"
              - network_name              = "bridge"
            },
        ] -> null
      - network_mode                                = "default" -> null
      - privileged                                  = false -> null
      - publish_all_ports                           = false -> null
      - read_only                                   = false -> null
      - remove_volumes                              = true -> null
      - restart                                     = "no" -> null
      - rm                                          = false -> null
      - runtime                                     = "runc" -> null
      - security_opts                               = [] -> null
      - shm_size                                    = 64 -> null
      - start                                       = true -> null
      - stdin_open                                  = false -> null
      - stop_signal                                 = "SIGQUIT" -> null
      - stop_timeout                                = 0 -> null
      - storage_opts                                = {} -> null
      - sysctls                                     = {} -> null
      - tmpfs                                       = {} -> null
      - tty                                         = false -> null
      - wait                                        = false -> null
      - wait_timeout                                = 60 -> null

      - ports {
          - external = 8000 -> null
          - internal = 80 -> null
          - ip       = "0.0.0.0" -> null
          - protocol = "tcp" -> null
        }
    }

  # docker_image.nginx will be destroyed
  - resource "docker_image" "nginx" {
      - id           = "sha256:021283c8eb95be02b23db0de7f609d603553c6714785e7a673c6594a624ffbdanginx" -> null
      - image_id     = "sha256:021283c8eb95be02b23db0de7f609d603553c6714785e7a673c6594a624ffbda" -> null
      - keep_locally = false -> null
      - name         = "nginx" -> null
      - repo_digest  = "nginx@sha256:08bc36ad52474e528cc1ea3426b5e3f4bad8a130318e3140d6cfe29c8892c7ef" -> null
    }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes   <- ★yesを入力

docker_container.nginx: Destroying... [id=c70291e91ade2fef0b1051a92a7a7e657d9b32c8bf63cafb7e5a3a4b7449bca2]
docker_container.nginx: Destruction complete after 0s
docker_image.nginx: Destroying... [id=sha256:021283c8eb95be02b23db0de7f609d603553c6714785e7a673c6594a624ffbdanginx]
docker_image.nginx: Destruction complete after 0s

Destroy complete! Resources: 2 destroyed.

削除後にDockerコンテナとコンテナイメージを確認すると、いずれも削除されていることが確認できる。

# docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

以上で、TerraformをAlmaLinuxにインストールし、簡単な動作確認を行う手順は完了となる。

参考

0 件のコメント:

コメントを投稿

人気の投稿