CLOVER🍀

That was when it all began.

Ubuntu Linux 18.04 LTSにTerraformをインストールする

ちょっとTerraformが気になっているので、試しにとインストールして触ってみることにしました。

Terraform by HashiCorp

Terraform?

そもそも、Terraformとはなんでしょう?

オフィシャルサイトによると、インフラをコードで定義し、リソースを作成したり変更したりできるもののようです。

Terraform by HashiCorp

HashiCorp Terraform enables you to safely and predictably create, change, and improve infrastructure. It is an open source tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.

また、リソースを定義し、作成することができる対象としてProviderがあり、いろいろな環境に対して利用できるようです。

Introduction - Terraform by HashiCorp

Use Cases - Terraform by HashiCorp

Providerの一覧は、こちらを参照。

Providers - Terraform by HashiCorp

AWSやMicrosoft Azure、GCPなど多くのProviderがあります。

とりあえず、実際に使って感覚を試してみましょう。

環境とインストール

今回の環境は、こちら。Ubuntu Linux 18.04 LTSです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.2 LTS
Release:    18.04
Codename:   bionic

ダウンロードページより、Terraformをダウンロードして展開します。

Download Terraform - Terraform by HashiCorp

今回のTerraformのバージョンは、0.11.13です。

$ wget https://releases.hashicorp.com/terraform/0.11.13/terraform_0.11.13_linux_amd64.zip
$ unzip terraform_0.11.13_linux_amd64.zip

シングルバイナリで実行可能なので、圧縮ファイルを展開して出てきた「terraform」ファイルを「/usr/local/bin」にでも
置いておきましょう。

$ sudo cp terraform /usr/local/bin

確認。

$ terraform -version
Terraform v0.11.13

これで、インストールは完了です。

リソースを作成してみる(プロビジョニングしてみる)

では、試しということでGetting Startedに添いつつ、リソースを作成(プロビジョニング)してみましょう。

Getting Started

…とは言ったものの、なにをリソース定義しましょうか?あんまり大掛かりなこともできないので、内容が小さそうな
MySQL Providerを使用しましょう。

Provider: MySQL - Terraform by HashiCorp

ページを見ていると、データベースを作成するようなProviderなようなので、MySQLを先にインストール。

$ wget https://dev.mysql.com/get/mysql-apt-config_0.8.12-1_all.deb
$ sudo dpkg -i mysql-apt-config_0.8.12-1_all.deb
$ sudo apt update
$ sudo apt install mysql-server

ユーザーも作成しておきます。

$ mysql -uroot -p
mysql> CREATE USER kazuhira@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.02 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO kazuhira@'%';
Query OK, 0 rows affected (0.03 sec)

Getting Startedに沿って、Terraformの設定ファイルを作成しましょう。

Build Infrastructure | Terraform - HashiCorp Learn

Terraformの設定ファイルの構文は、こちら。

Syntax - 0.11 Configuration Language - Terraform by HashiCorp

まずは、こんな感じで作成しました。

mysql.tf

provider "mysql" {
  endpoint = "localhost:3306"
  username = "kazuhira"
  password = "password"
}

resource "mysql_database" "app" {
  name = "my_database"
}

こちらでProviderとMySQLの接続情報を指定。

Providers - 0.11 Configuration Language - Terraform by HashiCorp

「provider」の後に続く文字列で、Providerを指定します。

provider "mysql" {
  endpoint = "localhost:3306"
  username = "kazuhira"
  password = "password"
}

リソース定義はこちら。

Resources - 0.11 Configuration Language - Terraform by HashiCorp

「resource」の後に、TYPE、NAMEが続きます。

resource "mysql_database" "app" {
  name = "my_database"
}

中には、作成するデータベースの名前を指定。

providerやresourceの中にどのような設定ができるかは、各Providerのリファレンスを参照することになります。

設定ファイルを作成したら、「terraform init」コマンドを実行します。

Build Infrastructure | Terraform - HashiCorp Learn

$ terraform init

すると、Providerのモジュールのダウンロードが行われるようです。

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "mysql" (1.5.1)...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.mysql: version = "~> 1.5"

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 plan」で、どのような処理が行われる予定かを確認することができます。

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + mysql_database.app
      id:                    <computed>
      default_character_set: "utf8"
      default_collation:     "utf8_general_ci"
      name:                  "my_database"


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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

