こんにちは。Kaneyasuです。
今回はIaCのリファクタリングの考え方の話をさせてください。
最近印象的なことがおきたので、そこから得た学びを共有したいと思います。
今回の記事はIaCをベースとしたお話しですが、考え方に主眼を置きたいので、あえて抽象化した言葉で書いていきます。
IaCをリファクタリングしたらデプロイに失敗するようになった!
以下のように、リソースAはリソースB・リソースCから参照されているとします。
リソースCは、リソースDから参照されているとします。
リソースAが要件とあわなくなったので、リソースAとは別のリソースAダッシュを作成。
リソースB・リソースCは、リソースAダッシュを参照するようにします。
この時、リファクタリングの結果起きることは、以下の3つです。
- リソースAの削除
- リソースAダッシュの作成
- リソースB・リソースCの参照先の変更
一見、問題なさそうですが、これをデプロイした時に、リソースB・リソースCが参照しているリソースAがなくなってしまう時間ができてしまうため、デプロイに失敗してしまうことがあります。
デプロイが失敗する理由とその対策
このデプロイが失敗する理由は、これがIaCであり、リソースに依存関係があるからです。
IaCには、リソースの作成・更新・削除が伴うため、全部を同時に変更することができません。
故に、依存関係を強く意識しないと、矛盾によるデプロイ失敗が起きてしまいます。
したがって、対策の一つは、依存関係をしっかりと定義することになります。
ただし、依存関係の定義の正しさは、新規デプロイと更新デプロイで異なる場合があるため、注意が必要です。
依存関係の定義で解決を図るのは、少々難易度が高いかもしれません。
もう一つの対策は、リファクタリングを小さく分割して行うことです。
例えば、上記の例であれば、以下のように2つのステップに分けて行います。
1ステップ目: リソースAダッシュの作成と、リソースB・リソースCの参照先の変更
2ステップ目: リソースAの削除
こちらの方法は、いったんリソースAがどこからも参照されない状態を作り出してから、リソースAの削除を行うため、デプロイの失敗を防ぐことができます。
注意点としては、単にコミットを分けるのではなく、1・2ステップがデプロイが分かれている必要があることです。
私としては、こちらの方法をオススメします。
焦らないリファクタリング
前項で、リファクタリングを小さく分割して行うことを提案しました。
このやり方は、一発でリファクタリングを完了させることができないため、プログラマーとしては、少々気持ち悪さを感じるかもしれません。
ここで大事なのは、システムはビジネスを継続させるためのものであることです。
したがって、プログラマー的な気持ち悪さよりも、デプロイが失敗しないことの方がはるかに重要です。
では、焦らない、ビジネスの継続を優先するには、どのような心構えをすればよいのでしょうか?
経験上言えることは、手離れをよくするとか、言い出しっぺが最後までやるとかをあまり意識しないことです。
自分は長い目でこのシステムに関わっていくのだ、他の人が途中までやったことを引き継いでいくこともあるのだ、と考えると、腰を据えてリファクタリングに取り組むことができるんじゃないかと思います。