Terraformerを使い既存システムのコード化を行う
はじめに
medibaの野崎です。
バックエンドエンジニアとしてバックエンドアプリケーションやインフラストラクチャーの運用を行っています。 また,兼務でテクノロジーセンターにてTechLeadチームにも所属しています。
昨年よりau Webポータルの運用チームに担当となりました。 au Webポータルの運用チームは、複数のシステムを運用しています。
大半のシステムが初期開発から数年経過しインフラストラクチャー(AWSリソース)を手動で変更するような業務となっており、後述するような課題が多く見受けられました。
本記事では、その改善のために行った既存システムのインフラストラクチャーのコード化 - Infrastructure as Code(IaC)を進めたプロセスを紹介したいと思います。
インフラストラクチャーを手動で変更する場合の課題
所属するチームではこれまで以下のような業務の流れになっておりインフラストラクチャー(AWSリソース)を手動で変更していました。
※弊社ではバックエンドエンジニアとインフラエンジニアにロールが分かれています。
- 変更内容をバックエンドエンジニアが作成し、インフラエンジニアに変更依頼を行う
- その変更内容を元にインフラエンジニアがAWSマネージメントコンソールを介して変更作業を行う
このような業務の大きな課題として以下のような点が挙がっていました。
- AWSリソースの管理がインフラエンジニアに属人的にとなる
- バックエンドエンジニアからの変更依頼が多い際には、変更作業にリードタイムが発生する
- 変更履歴が残らず、組織変更に柔軟に対応できない
こういった課題の解決のため、 まず既存システムのインフラストラクチャーのコード化 - Infrastructure as Code(IaC) を検討しました。
バックエンドエンジニアもコードを介して、AWSリソースの変更管理を行って貰うためです。
どのように既存システムリソースをインフラコード化するか
弊社では新規開発時にInfrastructure as Code(IaC)ツールとしてTerraformを利用することが多いため、Terraform利用を前提にしました。
既存のリソースをTerraformのコード化するには、terraform importコマンドを使うことになります。 しかし、このコマンドはAWSのリソースを1点ずつ指定する必要があります。
参考: https://www.terraform.io/docs/cli/import/index.html
今回の対象システムのリソース数は数100あり、この方法でコード化するのは現実的ではありませんでした。
そこで今回はTerraformerというツールを使い、既存システムのTeraformコードの生成を行いました。 以下では、その実施手順を記載します。
参考: https://github.com/GoogleCloudPlatform/terraformer
Terraformerは、既存のシステムからTerraformコードとそのstateファイル(tfstate)を生成するCLIツールです。
Terrformerによる既存システムのコード化の実施
今回のシステムは以下のような前提として記載していきます。
- システムの環境は、開発環境(dev環境)と商用環境(prd環境)に分かれている
- 各環境ごとに、AWSアカウントが1つずつある
- 東京リージョンを利用している
- ローカルPCとして、macOSを使う
1. コード化対象のシステムの確認
TerraformerのREADME.mdにAWSに対応しているサービスが記載されています。これらから対象システムのうちコード化したいサービスについてリージョンごとにリスト化しておきます。
(例: 東京リージョンにてacm,alb,ec2_instanceなど) また、AWSのグローバルサービスについても同様にリスト化しておきます。 (例: iam,route53,wafなど)
2. Terrformerコマンド実行し、コードを生成する
以下のツールをローカルPCにインストールします
- tfenv
- Terraformのバージョンを管理するツール
- https://github.com/tfutils/tfenv
- 利用したバージョン: 2.0.0
- Terraformer
- 既存システムからTerraformのコードとstateファイルを生成するツール * https://github.com/GoogleCloudPlatform/terraformer
- 利用したバージョン: 0.8.11
次に適当なディレクトリを作成し、以下のファイルを作成します。
init.tf
.terraform-version
ファイルには以下のように記載します。
$ echo 'provider "aws" {}' > init.tf
$ echo '0.11.14' > .terraform-version
次にterraformer importコマンドでコードの生成を行います。
このコマンドのフラグはいくつかありますが、今回はシステムに合わせて以下のようにしました。
- フラグregionsは、生成対象のサービスのリージョンを指定する。
- 今回は東京リージョンとグローバルサービスにそれぞれ分けて指定する。
- フラグresourcesには、「1. コード化対象のシステムの確認」で確認したサービスをリージョンごとに記載する。
- フラグpath-patternは、生成するコードの配置ディレクトリを指定する。
※tfenvにて0.11.14としている理由
TerraformerのAWSプロバイダーの生成するコードが0.11(HCL1)系のものになるためです。 README.md などを見ると_0.13対応などの記述もありましたが、コードを確認したり実際にコマンドを実行しましたが、現在のところ0.11系でしか生成出来ないようでした。
#対象が東京リージョンにあるサービス
$ terraformer import aws \
--resources=acm,alb,ec2_instance,eip,elasticache,igw,nat,nacl,rds,route_table,s3,sg,sns,sqs,subnet,waf_regional,vpc,vpc_peering \
--path-pattern aws-service/dev/ap-northeast-1 \
--regions=ap-northeast-1
#対象がグローバルサービス
$ terraformer import aws \
--resources=cloudfront,route53,waf,iam \
--path-pattern aws-service/dev/global/ \
--regions=global
このコマンドを実行すると、以下のようにtfファイルとtfstateファイルが生成されます。
※スクリーンショットでは、フォルダを閉じていますが_globalディレクトリの配下にもtfファイルとtfstateファイルが作成されています。
3. コードの修正とapply
生成したコードをチーム開発で使えるようにコードの修正をいくつか行いました。以下に今回実施したことを簡単にリストします。 これらは開発チームの状況や対象システムによって異なるため、参考までに留めてください。
- Teraformのバージョンアップ
- 前述したように、生成したコードは0.11のものとして作成されています
- 運用するバージョンに合わせて、Terraformのterraform 0.12upgradeコマンド等を使い、コード修正を行います
- 管理不要なAWSリソースをTeraform管理外とする
- 例えば、defaultのvpcなどは運用上管理が不要なので、この時点で管理外としておきます
- tfstateをローカルからS3に移動
最後に生成・修正したコードを元に実際の環境にterraform applyを実行します。 一見差分が出ないように思われますが、今回実行した場合いくつか差分が出ました。
一例として、Route53があります。providerにてcommentのdefault値がManaged by Terraformとなっているため、これ以外の文字列が実リソースに設定されていれば、差分となります。
このような差分は1点ずつ確認しながら、コードの修正(差分をignore_changesに設定する)またはapplyを行い、 最終的にコードとの差分を無くします。
チーム開発を始める
ここまでで既存システムをコード管理下に置くことが出来ました。 今回はさらにバックエンドエンジニアを対象に Terraformの使い方やAWSリソースそのものについて勉強会などを行い、IaCでの開発に必要な知識を理解して貰いました。 その上で簡単な変更作業を切り出しながら、Infrastructure as Code(IaC)での開発に慣れて貰っています。
最後に
弊社のようなシステムの安定性と変更容易性を高いレベルで両立しなければいけない組織では、Infrastructure as Code(IaC)は非常に大切なプロセスだと考えています。
今回の取り組みは改善の第一歩であり、 継続的に今回のプロセスを維持・改善しつつ、組織的にもスキルの向上を高めていけるように、今後も取り組みを続けていきたいと考えています。
medibaでは、システムを深く理解し関わる組織の理解も鑑みながら、よりよいサービス運用をともに検討していただけるようなエンジニアのご応募をお待ちしています。
以上になります。
