今更ながらにTerraformのディレクトリ構成を考えることにした。

こんにちはjoeです。

今更ですが仕事でTerraformでECSを0から作る可能性が出てきたのでディレクト構成について考えてみました。

沢山世の中にterraformのディレクトリ構成は出てはいるのですがなんとなく自分で深く考えたこともなくどの手法がいいのかなど 自分の考えとしてまとめておきたいと思います。

※あくまで今回の内容は個人の中で考えたレベルでやっておりまして業務で使えるレベルなのかどうかというのには疑問を感じているのでこういうのもあるんだなというレベルで考えて頂けると嬉しいです。

対象者

Terraform初めて使っていてリソースの作成方法はわかったけどディレクトリの構成をどうしたらいいのかわからない。

Terraformのリファクタリングをしたいのでその選択肢の一つとして見たい

単純にどんなもんかと野次馬も歓迎です

今回の構成はこちらのリポジトリに置いてありますので参考になれば幸いです。

github.com

ディレクトリ構成は以下のようになっています

workspaces/
├── account (iam)
├── computing (ECS, RDS, Redis)
├── deployment-pipeline (CodeDeploy, CodePipeline)
├── modules
├── networking (VPC, ALB)
├── security (KMS, ACM)
└── storage (S3)

各リソースをそれぞれのディレクトリに対して配置しています。 workspaceに関して簡単に説明します。

Workspace

Terraformにはworkspaceという機能があります。workspace 同じTerraformのコードを異なるworkspace(環境)毎に使い分けることができる機能でこれによって環境毎のコードをワンソースで管理することもできます。

同じawsのアカウントではなく環境毎に異なるawsのアカウントによって管理していることもあるのでその際はtfvarsファイルを作成して異なる環境に対応できるようにするなどが必要になってきます。

今回は同じアカウントなこと、またTerraform Cloud への対応も行えるような形で対応できるようにしてworkspaceのパターンを採用することにしました。

業務の中ではTerraform Cloudを使用していますが環境毎にディレクトを切っていて管理しています。 参考までに以下のようなディレクトリ構成です。

workspace
├── dev
├── prod
├── stg

次からそれぞれのディレクトリについて説明していきたいと思います。

account

ここは基本的にはIAM関連のリソースの作成をしています。 リソースの作成に対してIAMロールを紐付けたい場合はこちらで作成してからそれぞれのリソースについてIAMロールを紐づけるようにするので新しいリソースの作成にはまずはこの accountのディレクトリを始点にして作成していきます。

computing

このディレクトリはcomputing系のリソース。今回だとECSを使用していたのでECS。 他にもEC2やLambdaなどのリソースもここに配置していこうかと思っています。

RDSやElasticCacheについても僕はここに置いています。 もう少し細かく分割しようと思ったのですが個人開発の範疇だったのでそこまで切ることをしないためです。

deployment-pipeline

このディレクトリは使う人、使わない人がいると思うのですがcodepipelineやcodedeployなどのAWS Codeシリーズをリソースを管理しています。 もしこの辺りを全てcircleciに任せていますなどあれば特にリソースの作成の必要はないかもしれないかなと思います。

networking

VPCなどを管理しています。 他にもALBを個人的には配置していてAWSのネットワークに関連するリソースはここに配置しています。(ALBはロードバランサーなのでここが適切なのか不明なのでどこにおくのがいいのか教えて欲しいレベル)

security

秘密情報を扱うようなリソース、KMSなどを作成するときはここを使用します。 他にもACMの作成やEC2のキーペアなどもここに配置していく想定です。

ここは一度作成するとなかなか変更する機会が少ないディレクトリになるかなと思います。

storage

s3などのstorageサービスはここになります。 ALBのログがアプリケーションの画像や動画の保存するS3バケットの作成もここでします。

modulesについて

modulesですが何度か使用する物についてはmoduleにしました。

state管理

state管理についてはbackendにs3を使用したremote stateでの管理をしています。 terraformではremote stateのs3を管理してないのと排他制御のためにDynamoDBを入れることを複数人開発で入れることを忘れないようにすることを注意してください。

参考

まとめ

今回はworkspaceを使用したディレクトリ構成を作りました。 Terraformには様々なパターンがありベストプラクティスも提唱されていますがまだこれがいいというパターンはないのでチームの事情や能力に合わせて変わっていく形になるかなと思っています。

今回この記事を書くにあたってADWAYSさんの記事がとても参考になりました。

Terraformのディレクトリ構成の模索 - Adwaysエンジニアブログ

追記

会社の人から指摘をもらって確かにと思ったので追記です。

moduleはworkspaceと同じ階層に置くのが望ましいという指摘を受けてその通りだなと思ったので以下のように修正しました

workspaces/
├── account (iam)
├── computing (ECS, RDS, Redis)
├── deployment-pipeline (CodeDeploy, CodePipeline)
├── networking (VPC, ALB)
├── security (KMS, ACM)
└── storage (S3)

modulesは同一階層にしたので今回はtreeからは除いていますがworkspacesと同じ階層に置いています。