指定していない設定は、デフォルト値が適用される感じで表示されていますね。

内容を見たところで、「terraform apply」で適用。

$ terraform apply

「実行してよいか?」と聞かれるので

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」と入力してEnter。

  Enter a value: yes

データベースが作成されます。

mysql_database.app: Creating...
  default_character_set: "" => "utf8"
  default_collation:     "" => "utf8_general_ci"
  name:                  "" => "my_database"
mysql_database.app: Creation complete after 0s (ID: my_database)

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

確認してみましょう。MySQLに接続。

$ mysql -ukazuhira -p

データベースの一覧を見ると、Terraformの設定ファイルで指定したデータベースが作成されています。

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_database        |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.02 sec)

「CREATE DATABASE」の定義も、一応確認しておきます。

mysql> SHOW CREATE DATABASE my_database;
+-------------+----------------------------------------------------------------------+
| Database    | Create Database                                                      |
+-------------+----------------------------------------------------------------------+
| my_database | CREATE DATABASE `my_database` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+-------------+----------------------------------------------------------------------+
1 row in set (0.01 sec)

リソースが作成されたことが確認できました、と。

リソースの定義を変更してみる

次に、作成したリソースを変更してみましょう。

Change Infrastructure | Terraform - HashiCorp Learn

Terraformの設定ファイルを修正して、デフォルトのcharacter setとcollationを変更してみます。

resource "mysql_database" "app" {
  name = "my_database"
  default_character_set = "utf8mb4"
  default_collation = "utf8mb4_ja_0900_as_cs_ks"
}

定義できる内容が少ないんですけど、ソースコードを確認してみると、確かにこれくらいみたいです…。

https://github.com/terraform-providers/terraform-provider-mysql/blob/v1.5.1/mysql/resource_database.go#L27-L45

プランを確認。

$ terraform plan
------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ mysql_database.app
      default_character_set: "utf8" => "utf8mb4"
      default_collation:     "utf8_general_ci" => "utf8mb4_ja_0900_as_cs_ks"


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

------------------------------------------------------------------------

「ひとつ変更がある」、と言われます。

適用します。

$ terraform apply

結果…。

mysql_database.app: Refreshing state... (ID: my_database)

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ mysql_database.app
      default_character_set: "utf8" => "utf8mb4"
      default_collation:     "utf8_general_ci" => "utf8mb4_ja_0900_as_cs_ks"


Plan: 0 to add, 1 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

mysql_database.app: Modifying... (ID: my_database)
  default_character_set: "utf8" => "utf8mb4"
  default_collation:     "utf8_general_ci" => "utf8mb4_ja_0900_as_cs_ks"
mysql_database.app: Modifications complete after 0s (ID: my_database)

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

「CREATE DATABASE」の定義を確認すると、内容が反映されていました。

mysql> SHOW CREATE DATABASE my_database;
+-------------+----------------------------------------------------------------------------------------------------------+
| Database    | Create Database                                                                                          |
+-------------+----------------------------------------------------------------------------------------------------------+
| my_database | CREATE DATABASE `my_database` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_ja_0900_as_cs_ks */ |
+-------------+----------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

データベースを再作成するのではなく、「ALTER」で反映するみたいです。

https://github.com/terraform-providers/terraform-provider-mysql/blob/v1.5.1/mysql/resource_database.go#L74

リソースを破棄する

では、最後に作成したリソースを破棄してみます。

Destroy Infrastructure | Terraform - HashiCorp Learn

「terraform destroy」で破棄を実行します。

$ terraform destroy

実行内容が表示されて

mysql_database.app: Refreshing state... (ID: my_database)

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  - mysql_database.app


Plan: 0 to add, 0 to change, 1 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」と入力してEnter。

  Enter a value: yes

破棄されたようです。

mysql_database.app: Destroying... (ID: my_database)
mysql_database.app: Destruction complete after 1s

Destroy complete! Resources: 1 destroyed.

確認。

mysql> SHOW DATABASES;                                                                                                                                                                +--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

確かに、リソース定義したデータベースが削除されました。

とりあえず、最初はこんなところでしょうか。