54
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Terraform0.12時代に、より汎用的なmoduleを作るためのtips3選

Last updated at Posted at 2019-08-03

cover.jpg

はじめに

こんにちは。Wano株式会社エンジニアのnariと申します。
7月からある新規のプロジェクトでterraform職人デビューしました。
絶賛IaCにハマり、tfファイルと格闘する毎日を過ごしております。

moduleといえば、Terraform module Registryは実装の参考にはなるけれど、moduleとしてusecaseが狭かったり、外部に依存したくなかったりで、結局ローカルにprivate moduleを作ることが多いと思います。

その際痛感したのが、
汎用的なmodule作るのって、難しい。。。

あまり凝りすぎて可読性が落ちたり使いづらくならない範囲で、用途の広いmoduleが欲しい。。
そこで自分がmoduleを作るときに、便利だなと思って使用しているtipsを3つ紹介したいと思います。

想定読者

TL;DR

  • 汎用的なmodule作りには
    • optionalなfield -> variableのdefault値 null
    • optionalなargument -> dynamic block+三項演算子
    • optionalなresource -> count+三項演算子

実行環境

terraform 0.12.0

汎用的なmoduleの特徴

  • requiredが少ない
  • optionalが多く、様々な用途に対応できる

汎用的moduleを作るためのtips3選

1.variableのdefault値でnullを使用し、optionalなfieldを設定

module example

main.tf
/* codebuild */
resource "aws_codebuild_project" "default" {
...
  source {
    type      = var.source_type
    location  = var.source_location
    buildspec = var.buildspec
  }
...
}
variable.tf
/* optional source_typeがs3の場合required*/
variable "source_location" {
  default = null
}

説明

  • valiableのdefault値でnullを使用することで、設定しない限りそのfieldは無いものとして扱われる
  • null値の導入は0.12.0から
  • ある条件下でのみ設定したいfieldに使用する(今回で言えばsource_type=s3)

2.dynamic blockと三項演算子を使用し、optionalなargumentを設定

module example

main.tf
/* ecs sercie */
resource "aws_ecs_service" "default" {
...
  dynamic load_balancer {
    //is_load_balancer_modeがfalseならこのargument設定されない
    for_each = var.has_load_balancer ? {dummy:"hoge"} : {}
    content {
      target_group_arn = var.target_group_arn
      container_name   = var.container_name
      container_port   = var.container_port
    }
  }
...
}
variable.tf
/* optional*/
variable "has_load_balancer" {
  description = "もしload_balancer argumentを設定したいなら、trueを入れる"
  default     = false
}

/* has_load_balancerがtrueなら requierd */
variable "target_group_arn" {
  default = null
}
variable "container_name" {
  default = null
}
variable "container_port" {
  default = null
}

説明

  • has_load_balancerのflagを設定し、dynamic blockと三項演算子を使用することで、load_balancerを設定する場合もしない場合も対応可能なecs sercviceのmoduleが作れる
  • 三項演算子とは? -> 三項演算子
  • dynamic blockとは? -> Expressions
  • dynamic blockの導入は0.12.0から
  • has_load_balancer=falseの場合は、空のmapを設定することで、argumentが設定されない
  • has_load_balancer=trueの場合はkey valueが1組のmapを設定することで、argumentが1つ設定される(コードが汚いのでなんとかならないかな、、要検討)

3.countと三項演算子を使用し、optionalなresourceを設定

module example

main.tf
resource "aws_iam_user_login_profile" "default" {
  count   = var.has_login_profile ? 1 : 0
  user    = aws_iam_user.default.name
  pgp_key = var.pgp_key
}
variable.tf
/*if you want to login as this user, required*/
variable "has_login_profile" {
  default = false
}

説明

  • 例えば、コンソールログインできるuserもできないuserも作れるmoduleにしたい、という場合resource丸々がoptionalとして扱いたくなる
  • そこで、has_login_profileのようなフラグを用意して、trueならcount=1でlogin_profileを生成する,falseならcount=0でlogin_profileを生成しないとしてやる

終わりに

0.12.0で追加された話としては、object型が便利だなぁとか色々あると思いますが、今日はこの辺で。
今回紹介したサンプルなど、awsのresource系のmoduleはこちらのリンクに掲載してますので、ご参考にしてください。
terraformerとしてスーパービギナーですので至らぬところたくさんあると思いますのでご指摘お待ちしております。
最近全然記事書けてなかったので、今日明日で溜まってたトピックでいっぱい記事書こうと思います

54
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?