Moduleとは
特定のリソースをModuleにすることで、設定の使い回しや共通化を図る事ができます
どんなときに使うか
同一の設定のEC2インスタンスを複数起動する場合、Moduleを使うと簡単です。
workspaceの機能を使わずに、環境ごとにディレクトリを分けている構成をした場合は、Moduleを使用することで複数環境で同一の設定をすることができます。
ここでやること
簡単に試すことを目的にProviderはDockerを指定します。ImageとContainerをModuleにし、異なる環境でImageのタグやコンテナ名、ホストポートへのマッピングを変更する例を上げたいと思います。
実行環境
ツール
Tool | Version |
---|---|
Terraform | 0.12.8 |
ディレクトリ構成
以下の構成で考えます。
$ tree .
.
├── env
│ ├── A
│ │ └── main.tf
│ └── B
│ └── main.tf
└── modules
├── image
│ ├── main.tf
│ ├── output.tf
│ └── variable.tf
└── container
├── main.tf
├── output.tf
└── variable.tf
Moduleの定義
以下のファイルをそれぞれ定義します。
ファイル | 説明 |
---|---|
main.tf | resourceを定義します |
output.tf | 他のModuleで利用する値を定義します |
variable.tf | Moduleへの入力するための変数を定義します |
Image
imageはnginxを指定しますが、imageのタグは変更できるようにvariableとして定義します。
container側でimageのIDを利用するためにoutputを定義しています。
resource "docker_image" "nginx" {
name = "nginx:${var.nginx_image_version}"
}
output "nginx_image_id" {
value = "${docker_image.nginx.latest}"
}
variable "nginx_image_version" {
default = "latest"
}
Container
containerではコンテナ名とホストのポートを指定できるようにvariableで定義します。
resource "docker_container" "nginx" {
image = "${var.nginx_image_id}"
name = "${var.nginx_container_name}"
ports {
internal = 80
external = "${var.nginx_host_port}"
}
}
variable "nginx_image_id" {}
variable "nginx_container_name" {}
variable "nginx_host_port" {
default = 8080
}
Terraformの実行
Moduleを作成した後は必ず $ terraform init
を実行します。
環境ごとに以下の設定になるようにmain.tfファイルを編集します。
環境 | nginxのimageタグ | コンテナ名 | ホストポート |
---|---|---|---|
A | 1.17 | env_A_container | 8081 |
B | 1.16 | env_B_container | 8082 |
provider "docker" {
}
module "image" {
source = "../../modules/image"
nginx_image_version = "1.17"
}
module "container" {
source = "../../modules/container"
nginx_image_id = "${module.image.nginx_image_id}"
nginx_container_name = "env_A_container"
nginx_host_port = "8081"
}
provider "docker" {
}
module "image" {
source = "../../modules/image"
nginx_image_version = "1.16"
}
module "container" {
source = "../../modules/container"
nginx_image_id = "${module.image.nginx_image_id}"
nginx_container_name = "env_B_container"
nginx_host_port = "8082"
}
env/A
とenv/B
のディレクトリで$ terraform apply
を実行すると、2つのimageとcontainerが作成されているはずです。
最後に
Moduleへのインプットをvariableでアウトプットをoutputを用いることがわかれば、難しい話ではないはずです。
今回のように環境をディレクトリで分けるときには有効な方法かと思います。