IaCがもたらすインフラ管理のパラダイムシフト

# はじめに
この記事は、もともと会社のブログ上で公開していたものですが、サイト閉鎖により見れなくなってしまったため再掲したものです。一年前のものですが、今後最新の情報も含めてアップデートしたいと思っています。

# 目次

- [1. 導入](#1-導入)
- [2. IaCとは](#2-iacとは)
- [3. IaCツールの種類](#3-iacツールの種類)
- [4. IaCから派生する発展的概念](#4-iacから派生する発展的概念)
  - [4.1 CI/CD](#41-cicd)
    - [4.1.1 自動テスト](#411-自動テスト)
    - [4.1.2 DevSecOps](#412-devsecops)
    - [4.1.3 ブランチ戦略](#413-ブランチ戦略)
  - [4.2 イミュータブルインフラインフラストラクチャ](#42-イミュータブルインフラインフラストラクチャ)
  - [4.3 GitOps](#43-gitops)
    - [4.3.1 Push型のパイプライン](#431-push型のパイプライン)
    - [4.3.2 Pull型のパイプライン](#432-pull型のパイプライン)
  - [4.4 プラットフォームエンジニアリング](#44-プラットフォームエンジニアリング)
  - [4.5 ソフトウェア化するインフラ](#45-ソフトウェア化するインフラ)
- [5. おわりに](#5-おわりに)
- [6. 関連製品・サービス](#5-関連製品・サービス)

## 1. 導入
近年、パブリッククラウド上でのシステム開発ではIaC（Infrastructure as Code）によるインフラ管理が主流となっています。IaCを実施するとインフラリソースのデプロイを自動化することが可能ですが、それだけに留まらずインフラの構成管理、CI/CD、インフラのモジュール化など様々なことが実現可能です。さらに、IaCはこれらの要素を起点として、イミュータブルインフラストラクチャ、GitOps、プラットフォームエンジニアリングなどのより発展的な上位概念へと包括されていきます。本記事では、IaCの概要からIaCの導入によって引き起こされる開発手法の変容、IaCの今後の発展などについてご紹介します。

## 2. IaCとは
IaC（Infrastructure as Code）とはインフラをコードとして実装し、デプロイを自動化する手法のことです。IaCではクラウドのマネジメントコンソール上でリソースを手動で作成する代わりに、コードで記述したものをCLIから一括デプロイすることが出来ます。これにより、手動での設定や変更が排除され、インフラの設定の再現性や信頼性の向上が実現可能となります。また、コードで実装することによりバージョン管理やコードレビュー、テスト自動化など、ソフトウェア開発で一般的に用いられる手法をインフラ管理にも適用することが可能になります。

## 3. IaCツールの種類
IaCツールには様々なものが存在しますが、大きく以下のような三種類に大別されます。

1. インフラの状態をどのように達成するかを手続き的に記述するツール（例: Ansible）
2. 望む最終的な状態を宣言的に記述するツール（例: Terraform, AWS CloudFormation）
3. 汎用的なプログラミング言語を用いてコードを記述するツール（例: Pulumi, AWS CDK）
    
広義のIaCではシェルスクリプト、Dockerfile、Kubernetesのマニフェストファイル、Helmチャート等も含める場合もあります。ただし、近年のパブリッククラウド上での開発という文脈においては、上記のようなクラウドプロバイダの提供するリソースを作成するAPIコールを代替するものをIaCと呼ぶケースが多いです。本記事では2と3のIaCツールについて扱います。

## 4. IaCから派生する発展的概念
IaCを実施する利点として、一般的には構築自動化による開発工数削減や人為的ミスの削減等が挙げられます。しかし、IaCのもたらす効用というものは、それだけに留まりません。

### 4.1 CI/CD
前述したように、IaCではCI/CD (Continuous Integration/Continuous Delivery) のようなソフトウェア開発手法をインフラにも適用可能となります。インフラをコードで定義すると、アプリケーションのコードと同様にGitリポジトリ上でソースコードを管理できるので、プルリクエストを使用したコードレビューや自動テスト、自動デプロイなどが実施可能となります。
CI/CDを実現する代表的なツールには以下のようなものがあります。

- Jenkins
- AWS Codeシリーズ
- Azure DevOps
- Circle CI
- GitHub Actions

![](https://storage.googleapis.com/zenn-user-upload/183691d6a385-20240126.png)
*出典　Microsoft Learn. "IaC および GitHub Actions を使用した Microsoft Azure へのデプロイ - Azure DevOps". 2023. https://learn.microsoft.com/ja-jp/devops/deliver/iac-github-actions . (参照 2024-02-02).*

#### 4.1.1 自動テスト
IaCの登場以前は、クラウド上に作成したリソースがパラメータシート等に記述した設定値に準拠しているか否かを確認するには、目視で確認するしか術がありませんでした。しかし、現在主流となっているTerraform等の宣言的なIaCツールでは記述したコードがリソースの望ましい状態を表現しており、コード内に記述した設定値の状態がそのままクラウド上に反映されます。そのため、手作業での人為的ミスによる設定値の誤り等は基本的に発生しません。従って、ソースコードに適切な設定値が記載してあるということが担保されている限り、IaCではリソースの設定誤り等の確認という意味での単体テストは不要です。

IaCにおける自動テストには様々なものがありますが、基本的にはソフトウェア開発と同様のLinterを使用したコードの静的解析、ビルド、スナップショットテスト、設定値に対するアサーションテストやdry-runなどが存在します。例えば、Terraformでは``terraform validate``コマンドでコードの静的解析を行い、``terraform plan``コマンドでdry-runを行うことができます。また、個別に確認したい設定値がある場合はテストコードを用意し、アサーションテストを実施することも可能です。ただし、全ての設定値に対してアサーションテストを実装するとテストコードが冗長になるうえ、IaCのコードと記述内容が重複してしまいます。そのため、システム全体への影響が大きく不可逆的な設定値（例：仮想ネットワークのCIDRブロック）やセキュリティ脆弱性を含有する可能性のある設定値（例：WAFのルール）等、確認が必要な値のみテストを実施し、開発時に頻繁に変更が加わるリソース（例：FaaSの設定やそれに紐づけるAPIのエンドポイントの設定）はテストを省略といったように、リソースの特性やライフサイクルに合わせてテスト対象となるパラメータを見極める必要があります。

また、インフラリソースの場合、データベースのように実環境にリソースを作成して挙動を確認するには時間がかかる場合があります。このような場合は、CIの処理にLocalStack等を導入してクラウドプロバイダへのAPIコールをモックすることで挙動を確認することも可能です。因みに、Pulumiではデフォルトでモック機能が備わっています。これらの機能を利用することで、実環境上でのリソースの作成を介さずに結合テストやE2Eテストを疑似的に実施することも可能です。

![](https://storage.googleapis.com/zenn-user-upload/8f54d949d2bf-20240126.png)
*出典　LocalStack | Docs. "Continuous Integration". 2024. https://docs.localstack.cloud/user-guide/ci/ . (参照 2024-02-02).*

#### 4.1.2 DevSecOps
IaCにおけるCIはセキュリティの観点からも有用です。IaCではインフラリソースをコード化することにより、記述されたコードからインフラの構成に含まれるセキュリティ脆弱性の有無を検出することが可能となります。手作業でインフラリソースを作成する際には、セキュリティグループのインバウンドルールで全てのポートからの通信を許可している、閉域網で使用するシステムにおいて負荷分散装置が誤って公開アクセス可能な状態になっているなどセキュリティ要件に反する設定を実施していてもその場では気づけない場合があります。しかし、インフラをコードとして記述すると、これらのセキュリティ脆弱性をCIプロセス内で機械的に解析して検出することが可能となります。こうすることで、セキュリティ脆弱性を含むリソースのデプロイを未然に防止することが可能となります。近年のDevSecOpsではソフトウェア開発の早期の段階からこのようなセキュリティ脆弱性を低減することが重要視されており、Shift-leftと呼ばれています。

IaCのセキュリティリスクを検出する代表的なツールとしては、Terraformのtfsec、AWS Cloud
Formationのcfn-nag, Snyk社が提供するSnyk IaCなどが存在します。このように、IaCではインフラ領域においてもソフトウェア開発と同様のShift-leftのような、DevSecOpsのプラクティスを適用可能となります。

#### 4.1.3 ブランチ戦略
複数人のチームでのソフトウェア開発では、機能ごとの実装の分担や環境の切り分けといった目的で、Gitブランチの分割・運用方法が一般的に考慮されます。これをブランチ戦略と呼び、代表的なものにはGit-Flow、GitHub-Flow、トランクベース開発といったものが存在します。IaCでも同様に、これらのブランチ戦略を適用して開発を実施することが可能です。例えば、対象のシステムに本番環境・ステージング環境・開発環境が存在する場合、それぞれの環境に対応するmainブランチ、stagingブランチ、developmentブランチを作成し、各ブランチと環境の内容を同期させることが可能です。さらに、ステージング環境でテストを行った後に本番環境にリソースをデプロイする場合、stagingブランチからmainブランチへプルリクエストを作成し、コードレビュー実施後に手動承認のプロセスを経てマージし、本番環境へ適用することが可能です。これらのブランチ戦略を導入すると、各ブランチが特定の環境の特定のバージョンのインフラを表現しているため、問題が発生した際のインフラの更新履歴の参照やロールバックも容易に行うことができます。また、環境ごとに個別のブランチでインフラの状態が管理されるため、特定の環境下で発生した障害の他環境への波及を未然に防止することができます。

![](https://storage.googleapis.com/zenn-user-upload/a9aa3e32be12-20240131.png)
*出典　nvie.com. "A successful Git branching model". 2010. https://nvie.com/posts/a-successful-git-branching-model/ . (参照 2024-02-02).*

#### 4.1.4 インフラのCI/CDの現状
インフラ領域のCI/CDは比較的新しい概念のため、IaC（やその他のコード含む）に対する適切なCI/CDパイプラインの作成手法は現段階では確立されていません。例えば、ソフトウェア開発におけるCIではテスト駆動開発のようなアプローチを使用しますが、IaCのコードに対してこのような開発手法を適用するケースは少ないです。しかし、近年では汎用プログラミング言語によるIaCツールも台頭してきていいるため、徐々にインフラ領域にもよりソフトウェア開発に近いCI処理が取り入れられていく可能性はあります。

また、リポジトリの分割単位やブランチ戦略についても未知の部分が多いと言えます。4.1.3節項では環境毎にリリースブランチを分割する例を示しましたが、これは環境間で間で差分が発生する要因にもなり得ます。ちなみに、モダンなアプリケーション開発手法の原則を紹介したTwelve-Factor Appでは単一のソースコードから複数の環境へデプロイすることが推奨されています。これに従うと、単一のブランチから複数環境にデプロイし、環境間の差分発生リスクを防止するといったブランチ運用も考えられます。しかし、いずれの場合にせよ既存のブランチ戦略はソフトウェア開発に対するものなので、現段階ではインフラリソースのデプロイに最適化された汎用的なブランチ戦略というものは提唱されていません。

![](https://storage.googleapis.com/zenn-user-upload/b67fd37b628e-20240208.png)
*出典　The Twelve-Factor App （日本語訳）. "I. コードベース". 2017. https://12factor.net/ja/codebase . (参照 2024-02-08).*

加えて、一口にIaCといってもツール毎に特性や実装方法が異なる上に、CI/CDツールもクラウドプロバイドの提供するものからOSSまで様々なものが存在します。特に、対象となるシステムの構築にクラウドプロバイダの提供するサービス以外にも外部のSaaSやOSSのツールを組み合わせる場合、パイプラインの本数が増大したり処理が複雑化するケースもあります。例えばCloudFormationでAWSリソースを、TerraformでDatadogやPagerdutyなどのSaaSのリソースを、Flux CDでKubernetesリソースをデプロイするような場合では各ツールに対応したソースコードの差分検出を条件分岐により行い、個別にCI処理を実施するためのロジックを実装する必要があります。

![](https://storage.googleapis.com/zenn-user-upload/67484d093b8c-20240208.png)
*出典　ZOZO TECH BLOG. "ついに最強のCI/CDが完成した 〜巨大リポジトリで各チームが独立して・安全に・高速にリリースする〜". 2023. https://techblog.zozo.com/entry/the-best-cicd. (参照 2024-02-08).*

このように、IaCに対してCI/CDを行う場合、ツール選定からリポジトリの構成及び適切なブランチ戦略の設計など、様々な観点で未だ議論の余地が大きいと言えます。

### 4.2 イミュータブルインフラインフラストラクチャ

DevOpsの分野では、イミュータブルインフラストラクチャ(Immutable Infrastructure)という概念が存在します。Immutableとは不変という意味で、一度デプロイされたインフラの状態を変更しないという原則に基づいています。イミュータブルインフラストラクチャでは、新しいバージョンのアプリケーションやシステムの変更が必要な場合には既存のインフラを直接変更するのではなく、新しいインフラを更新した設定値と共に作成します。

インフラリソースをマネジメントコンソールなどを通じて手作業で作成する場合、担当者によってはオペミスが発生したり、パラメータシートや手順書に記載された設定値と実環境の設定が乖離するケースがあります。また、特定の開発ルール等を設けず複数の作業者が手作業でリソースに変更を加える場合、重複するリソースの発生や削除し忘れたリソースの残存、必要なリソースの不足、命名規則に従わないリソースの発生などが起こりえます。このような状況下では実環境の状態を把握することが困難となり、インフラがブラックボックス化する可能性があります。また、実環境の状態が把握出来なければ障害発生時に原因の特定や問題の切り分けが非常に困難となる上、発生した障害の台帳管理などの運用工数もかさむこととなります。また、目視でパラメータシートと実環境の全てのリソースを把握するという運用も考えられますが、非効率的です。

このような問題に対し、IaCは有用となります。IaCは同じ操作を何度行っても結果が同じになる性質である冪等性があるため、一度設定した環境の再現や新規の環境構築がスムーズに行えます。環境ごとにテンプレートを作成すると、手作業による影響を排除し、環境毎に冪等性のあるリソースの作成を実施できます。これにより問題のある設定値を含む環境があったとしても、同様の環境を適切な設定値と共に新規に作成しなおすことが可能です。また、IaCはGit等でバージョン管理が可能であるため、問題が発生した際のロールバックや問題の発生源の特定も容易です。
実環境の状態の把握という意味でも、IaCではインフラストラクチャの設定がコードとして宣言的に記述されるため、環境の状態が一目で把握できます。手動の場合は誰がどのリソースを作成したかというのを把握するのは困難ですが、バージョン管理を行えば変更履歴が記録されるため、環境のブラックボックス化を防ぐことができます。また、Terraformのステートファイルに代表されるようにIaCツールには現状のインフラの状態を管理する機構が備わっているので、コード実行時にローカルの環境と実環境の差分を検出することも容易です。

さらに、IaCはCI/CDと組み合わせることで、手作業によるヒューマンエラーを防ぐことができます。CI/CDパイプライン経由でIaCのコードをデプロイする場合、基本的に手動での操作は行わず、ソースコードのリポジトリへのpushやプルリクエストを契機に自動でデプロイが実行されます。本番環境のリソース作成時にはマネジメントコンソール上からの手作業の操作を制限し、CDパイプラインからのデプロイのみに限定する、といった運用ルールをチームで設けておけば、人手を介さないインフラの実現が可能となります。ただし、IaCを使えば自動的にイミュータブルなインフラが実現できるわけではないので、自分達のチームで開発・運用ルールを設けたり、適切なCI/CDパイプラインの設計を行う必要があります。

### 4.3 GitOps
GitOpsとはGitリポジトリを信頼できる唯一の情報源として使用し、インフラとアプリケーションのコードの構成管理を行う手法です。主にKubernetesを使用したアプリケーション開発におけるCI/CDの文脈で使用されます。
Kubernetesでは必要なリソースをマニフェストファイルというYAML形式のファイルで定義することが出来ます。マニフェストファイルにはPod、Service、Ingress、ConfigMapなどのKubernetesクラスタの構築に必要なリソースの設定値が記述されます。このマニフェストファイルをGit上で管理することにより、これまで説明したようなIaCやCI/CDのプラクティスをKubernetesにも適用することが可能となります。GitOpsではPush型とPull型と呼ばれるパイプラインが存在します。

#### 4.3.1 Push型のパイプライン
KubernetesのリソースをCI/CDパイプライン経由でデプロイする場合、以下のようなパイプラインの処理が考えられます。
 
- アプリケーションのソースコードやDockerfileからDockerイメージをビルド
- ビルドしたDockerイメージをコンテナレジストリにpush
- ビルドしたイメージを基にマニフェストファイルを更新
- ``kubectl apply``コマンド実行によりマニフェストファイルに定義したリソースをデプロイ

このようなパイプラインはPush型のパイプラインと呼ばれ、比較的シンプルに実装することが可能です。しかし、Push型のパイプラインにはいくつか問題点があります。
まず、このパイプラインでは処理内容が順方向に伝播し、CIの処理の過程でデプロイまで行われるので、適用した環境の状態を元に戻すといったことは想定されていません。特に、アプリケーションとKubernetesのマニフェストファイルを同一のリポジトリで管理している場合、障害発生時にはアプリケーションのコードをrevertした後に再度CIの処理を実行する必要があり、ややロールバックの処理が冗長と言えます。また、マニフェストファイルへの軽微な変更でも同様にCIの処理を実施する必要があるるため、利便性に欠けます。加えて、コミット履歴にアプリケーションとマニフェストファイルのものが両方含まれるので、変更点の追跡も難しくなります。
その他、Push型のパイプラインではKubernetesリソースをデプロイする際にCIツールにクラスタの認証情報を渡す必要があります。そのため、CIツールにセキュリティ脆弱性が発生した場合、Kubernetesクラスタ内の情報漏洩が発生する危険性を孕んでいます。

#### 4.3.2 Pull型のパイプライン
Push型のパイプラインもGitOpsの定義自体には従っていますが、一般的にGitOpsという言葉が使用される場合、Pull型のパイプラインを示すケースが多いです。Pull型のパイプラインではPush型とは対照的に、CIとCDの処理でパイプラインが分割されます。Pull型のパイプラインを実現するツールで有名なものにはArgo CDやFlux CDなどがあます。

Pull型のパイプラインではGitOpsツールがクラスタの一部となり、現在のインフラの状態とGitリポジトリの状態を定期的に比較します。これらの状態に差分が発生した場合、GitOpsツールがGitHub等からWebhookを受け取り、Gitリポジトリ上に格納されたマニフェストファイルをクラスタにデプロイします。これにより、インフラスの状態とGitリポジトリの状態を常に同期させることが可能となります。Push型のパイプラインではリソースのデプロイは手続き的にコマンドを実行するだけでしたが、Pull型のパイプラインはより宣言的なアプローチと言えます。また、Pull型ではKubernetesクラスタ自体が自律的に自らの状態を更新するので、CIのパイプラインでは後続の処理を気にする必要がありません。ちなみに、Argo CDではImage Updaterを使用するとコンテナレジストリ内の変更が随時確認され、マニフェストファイル内のイメージタグの更新自体もArgo CD自身が実行してくれます。このように、Pull型のパイプラインではCIとCDの処理の担当が分かれるため、開発チームとSREやインフラチーム等で責任分界点を設けることも可能となります。加えて、Pull型のパイプラインではPush型のように認証情報をクラスタ外部に保存する必要が無いため、セキュリティの観点でも有用です。更に、障害時もrevertなどによりマニフェストファイルのコミット履歴のみを取り消せばロールバックが可能となります。

![](https://storage.googleapis.com/zenn-user-upload/92045ce66081-20240119.png)
*出典　Argo CD. "Declarative GitOps CD for Kubernetes". 2023. https://argo-cd.readthedocs.io/en/stable/. (参照 2024-02-08).*

### 4.4 プラットフォームエンジニアリング
近年、DevOpsの開発手法としてプラットフォームエンジニアリング(Platform Engineering)というものが注目されています。プラットフォームエンジニアリングは開発者の生産性を高めるプラットフォームを設計、構築、および運用し、開発者体験を向上することを主たる目的としています。2022年にGartner社のテクノロジーハイプサイクルに登場したことで急速に注目を浴びるようになりました。

![](https://storage.googleapis.com/zenn-user-upload/25498c3e781f-20240208.png)
*出典　Gartner . "3 Exciting New Trends in the Gartner Emerging Technologies Hype Cycle". 2022. https://www.gartner.com/en/articles/what-s-new-in-the-2022-gartner-hype-cycle-for-emerging-technologies. (参照 2024-02-08).*

クラウドの責任共有モデルは従来IaaS、PaaS、SaaSのような区分を用いて説明されてきました。しかし、近年ではDockerやKubernetesをはじめとしたコンテナ技術の普及、サーバレスなマネージドサービスの台頭、マイクロサービスの浸透、DevOpsやSREの普及によるエンジニアの担当範囲の拡大などが重なり、従来存在しなかったK8s-aaS(Managed K8s as a Servicee)、CaaS(Container-as-a-Service)、FaaS(Function-as-a-Service)等のより細分化されたサービス区分を含めた新たな責任共有モデルも提案されています。このように、現在パブリッククラウドにおける開発ではアプリケーションとインフラのレイヤは曖昧となっており、開発者が関わるレイヤも従来より増えるケースが多くなっています。

![](https://storage.googleapis.com/zenn-user-upload/3c5dbd3f1554-20240208.png)
*出典　CSA . "The Evolution of Cloud Computing and the Updated Shared Responsibility". 2021. https://cloudsecurityalliance.org/blog/2021/02/04/the-evolution-of-cloud-computing-and-the-updated-shared-responsibility
. (参照 2024-02-08).*

しかし、開発以外の部分で関与するレイヤが増すことは、開発者にとっては負荷が増大する要因になります。このような場合、開発者はアプリケーション開発に必要なプログラミング言語やフレームワーク等の知識に加え、パブリッククラウド（インフラ）の知識、Kubernetesをはじめとしたコンテナオーケストレーションの知識、IaCやCI/CDの知識、可観測性の知識など広範な知識やスキルセットが必要となってきます。DevOpsの文脈では開発者と運用者は互いに協力してアプリケーション開発に携わる必要があるためこの潮流は必然ですが、大規模なシステム構築において一人の開発者がアプリ～インフラまであらゆるレイヤに対してフルスタックに深い知見やスキルを有するというのは非現実的です。そのため、インフラチームやSREチームがある程度アプリケーションの実行基盤を担保する必要があります。近年では、このように様々な技術や開発手法の発展によって高度に複雑化するクラウド上での開発プラットフォームの形成のために、プラットフォームエンジニアリングが必要とされています。

プラットフォームエンジニアリングにおいて、プラットフォームチームはソフトウェア開発時に必要となるアプリケーション以外の要素を担当します。具体的には、アプリケーションのデプロイ先となるクラウド環境の構築と提供、ソースコードリポジトリの作成、CI/CD環境の構築、モニタリング周りの設定などを実施します。これらの作業はSREでも実施しますが、プラットフォームエンジニアリングでは開発者の負担を減らすことに主眼を置いているので、これらの設定を抽象化した上で開発者の扱いやすい形で提供します。具体的には、標準的に使用するインフラの構成をTerraformのコードをテンプレートとして自組織で用意し、開発者の扱いやすい形でTerraform as a Serviceとして提供する、開発に必要な社内向けのKubernetes環境をKubernetes as a Serviceとして提供するといった、実行基盤のセルフサービス化が挙げられます。
昨年10月にはMicrosoft社から、上記のような思想に基づいたRadiusというツールが発表されました。こちらはビルディングブロックのような形でアプリケーションの実装に必要なリソースを配備すると、開発者がそれ以下のレイヤを意識することなく、IaCのテンプレート（Helm/Terraform/Bicepなど）によってリソースが任意のクラウド上でデプロイされるようになっています。このように、現在のパブリッククラウドでの開発は、複雑化しがちなインフラ実行基盤を如何に抽象化して開発者の扱いやすい形で提供するかといったことに重きが置かれています。

![](https://storage.googleapis.com/zenn-user-upload/661c0a13336e-20240201.png)
*出典　Radius Docs . "Overview: Radius Applications". 2024. https://docs.radapp.io/guides/author-apps/application/overview/
. (参照 2024-02-08).*

### 4.5 ソフトウェア化するインフラ
近年のパブリッククラウド上での開発では、サーバレスのサービスも注目されるようになっています。特に中～小規模のアプリケーション開発ではコンテナさえ使用せず、AWS LambdaやAzure FunctionsのようなFaaSをのみを使用したフルサーバレスのアーキテクチャが採用される場合もあります。FaaSはFunction as a Serviceという名前の通りアプリケーションの関数単位でプログラムを実行するので、従来のようなインフラのパフォーマンスチューニング等の設定は極めて矮小化されています。さらに、FaaSではアプリケーションのコード（関数）自体がサービスの設定値と見なされるので、アプリケーションのコードの変更とインフラのライフサイクルが一致することとなります。こうなると、アプリとインフラの境はもはや存在しないと言っても過言ではありません。

上記のようなアプリケーションを扱う場合、汎用プログラミング言語でIaCのコードを記述するPulumiやAWS CDKが有用となります。フルサーバレスなアーキテクチャの場合、アプリケーションのコードとIaCのコードを同一のリポジトリ内で管理するケースもあります。このような場合、PulumiやAWS CDKを使用するとアプリケーションのフロントエンド/バックエンド～インフラで使用する言語を統一するといったことも実現可能となるため、開発時のコンテキストスイッチや認知負荷を下げることが可能です。加えて、AWS CDKではリポジトリ内に存在するLambdaのコードやDockerイメージなどをバンドルする機能も備わっているため、このようなサーバレスなアプリケーションでの開発に適していると言えます。

その他、PulumiやAWS CDKではプログラミング言語の恩恵を十分に享受することが可能です。
従来のIaCツールではコードを単純なJSONやYAML、TerraformのHCLに代表されるドメイン固有言語で記述していましたが、これらのツールではPythonやTypeScriptのような一般的なアプリケーション開発で使用されるプログラミング言語を使用できるので、開発者にとっては学習コストも低く扱いやすいです。中でもTypeScriptのような静的型付け言語では変数の型を指定することが可能なので、パラメータに数値や文字列、オブジェクトなど多様な値が代入されるIaCの実装において効力を発揮します。例として、Terraformでは変数の型チェックは``terraform plan``コマンド実行時に行われますが、TypeScriptの型補完を使えば不適切な設定値をコマンドを実行せずともIDE上で検出することが可能です。
また、PulumiやAWS CDKではインフラリソースをオブジェクト指向言語のクラスを利用して抽象化することが出来ます。そのため、自組織で頻繁に使用するインフラの構成や付随するリソースを一つのクラスに集約すれば、開発者がインフラをソフトウェアのモジュールやライブラリとして扱うことが可能となります。Pulumi RegistryやAWS CDKのConstruct Hubでは、様々なユースケースで必要なインフラのリソースを抽象化したライブラリ群が配布されています。このようなプラットフォーム上では、インフラはJavaScriptのnpmやPythonのpipのようなライブラリの一つとして配布されるようになります。こうすれば、インフラの細かいパフォーマンスチューニング等の知識がない開発者でも、既存のライブラリから開発に必要なリソースをデプロイ可能となります。

プラットフォームエンジニアリングでは開発者が出来るだけインフラのレイヤに関わらないように他のチームが実行基盤を構築するイメージですが、汎用プログラミング言語でIaCを実施する場合、開発者がアプリケーションのレイヤからインフラにアプローチすることが可能となります。どちらのアプローチが今後主流になるかは分かりませんが、汎用プログラミング言語でのIaCの記述というのは大きな可能性を秘めています。

## 5. おわりに
IaCは様々な可能性を秘めていますが、銀の弾丸ではありません。やみくもに実装しようとするとかえって時間がかかり、手作業でリソースを作成する方が早いケースもあります。IaCを実施する際は開発工数、チーム編成、ツール選定、技術選定、開発・運用ルールなど様々な点を考慮する必要があります。自組織の成熟度に合わせた目標設定を行い、IaCを活用していきましょう。