はじめに
2016年、初版の『Infrastructure as Code』がリリースされ、クラウド技術の運用における新たな標準をぶち立てました。
公式サイトもここに置いておきます。 infrastructure-as-code.com
初版の2017年に日本語版がリリースされました。
それから4年後、待望の『Infrastructure as Code, 2nd Edition』が登場した。この新版は、サブタイトルを「Managing Servers in the Cloud」から「Dynamic Systems for the Cloud Age」へと変更し、クラウド技術の進化と共に変わるシステム管理のダイナミクスに焦点を当てている。さらに、360ページから427ページへと内容が拡張され、より包括的な情報と洞察が提供されている。残念ながら、『Infrastructure as Code, 2nd Edition』の日本語版は現在提供されていませんがこの本はクラウドインフラストラクチャの管理に関して重要な洞察と知識を提供しており、その内容は多くの専門家や技術者にとって非常に価値があります。
『Infrastructure as Code』の第二版では、かつて新しい概念として導入されたインフラストラクチャとしてのコードが、今や世界中の企業、銀行や伝統的な組織を含めてクラウドへの移行が進む中で、開発チームが大規模なインフラコードベースの構築において不可欠なものとなっています。この改訂版は、DevOpsチームによって開発された原則、実践、パターンを活用し、クラウド時代に適したインフラの管理方法を明らかにしています。システム管理者、インフラエンジニア、ソフトウェア開発者たちに、クラウドと自動化技術を用いて、容易に、安全に、迅速に、かつ責任を持って変更を加える方法を教えます。また、コードとして全てを定義し、小さく疎結合な部品を組み合わせてシステムを構築する技術も伝えます。ただし、日本語版のリリースがなされぬままに、次の第三版が出版される可能性があります。これはそういった悲しみの読書感想文でもあります。また、このブログはずっと。
次回の記事 syu-m-5151.hatenablog.com
目次
I. Foundations (基礎) 1. What Is Infrastructure As Code? (インフラストラクチャとしてのコードとは何か?) - インフラストラクチャをコードで管理する概念とその重要性について説明します。 2. Principles Of Cloud Age Infrastructure (クラウド時代のインフラストラクチャの原則) - クラウドインフラストラクチャ管理の基本原則を掘り下げます。 3. Infrastructure Platforms (インフラストラクチャプラットフォーム) - 現代のインフラストラクチャプラットフォームの種類と特徴について論じます。 4. Core Practice: Define Everything As Code (コアプラクティス:すべてをコードとして定義する) - インフラストラクチャ要素をコードとして定義する実践方法に焦点を当てます。 II. Working With Infrastructure Stacks (インフラストラクチャスタックとの作業) 5. Building Infrastructure Stacks As Code (インフラストラクチャスタックをコードとして構築する) - インフラストラクチャスタックをコードで構築するプロセスとテクニックを紹介します。 6. Building Environments With Stacks (スタックで環境を構築する) - スタックを使用して異なる環境を構築する方法を解説します。 7. Configuring Stack Instances (スタックインスタンスの設定) - 個々のスタックインスタンスを設定するための戦略とベストプラクティスを提供します。 8. Core Practice: Continuously Test And Deliver (コアプラクティス:継続的なテストと提供) - インフラストラクチャコードの継続的なテストと提供の重要性について論じます。 9. Testing Infrastructure Stacks (インフラストラクチャスタックのテスト) - インフラストラクチャスタックのテスト手法と戦略を紹介します。 III. Working With Servers And Other Application Runtime Platforms (サーバーおよびその他のアプリケーションランタイムプラットフォームとの作業) 10. Application Runtimes (アプリケーションランタイム) - アプリケーションの実行環境に関する概要と管理方法を提供します。 11. Building Servers As Code (サーバーをコードとして構築する) - コードを使用してサーバーを構築する方法について詳しく説明します。 12. Managing Changes To Servers (サーバーへの変更の管理) - サーバーに加えられる変更を効果的に管理する戦略を提供します。 13. Server Images As Code (サーバーイメージをコードとして) - サーバーイメージをコード化するアプローチとその利点について解説します。 14. Building Clusters As Code (クラスターをコードとして構築する) - クラスターを効率的にコードで構築する手法について紹介します。 IV. Designing Infrastructure (インフラストラクチャの設計) 15. Core Practice: Small, Simple Pieces (コアプラクティス:小さく、単純な部品) - 小さく単純な部品を使用してインフラストラクチャを設計する方法に焦点を当てます。 16. Building Stacks From Components (コンポーネントからスタックを構築する) - 個々のコンポーネントから効果的なスタックを構築するアプローチを提供します。 17. Using Stacks As Components (スタックをコンポーネントとして使用する) - スタックをコンポーネントとして活用するための戦略について説明します。 V. Delivering Infrastructure (インフラストラクチャの提供) 18. Organizing Infrastructure Code (インフラストラクチャコードの整理) - インフラストラクチャコードを整理し管理する方法について論じます。 19. Delivering Infrastructure Code (インフラストラクチャコードの提供) - インフラストラクチャコードを効果的に提供する戦略について解説します。 20. Team Workflows (チームワークフロー) - チームがインフラストラクチャコードを管理し作業するためのワークフローについて紹介します。 21. Safely Changing Infrastructure (インフラストラクチャの安全な変更) - インフラストラクチャを安全に変更するための実践的なアドバイスを提供します。
I. Foundations (基礎)
What Is Infrastructure As Code? (インフラストラクチャとしてのコードとは何か?)
この章は、現代のITインフラストラクチャの管理における根本的なシフトを示唆しています。クラウドとインフラストラクチャの自動化技術は、より迅速かつ信頼性の高い価値提供を可能にする一方で、管理するべきものの複雑さと多様性を増大させています。このジレンマは、組織がデジタル化するにつれて特に重要になってきています。「デジタル」という言葉は、ソフトウェアシステムが組織の活動に不可欠であることを意味します。これは私自身のソフトウェアエンジニアおよびSREとしての経験にも共鳴します。変更管理プロセスを厳格化することで混乱を防ごうとする試みは、しばしばクラウド技術の利点を損なうものです。
「クラウドと自動化技術を利用して、変更を容易に、安全に、迅速に、そして責任を持って行うことができる」というこの本の前提は、特に重要です。この利点は、自動化ツールやクラウドプラットフォームというツールそのものからではなく、これらの技術の使い方に依存しています。
印象的なのは、インフラストラクチャとしてのコード(IaC)が、ソフトウェア開発からの実践に基づいたインフラストラクチャの自動化へのアプローチであるという点です。これは、システムのプロビジョニングと変更およびその設定を一貫して、繰り返し可能なルーチンとして扱います。コードの変更を行い、それらの変更をシステムに自動的にテストし適用します。
この章はまた、クラウド時代のインフラストラクチャへのアプローチが、速度と品質の間の偽のジレンマを排除する方法を説明しています。速度を品質向上の手段として利用し、品質を高速なデリバリーの可能性として利用します。また、このような言及が出てくるのもソフトウェア開発のプラクティスに基づくインフラストラクチャ自動化のアプローチとして定着しているこの本ならではだなって思いました。
「クラウド時代のインフラストラクチャを管理するためには、クラウド時代のマインドセットが必要」というメッセージは、私の経験と完全に一致します。クラウド時代では、変更の速度を利用してリスクを減らし、品質を向上させる新しい考え方が求められます。このアプローチは、根本的なアプローチの変更と変更とリスクに対する新しい考え方を必要とします。
"A fundamental truth of the Cloud Age is: Stablity comes from making changes."(クラウド時代の基本的な真理は:変更から安定性が生まれる)は、インフラストラクチャの管理における直感に反すると思いますが2023年の現在ではとても納得することが出来ます。未パッチのシステムは安定しているのではなく、脆弱であり、発見した問題をすぐに修正できない場合、システムは安定していないという考え方です。
最後に、インフラストラクチャとしてのコードの3つのコアプラクティス:すべてをコードとして定義する、進行中のすべての作業を継続的にテストし提供する、そして、独立して変更できる小さくシンプルな部品を構築する、これらはインフラストラクチャの管理における新しい標準を示しています。似たようなプラクティスはソフトウェア開発でももちろん存在していてソフトウェア開発のプラクティスをインフラ管理に持ち込める強みのようなものを強く感じました。
この章を読んで、クラウド時代におけるインフラストラクチャ管理の新しい考え方とアプローチについての理解が深まりました。
2. Principles Of Cloud Age Infrastructure (クラウド時代のインフラストラクチャの原則)
この章は、クラウド時代のインフラストラクチャ設計と実装における基本原則を提示し、それらがどのように従来の「鉄の時代」のインフラストラクチャと異なるかを示しています。クラウド時代はコンピューティングリソースを物理的なハードウェアから切り離し、これらが仮想的な構成物として変更や破棄が可能になります。
「鉄の時代」とCloud Native を語っている書籍があり一章だけでも面白いの読んでほしいです。
原則: Assume Systems Are Unreliable (システムが信頼できないと仮定する)
クラウドスケールのインフラストラクチャでは、信頼性のあるハードウェアを使用しても障害は発生します。この原則は、根底のリソースが変化したときにも中断なくサービスを提供するための設計を必要とします。
重要性と実装の方法
この原則の重要性は、特にクラウド環境で顕著になります。クラウドでは、物理的なサーバーやネットワーク機器に依存しない仮想化されたリソースを使用します。これらのリソースは柔軟でスケーラブルですが、未知だったりコントロール外の障害の可能性も含まれています。したがって、システムの設計において、予期しないエラーに対処する機能を組み込むことが重要です。
障害を前提とした設計では、冗長性の構築、フォールトトレラントなアーキテクチャの採用、自動回復機構の組み込みなどが行われます。例えば、データの自動バックアップ、複数の地域にまたがるサービスのデプロイ、障害発生時にトラフィックを自動的に切り替えるロードバランシングなどがこれに該当します。
総合的なアプローチ
システムの信頼性を高めるためには、ハードウェアとソフトウェアの両方の側面を考慮した総合的なアプローチが必要です。これには、適切なハードウェアの選択、ログやメトリクスの取り扱い、ソフトウェアの品質保証、セキュリティ対策、そして継続的なメンテナンスとアップデートが含まれます。「システムが信頼できないと仮定する」という原則は、特にクラウドベースのインフラストラクチャにおいて重要です。この原則に従うことで、システムはより堅牢で回復力があり、最終的にはユーザーに対してより信頼性の高いサービスを提供することができます。このアプローチを採用することで、企業は技術的な障害によるリスクを最小限に抑え、ビジネスの継続性を確保することができるのです。
参考リンク
AWSの公式ドキュメント - AWS Well-Architected Framework
Google Cloudのドキュメント - Google Cloud Architecture Framework
- Google Cloudでの信頼性の高いシステム設計に関する包括的なガイドです。
『Site Reliability Engineering』
- GoogleのSREチームによって書かれたこの本は、大規模なシステムの信頼性を保つための実践的なアプローチを紹介しています。
『継続的デリバリー 信頼できるソフトウエアリリースのためのビルド・テスト・デプロイメントの自動化』
- 本書は、本番環境にデプロイされるソフトウェアの設計において考慮すべき点、特に継続的デリバリーをどのように実践するかに重点を置いています。
原則: Make Everything Reproducible (全てを再現可能にする)
システムの回復性を高める一つの方法は、その部品を容易かつ信頼性高く再構築できるようにすることです。これによりテスト環境を本番環境と一致させたり、負荷の高い時に需要に応じてインスタンスを追加することが容易になります。でも、実際には様々な理由から完全に一致させることは難しいので機能を制限したりコスト削減の為にkube-downscalerやInstance Schedulerなどを入れるようにしましょう。
実際の経験から、この原則を守るためのキーポイントは、構成管理とバージョン管理の徹底です。例えば、私が取り組んだプロジェクトでは、全てのサーバー設定や依存関係をコードで管理し、Gitなどのバージョン管理システムを使用しました。これにより、ある特定のバージョンのコードベースから環境を正確に再現できるようになります。また、自動化されたデプロイメントパイプラインを設置することで、一貫性のあるデプロイメントプロセスを確保しました。これは、予期しない問題が生じた場合に、迅速に対応できるようにするために重要です。
さらに、継続的インテグレーション(CI)を活用することも大切です。CIツールを使用することで、コードの変更が他の部分に悪影響を及ぼさないかどうかを常に確認できます。例えば、新しい機能を追加する際には、既存のシステムに影響がないかを自動テストで確認します。これにより、安定した本番環境を保ちながら迅速に開発を進めることができます。
最後に、ドキュメントの重要性を忘れてはなりません。システムの各部分がどのように機能し、どのように相互作用するかを明確に文書化することで、新しいメンバーやチーム外の人がシステムを理解しやすくなります。これにより、効率的なコラボレーションと問題解決が促進されます。
落とし穴: Snowflake Systems (特殊なシステムの罠)
スノーフレークシステムは再構築が困難なシステムのインスタンス、または本来似ているべき環境が理解できない方法で異なる環境を指します。これらのシステムはリスクを生み、管理するチームの時間を浪費します。特殊な設定やカスタムの依存関係が原因で、システムが一意的になりすぎることがあります。これは、将来のスケーラビリティやメンテナンス、アップグレードの際に問題を引き起こします。また、これらのシステムは新しいチームメンバーにとって理解しにくく、エラーの原因となる可能性が高まります。
原則: Create Disposable Things (廃棄可能なものを作る)
ダイナミックなインフラストラクチャに対処するためのシステムを構築することは重要ですが、システム自体がダイナミックであることも重要です。部品を柔軟に追加、削除、開始、停止、変更、移動できるようにすることが重要です。この原則の鍵は、自動化とスケーラビリティです。インフラストラクチャのコード化(Infrastructure as Code: IaC)を採用することで、システムの部品を簡単に作成し、廃棄することができます。また、コンテナ技術やサーバーレスアーキテクチャを利用することで、リソースを効率的に管理し、必要に応じて柔軟にスケールアップまたはスケールダウンできます。これにより、システムのメンテナンスやアップデートを簡単に行い、変更に迅速に対応できるようになります。
原則: Minimize Variation (変動を最小限にする)
システムが成長するにつれて、理解、変更、修正が難しくなります。多くの異なる種類の部品があるほど、作業は複雑になります。したがって、システムを管理しやすくするためには、異なる種類の部品を少なくすることが有用です。私の経験では、使用する技術やツールの数を最小限に抑えることで、システムの理解と管理が大幅に容易になりました。例えば、異なるプロジェクトやチーム間で同じ技術スタックやツールを使用することで、知識の共有が容易になり、新しいメンバーのトレーニングもスムーズに進みました。
Configuration Drift (設定の変動)
設定の変動は、かつて同一だったシステムが時間の経過とともに異なるようになることを指します。手動での変更や、一部のインスタンスにのみ自動化ツールを使用して行うアドホックな変更が原因で発生することがあります。この問題を解決するために、私は以前のプロジェクトで、全ての設定変更を中央で管理し、自動化ツールを用いて全インスタンスに一貫して適用する方法を採用しました。これにより、設定の一貫性が保たれ、予期しない問題の発生を防ぐことができました。
原則: Ensure That You Can Repeat Any Process (任意のプロセスを繰り返せるようにする)
再現性の原則に基づき、インフラストラクチャに対して行うあらゆる操作を繰り返せるようにする必要があります。スクリプトや設定管理ツールを使用して行動を繰り返す方が、手動で行うよりも簡単です。実際、私は自動化ツールやスクリプトを利用して、インフラストラクチャの構築、設定、デプロイを繰り返し可能にしました。これにより、新しい環境を迅速かつ一貫して構築でき、エラーの発生率を低減しました。また、これらのプロセスを文書化し、全チームメンバーが理解しやすい形で共有することで、作業の効率化と知識の共有を実現しました。
この章を読んで、クラウド時代のインフラストラクチャの原則が、伝統的なインフラストラクチャとどのように異なるか、そしてこれらの原則がどのようにクラウドプラットフォームの性質を最大限に活用する鍵となるかを理解しました。クラウドプラットフォームにおける変更の容易さを抵抗するのではなく、品質と信頼性を得るためにそれを利用することの重要性が強調されています。
3. Infrastructure Platforms (インフラストラクチャプラットフォーム)
この章では、クラウドインフラストラクチャの複雑さを解体し、その構成要素を理解しやすく分類しています。ここで提示されたモデルは、特定の技術やツールに依存することなく、概念やアプローチを議論するための文脈を作り出しています。これは非常に有益で、私たちが使用するテクノロジースタックやプラットフォームに関係なく、議論を関連性のあるものに保つために役立ちます。
インフラストラクチャシステムの部品 (The Parts of an Infrastructure System)
モダンなクラウドインフラストラクチャは、アプリケーション、アプリケーションランタイム、インフラストラクチャプラットフォームの3つの主要な層で構成されています。この分類は、インフラストラクチャの複雑な世界を整理し、各層がどのように組織全体の機能提供に寄与しているかを明確にします。
私の経験では、この3層モデルを理解し、適切に管理することが、効率的なシステム運用に不可欠です。特にアプリケーション層の性能と信頼性を保証するためには、アプリケーションランタイムとインフラストラクチャプラットフォームの調和が必要です。例えば、あるプロジェクトでは、コンテナ化されたアプリケーションをクラウド上で稼働させるために、Kubernetesを使用しました。これにより、アプリケーションランタイムの管理が容易になり、インフラストラクチャプラットフォームのリソースを効率的に利用することができました。また、これらの層を適切に管理することで、全体のシステムメンテナンスやアップグレードもスムーズに行えるようになりました。しかし、すべてのプロジェクトで当てはまるわけではないです。他のプロジェクトには他の要件や制約がありそれぞれに違う正解があると思います。
Figure 3-1. Layers of system elements より引用
"Applications and services provide capabilities to your organization and its users. Everything else in this model exists to enable this layer." (アプリケーションとサービスは、あなたの組織とそのユーザーに機能を提供します。このモデルの他のすべては、この層を可能にするために存在します。)はアプリケーション層が最終的な目標であり、アプリケーションランタイムとインフラストラクチャプラットフォームがその実現のための手段であることを示しています。これは、インフラストラクチャをただのサポート機能ではなく、組織の目的達成に不可欠な要素として位置づけている点で示唆に富んでいます。
インフラストラクチャプラットフォーム (Infrastructure Platforms)
このセクションは、インフラストラクチャとしてのコード実践において、ダイナミックなインフラストラクチャプラットフォームがいかに中心的な役割を担っているかを強調しています。クラウド技術は物理ハードウェアからの解放をもたらし、APIを通じた資源の管理を可能にしました。
一部をクラウドベースのインフラストラクチャプラットフォームを活用することで、システムの柔軟性と拡張性が大幅に向上しました。例えば、AWSのサービスを使用して、サーバーレスアーキテクチャを構築しました。これにより、物理的なハードウェアの制約から解放され、APIを介してリソースを効率的に管理することができるようになりました。このアプローチは、システムの拡張性を高めるだけでなく、運用コストの削減にも寄与することがあります。
"Virtualization decoupled systems from the hardware they ran on, and cloud added APIs to manage those virtualized resources." (仮想化はシステムを実行しているハードウェアから切り離し、クラウドはこれらの仮想化されたリソースを管理するAPIを追加しました。)は仮想化とクラウドがどのようにしてインフラストラクチャの運用を変革したかを端的に表しています。APIによる管理は、リソースの柔軟な扱いを可能にし、インフラストラクチャの変更や拡張を以前に比べて格段に簡単にしました。
インフラストラクチャリソース (Infrastructure Resources)
インフラストラクチャリソースは、現代のITシステムの根幹を成す重要な要素です。計算、ストレージ、ネットワークのこれら3つの基本リソースは、システムの性能や拡張性を決定づける要因となります。仮想マシン、コンテナインスタンス、データベースインスタンスなどの形態で利用されるこれらのリソースは、クラウドインフラストラクチャにおいて特に重要です。これらを適切に管理し、最適化することで、システムの効率性、柔軟性、信頼性を高めることができます。
"The line between a primitive and a composite resource is arbitrary, as is the line between a composite infrastructure resource and an application runtime service." (プリミティブリソースとコンポジットリソースの間、またコンポジットインフラストラクチャリソースとアプリケーションランタイムサービスの間の線引きは任意です。)は、インフラストラクチャリソースのカテゴライズが一定の基準に基づいているわけではなく、使用する文脈や目的に応じて変わることがあるという点を浮き彫りにしています。重要なのは、これらのリソースをどのようにして有効に組み合わせ、運用するかということであり、そのためには柔軟性が必要です。
全体を通して、この章はクラウドインフラストラクチャの理解を深め、それぞれの要素がどのように相互作用して機能するのかを示す貴重な洞察を提供しています。これらの知識は、インフラストラクチャとしてのコードを実践する上で、私たちが直面する課題への取り組み方や、利用可能な技術を選択する際の指針となります。
4. Core Practice: Define Everything As Code (コアプラクティス:すべてをコードとして定義する)
インフラストラクチャをコードとして定義する理由 (Why You Should Define Your Infrastructure as Code)
インフラエンジニアとして、インフラストラクチャをコードとして定義することの価値を語るのは、自明の理だと感じます。しかし、このアプローチは私たちの仕事を根本的に変えました。初めて自動化スクリプトを書いたとき、それは単なる作業の簡略化ではなく、再利用可能性、一貫性、透明性をもたらしました。これは組織のアジリティを高め、変更を迅速かつ確実に行う能力を提供する秘密の要因となります。これらの価値は、インフラストラクチャの変更が頻繁であろうとなかろうと、品質を向上させるために速度を活用することにあります。
コードとして定義できるもの (What You Can Define as Code)
過去にはプラットフォームのウェブベースのユーザーインターフェイスを使用したり、CLIを駆使してインフラストラクチャを手動でプロビジョニングすることが一般的でした。しかし、インフラストラクチャをコード化することで、過去のプロジェクトで見た、可視性の高い変更管理と迅速な展開の実現が可能となりました。これは、経験上も正しく技術的な変更が頻繁に発生する環境で特に重要です。
インフラストラクチャをコードとして定義することは、変更の自動化、文書化されたプロセス、およびエラーの減少に大きく貢献します。また、様々な現場ではIaCを通じて運用効率の向上、設定の一貫性、そしてセキュリティの強化を実現しています。IaCはリスクを軽減し、復元力の高いシステムを構築するための重要な手段となっています。さらに、チームの生産性の向上とスケールアップの際の柔軟性も、IaCの利用によって可能となっています。
インフラストラクチャコーディング言語 (Infrastructure Coding Languages)
スクリプト言語やDSLの使用から、一般的なプログラミング言語を使用したインフラストラクチャのツールへの移行は、運用の柔軟性を飛躍的に向上させました。以前に取り組んだプロジェクトでは、Terraformのような宣言的言語を使用してインフラストラクチャを定義し、それがもたらすシンプルさと明確さに驚かされました。このようなツールにより、インフラストラクチャのコードが従来のプログラミングコードと同様に「リアルなコード」として扱われるようになりました。
インフラストラクチャをコードとして定義するための実装原則 (Implementation Principles for Defining Infrastructure as Code)
宣言的と命令的コードを混在させることなく、インフラストラクチャコードを「リアルな」コードとして扱うことは、私たちのコードベースをクリーンに保つために不可欠です。参加した多くのプロジェクトでは、技術的負債を積極的に管理し、コードの品質を維持するために、コードレビュー、ペアプログラミング、自動テストなどの慣行を取り入れていました。これらは、インフラストラクチャコードの維持可能性を確保するために重要な実践です。
この章は、システムをコードとしてどのように定義するか、その方法とその背後にある理由を詳細に説明しています。インフラストラクチャを定義するための適切な言語を選択することは、効果的なインフラストラクチャを構築する上での重要な課題です。私の経験では、この課題はまだ解決されていませんが、本書を通じて、このテーマが再び現れ、私たち全員が最善の方法を発見するための考察を深めることを期待しています。
まとめ
『Infrastructure as Code』の初めの4章は、クラウド時代のインフラストラクチャ管理の新しいパラダイムを解き明かしています。第1章では、変更を効率的に、安全に、かつ迅速に行うためのインフラストラクチャとしてのコード(IaC)の基礎を設定します。第2章では、システムの不確実性を前提とし、再現性、廃棄可能性、変動の最小化といったクラウド時代のインフラストラクチャ設計の原則に深く潜ります。第3章は、インフラストラクチャプラットフォームとそのリソースがどのようにアプリケーションランタイム層の構築に寄与するかを具体的に説明し、計算、ストレージ、ネットワークという基本リソースを掘り下げます。そして第4章は、これらのリソースをシンプルで独立して変更可能な部品に分けることの重要性を強調し、チームワークフローとインフラストラクチャの安全な変更方法について具体的なガイダンスを提供します。これらの章は、IaCの実践における基本的な理解を構築し、次のセクション「II. Working With Infrastructure Stacks (インフラストラクチャスタックとの作業)」でのより具体的なスタック構築への取り組みへと説明してくれます。
Infrastructure as Code, 2nd Editionの読書感想文
- Infrastructure as Code, 2nd Edition の I. Foundations 読書感想文 - じゃあ、おうちで学べる
- Infrastructure as Code, 2nd Edition のII. Working With Infrastructure Stacks 読書感想文 - じゃあ、おうちで学べる
- Infrastructure as Code, 2nd Edition の III. Working With Servers And Other Application Runtime Platforms 読書感想文 - じゃあ、おうちで学べる
- Infrastructure as Code, 2nd Edition のIV. Designing Infrastructure 読書感想文 - じゃあ、おうちで学べる
- Infrastructure as Code, 2nd Edition のV. Delivering Infrastructure 読書感想文 - じゃあ、おうちで学べる