terraformでインフラ管理をする際のベストプラクティスとして、実行単位を細かく分けよう
というのがあるのですが、安全に運用するためにはどのレベルで分割を行うべきかについて考えてみました。
terraformとは
AWSやGCPなどのインフラ等をコードで管理するツールです。
なぜ分割して管理する必要があるのか
Terraform Best Practices in 2017
に記載がありますが、1つのtfstateファイルで多くのリソースを管理してしまうと、問題があった場合の影響範囲が大きくなってしまいます。
また、変更したい場所以外で何かしらの差分がある場合、その差分の原因を突き止めるまで更新が出来ない等いろいろ不便な状況になります。(本番環境でなんかよくわからないけど差分が出ちゃった場合それを無理やり元に戻すなんてなかなか出来ないですよね。。)
だからといって、すごく細かくリソースを分割して管理すると運用上煩雑度が増すので、楽で安全に運用できる塩梅を探したいなと思っています。
案
変更頻度で分ける
AWSでシステムを運用する場合、よく変更するものしないものがあると思います。例えばVPCやルーティングテーブル等の設定は開発時には変更があるかもしれませんが、運用に入ってからはそんなに頻繁に変更することは少ないのではないでしょうか。逆にEC2やsecurity group等は、EC2のインスタンスサイズ変更、アクセス元IPアドレスの追加等、運用に入ってからもちょこちょこ変更がありそうです。
AWSのサービス単位で分ける
AWSのサービス毎にEC2ならEC2、S3ならS3をまとめて管理する案です。ただ、同一サービスの中にも重要度の高いもの、低いもの等があると思う(例えばEC2ならwebサーバと踏み台サーバでは何かあったときの影響度に差がある)ので、単純にAWSのサービス単位で分けるのはあまり安全な分割方法ではなさそうな気がします。
システム内の役割単位で分ける
システム内の役割単位で分けるのも一つの手かもしれません。商用のサービスを提供しているEC2、RDS、管理用のEC2(例えば踏み台サーバ)等に役割ごとに分けておくと、管理用EC2の設定を更新した際に仮に問題が起こってもサービス自体には影響が及ばない等メリットがありそうです。
まとめ
最終的にこれと言った答えは自分の中でも出てないですが、変更頻度やシステム内での役割を考慮しつつ分割していけば良いのかなと思っています。
個人的な案としてはこんな感じにするのが良いのかなと考えています。
- network
- ネットワーク系の設定VPC、subnet、NAT、routing等の設定を管理
- securitygroup
- セキュリティグループの管理
- iam
- IAMの管理
- s3
- S3回りの管理
- backend
- DB等のデータストア関連のリソースを管理
- webservers
- webサーバやALB等の管理
- opsservers
- 運用系のサーバの管理
terraform自体の変化とともに最適な構成は変わってくると思うので、今後も運用しながら適切な構成を探っていきたいなと思います。