Terraform で Docker 設定する人とかいるんかいな・・・

# Terraform で Docker 設定する人とかいるんかいな・・・

[Terraform](https://www.terraform.io/) では、Docker も設定できます。
が、しかし、使う人いるんですかね？？？
ちょっと疑問に思いながらも、試してみました。

## 前提条件

- docker が入ってる ubuntu サーバ（ centos や debian でも・・・）
- terraform 拾っておいてください

## とりあえずドキュメント通りにやってみる

ドキュメントだと `ubuntu` がサンプルになってますけど、ここは `nginx` でやってみます。

```docker.tf
# Configure the Docker provider
provider "docker" {
  host = "tcp://127.0.0.1:2376/"
}

# Create a container
resource "docker_container" "nginx" {
  image = "${docker_image.nginx.latest}"
  name  = "nginx"
}

resource "docker_image" "nginx" {
  name = "nginx:latest"
}
```

とりあえず、実行してみましょう。

```
> ./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.


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

Error: Error running plan: 1 error(s) occurred:

* provider.docker: Error pinging Docker server: Cannot connect to the Docker daemon at tcp://127.0.0.1:2376/. Is the docker daemon running?
```

おや？ダメですね。`docker` に `tcp` でつなぎに行こうとして失敗してますね。
確か、`sock` で立ち上がっているはず・・・

```
> ss|grep docker
u_str  ESTAB      0      0      /var/run/docker.sock 34261443              * 34262024
u_str  ESTAB      0      0      /var/run/docker.sock 34262033              * 34258932
u_str  ESTAB      0      0      /var/run/docker.sock 34262037              * 34258934
u_str  ESTAB      0      0      /var/run/docker.sock 34262043              * 34258937
u_str  ESTAB      0      0      /var/run/docker.sock 34262053              * 34258942
u_str  ESTAB      0      0      /var/run/docker.sock 34262041              * 34258936
u_str  ESTAB      0      0      /var/run/docker.sock 34262039              * 34258935
u_str  ESTAB      0      0      /var/run/docker.sock 34262035              * 34258933
u_str  ESTAB      0      0      /var/run/docker.sock 34262055              * 34258943
u_str  ESTAB      0      0      /var/run/docker.sock 34261446              * 34258927
u_str  ESTAB      0      0      /var/run/docker.sock 34262025              * 34258926
u_str  ESTAB      0      0      /var/run/docker.sock 34261450              * 34261449
u_str  ESTAB      0      0      /var/run/docker.sock 34258928              * 34261453
u_str  ESTAB      0      0      /var/run/docker.sock 34262029              * 34261452
u_str  ESTAB      0      0      /var/run/docker.sock 34268741              * 34269380
u_str  ESTAB      0      0      /var/run/docker.sock 34262027              * 34261448
u_str  ESTAB      0      0      /var/run/docker.sock 34268743              * 34269381
u_str  ESTAB      0      0      /var/run/docker.sock 34262057              * 34258944
u_str  ESTAB      0      0      /var/run/docker.sock 34261441              * 34262022
u_str  ESTAB      0      0      /var/run/docker.sock 34258924              * 34261445
u_str  ESTAB      0      0      /var/run/docker.sock 34258922              * 34262023
u_str  ESTAB      0      0      /var/run/docker.sock 34262049              * 34258940
u_str  ESTAB      0      0      /var/run/docker.sock 34262051              * 34258941
u_str  ESTAB      0      0      /var/run/docker.sock 34262047              * 34258939
u_str  ESTAB      0      0      /var/run/docker.sock 34262031              * 34261454
u_str  ESTAB      0      0      /var/run/docker.sock 34258930              * 34261455
u_str  ESTAB      0      0      /var/run/docker.sock 34262045              * 34258938
```

なので、どうしましょうかね。

`host - (Required) This is the address to the Docker host. If this is blank, the DOCKER_HOST environment variable will also be read.`

ソケットに接続できるように設定してやる必要がありそうですね。

```docker.tf
# Configure the Docker provider
provider "docker" {
  host = "unix:///var/run/docker.sock"
}

# Create a container
resource "docker_container" "nginx" {
  image = "${docker_image.nginx.latest}"
  name  = "nginx"
}

resource "docker_image" "nginx" {
  name = "nginx:latest"
}
```

行ってみましょう。

```
> ./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:

  + docker_container.nginx
      id:               <computed>
      attach:           "false"
      bridge:           <computed>
      container_logs:   <computed>
      exit_code:        <computed>
      gateway:          <computed>
      image:            "${docker_image.nginx.latest}"
      ip_address:       <computed>
      ip_prefix_length: <computed>
      log_driver:       "json-file"
      logs:             "false"
      must_run:         "true"
      name:             "nginx"
      network_data.#:   <computed>
      ports.#:          "1"
      ports.0.external: "80"
      ports.0.internal: "80"
      ports.0.ip:       "0.0.0.0"
      ports.0.protocol: "tcp"
      restart:          "no"
      rm:               "false"
      start:            "true"

  + docker_image.nginx
      id:               <computed>
      latest:           <computed>
      name:             "nginx:latest"


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

行けそうな感じですね。
ちなみに、`host` 行を削除してもいけたので、デフォルトは `sock` ぽいですね。
では、実際に `apply` していきます。

```
> ./terraform apply

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:

  + docker_container.nginx
      id:               <computed>
      attach:           "false"
      bridge:           <computed>
      container_logs:   <computed>
      exit_code:        <computed>
      gateway:          <computed>
      image:            "${docker_image.nginx.latest}"
      ip_address:       <computed>
      ip_prefix_length: <computed>
      log_driver:       "json-file"
      logs:             "false"
      must_run:         "true"
      name:             "nginx"
      network_data.#:   <computed>
      ports.#:          "1"
      ports.0.external: "80"
      ports.0.internal: "80"
      ports.0.ip:       "0.0.0.0"
      ports.0.protocol: "tcp"
      restart:          "no"
      rm:               "false"
      start:            "true"

  + docker_image.nginx
      id:               <computed>
      latest:           <computed>
      name:             "nginx:latest"


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` しちゃいましょう。

```
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

docker_image.nginx: Creating...
  latest: "" => "<computed>"
  name:   "" => "nginx:latest"
docker_image.nginx: Creation complete after 8s (ID: sha256:568c4670fa800978e08e4a51132b995a...ae83ca133ef5546d092b864acfnginx:latest)
docker_container.nginx: Creating...
  attach:           "" => "false"
  bridge:           "" => "<computed>"
  container_logs:   "" => "<computed>"
  exit_code:        "" => "<computed>"
  gateway:          "" => "<computed>"
  image:            "" => "sha256:568c4670fa800978e08e4a51132b995a54f8d5ae83ca133ef5546d092b864acf"
  ip_address:       "" => "<computed>"
  ip_prefix_length: "" => "<computed>"
  log_driver:       "" => "json-file"
  logs:             "" => "false"
  must_run:         "" => "true"
  name:             "" => "nginx"
  network_data.#:   "" => "<computed>"
  ports.#:          "" => "1"
  ports.0.external: "" => "80"
  ports.0.internal: "" => "80"
  ports.0.ip:       "" => "0.0.0.0"
  ports.0.protocol: "" => "tcp"
  restart:          "" => "no"
  rm:               "" => "false"
  start:            "" => "true"
docker_container.nginx: Creation complete after 1s (ID: 8348aaa0299dc933358f07b6638705fb32dc92658d28b7ec26ac3aaa4313c668)

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

イメージをプルしてくるので、少し時間がかかるかもしれません。
なんか、できたようですね。

```
> curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

あまりよくないですけど、`nginx` のデフォルトページを見ることができました。

## まとめ

使う人がどれくらいいるのかな？とは思いますが、さくっと `docker` にサーバを立ち上げることができました。
いや、`docker run` すりゃいいじゃんとか言ったら身も蓋もないですけどね・・・