- 渡邉光
- 約 6,800 文字
- 3,400 View
目次
はじめに
Technology Inovation Group(TIG)所属の筋肉エンジニアの渡邉です。
春の入門連載2023 8日目を担当します。
普段はクラウドインフラを中心に業務を行なっていますが、インフラリソースを管理するにあたってはIaC(主にTerraform)を使用しています。春の入門ということで、改めてIaCのメリット・デメリットについて整理してみました。また、PulumiというIaCツールに入門してみたので、皆さんと一緒にPulumiについて理解していきたいと思います。
IaC(Infrastructure as Code)とは
IaC (Infrastructure as Code)とは、ネットワーク、サーバ、データベースなどのインフラリソースをコードによって管理しプロビジョニングできることを言います。
クラウドを利用している場合、マネジメントコンソールからボタンポチポチでリソースを作成・更新・削除できます。手動で操作する場合、手順書を用意し手順書に沿ってマネジメントコンソールを操作すると思いますが、手順書を確認していてもオペミスによって意図せずリソースを更新・削除してしまう可能性やマネジメントコンソールは定期的にアップデートされるため、手順書が古くなってしまい意味を成さなくなってくる時もあると思います。
IaCを利用する場合、インフラリソースのあるべき姿をコードで定義・管理するためインフラリソースの変更前にレビューを挟むことができるので、意図せずリソースを作成・更新・削除してしまう可能性を少なくできます。
IaCで有名なツールとしては以下があります。
- Ansible(主にサーバ内のミドルウェアなどを管理する構成管理ツール)
- Terraform(各クラウドのリソースを管理する構成管理ツール)
- CloudFormation(AWSのリソースを管理する構成管理ツール)
IaCのメリット
既存コードの使い回し・各環境への迅速なプロビジョニング
インフラリソースの構成をコードで管理できるため、一度コードを作成してしまえば同じインフラ構成を作成したい場合、既存のコードを使いまわして構築できます。また、terraformであればworkspaceという機能を利用することで開発環境・検証環境・本番環境と各環境を同じコードで作成できます。例えば、咄嗟に性能環境が欲しいとなった場合でも迅速に環境を用意できます。
オペレーションミスの防止
IaCではコードに基づいてプログラムがインフラリソースを作成・更新・削除するため、手作業に比べるとオペレーションミスを減らせることができます。主に同じ作業を複数回する場合であったり、各環境に対して同じ作業をする場合などは手作業だとミスが起こりやすいので、IaCを用いる場合はミスを減らせると思います。
また、コードで管理されているためコードの実行前にレビューを挟むことができるため、品質を担保した状態を保つことができます。
DevOpsツールとの相性がよい
コード管理されていることによって、Githubなどのリポジトリサービスでバージョン管理できます。CI/CDとも相性が良いので、CI機能を利用してインフラリソースの命名規則をチェックしたり、linterを使用して整形したりなど、たくさんのDevOpsツールを利用して開発・運用効率を上げることが可能になります。
IaCのデメリット
IaCツールごとの言語/ルールが異なるためキャッチアップが必要
IaCツールはTerraformやAnsibleなどがありますが、TerraformはHCL(HashiCorp Configuration Language)という独自言語でインフラリソースの状態をコード化する宣言型のツールとなり、Ansibleはplaybookと呼ばれるファイルにYAMLで構成手順を記述する手続き型ツールになります。各ツールごとのルールや記載方法などをキャッチアップする学習コストがかかります。
コードと実態で差分が発生するリスク
IaCのコードによって管理されているインフラリソースに対して、例えば、手作業で変更を加えてしまった場合はコードとの差分が発生します。この差分によって、コードを使用してインフラリソースを更新しようとした際に、エラーが発生し、インフラが更新できなくなる可能性があったり、どちらが正しい構成なのかわからなくなってしまったりします。
簡単なインフラリソースの変更であれば、コードから変更するよりもコンソール画面から行ったほうが速い場合があるので、そういう場合にこの事象は発生しやすいと思います。
Pulumiとは
Pulumiとは、OSSのIaCツールの1つであり、Terraformは独自のHCL言語でコードを記述しなければなりません。一方、Pulumiの場合、アプリケーション開発者がよく使用する言語(Go/Java/Python/Typescript/C#/Yaml)などでコードを記述できるため、普段アプリケーションコード書いているエンジニアでも学習コストが低く、使い慣れた言語でインフラリソースをループ処理で作成したりできます。AWS/GCP/Azureなど各クラウドプロバイダーやKubernetesやServerlessにも幅広く対応しています。また、TerraformやCloudFormationからPulumiに変換することも可能なため、Pulumiへの移行も可能です。
Pulumiは無料で利用できますが、複数人での利用や、企業単位、ミッションクリティカルなシステムを扱う方向けに有償プランもあり、追加機能や充実したサポートを利用できます。
詳しくは公式ドキュメントを参照ください。
Pulumiは以下の構成をとります。詳しくは公式ドキュメントを参照ください。
- Project:Programや他ファイルを含むディレクトリ
- Program:インフラリソースのあるべき姿を定義したもの
- Resource:インフラリソースを構成するオブジェクト。オブジェクトのプロパティ(設定値)に関しては、Inputs/OutPutsによりの別のオブジェクトで利用することが可能
- Stack:Programをデプロイした後のインスタンス。同一のProgramから開発環境/検証環境など、用途に応じて複数の環境用にインスタンスを作成が可能
とにかく、触ってみないと理解できないので、さっそくさわってみたいとおもいます。
Pulumiを使用してGoogle Cloudのリソースを作ってみる
公式チュートリアルに沿って進めていきたいと思います。
Pulumiのインストール
Pulumiを利用するため、ローカルのWSL2にPulumiをインストールします。
curl -fsSL https://get.pulumi.com | sh |
言語ランタイムのインストール
Pulumiでは、Goを利用しようと思うのでGoをインストールします。
こちらは公式ドキュメントを参照ください。
go version |
GCP初期設定
ローカルにGoogle Cloud SDKはインストールされている前提で進めます。
PulumiはGoogle Cloud リソースとやり取りするためにデフォルトのアプリケーション資格情報を必要とするため、gcloud auth application-default loginコマンドを実行して資格情報を取得します。
gcloud auth application-default login |
表示されたURLをブラウザに入力すると、「Googleログイン画面」に遷移します。
「許可」をクリックします。
表示された認証コードをコピーします。
コピーした認証情報を入力し、「Enter」を押します。
Enter authorization code: xxxxxxxxxxxx |
環境変数を介して GCPのデフォルトプロジェクトを設定します。
export GOOGLE_PROJECT=xxxxxxxx |
Pulumiプロジェクトの作成
Pulumiを利用するためPulumiプロジェクトを作成します。
mkdir pulumi && cd pulumi |
アクセストークンの入力を求められました。https://app.pulumi.com/account/tokensにアクセスしてPulumi Cloudを初期設定します。
上記のURLへアクセスするとPulumiのSign In画面へ遷移します。
まだ、アカウントを作成していないのでCreate an accoutをクリックします。
アカウントを作成するため、今回はE-Mailを利用してアカウントを作成しようと思います。
- Username
- Password
を入力しCreate Accountをクリックします。
Personal access tokensの作成を求められるので、Create Tokenをクリックします。
descriptionに任意の値を入力します。
アクセストークンが生成されるので、メモしておきます。
先ほどのCLI画面に戻り、生成したアクセストークンを入力します。
するとWelcome to Pulumi!と表示されます。
pulumi new gcp-go |
Pulumiのプロジェクト名とプロジェクトの説明を求められるので、任意の値を入力していきます。
project name: (pulum) gcp-test |
次に、スタック名を尋ねられます。devと入力します。
Please enter your desired stack name. |
最後に、Google Cloud プロジェクトの場合、Google Cloud プロジェクトを選択するよう求められます。Google Cloud プロジェクト ID を入力します。
gcp:project: The Google Cloud project to deploy into: xxxxxxxx |
上記の設定が完了すると、作業ディレクトリに以下のファイルが生成されます。
tree |
main.goの見ていきましょう。
このPulumiのプログラムは…
- USリージョンにGCSバケットを作成
- GCSバケット名をExportする
内容になっています。
package main |
リソースの作成
上記の内容でPulumiを実行してGoogle Cloudのリソースを作成します。
pulumi up |
上記のコマンドを実行すると、Goのプログラムを評価し、実行するリソースの更新を決定します。変更の概要を示すプレビューが表示されます。
Previewing update (dev) |
detailsを選択すると、変更内容の詳細な差分が表示されます。
Do you want to perform this update? details |
yesを選択するとGoogle Cloud に新しいストレージ バケットが作成されます。
Do you want to perform this update? yes |
Google Cloudのコンソール画面からCloud Storageを確認すると、バケットが作成されていることが確認できました。
スタックのアウトプットを確認したい場合は、以下のコマンドを実行すると確認できます。
pulumi stack output bucketName |
また、自身のPulumi Cloudのアカウントを確認しに行くと以下のように、Web上でもリソースの状態を確認できます。
リソースの変更
GCSバケットを作成できたので、バケットにオブジェクトを追加してみます。
作業ディレクトリにindex.htmlを追加します。
<html> |
main.goにオブジェクトを追加するコードコメントアウト部分:Add index.html Objectを追加します。
package main |
main.goの修正が完了したので、変更分をデプロイしていきましょう。
再度pulumi upを実行します。
pulumi up |
yesを入力します。
Do you want to perform this update? yes |
更新作業が完了したので、gsutilコマンドでオブジェクトのアップロードを確認します。
gsutil ls $(pulumi stack output bucketName) |
オブジェクトがアップロードできていることが確認できました。
index.html がバケットにあるので、main.goを変更して、バケットが index.html を静的 Web サイトとして機能するように設定します。
変更内容は以下になります。
- websiteバケットにプロパティを設定します。
- Google Cloud Storage の推奨事項に合わせて、バケットに対する均一なバケットレベルのアクセスをtrueに設定します。
- バケットのコンテンツをインターネット経由でアクセスできるようにします。
- オブジェクトのコンテンツタイプ
text/htmlに変更して、HTMLとして提供されるようにします。 - バケットのエンドポイントURLをエクスポートします。
コメントアウト://Settings for publishing content to the Internetが修正部分になります。
package main |
main.goの設定が完了しましたので、pulumi upを実行しyesを選択しデプロイします。
pulumi up |
デプロイが完了しましたので、curlコマンドを実行し、バケットエンドポイントへアクセスします。
curl $(pulumi stack output bucketEndpoint) |
オブジェクトを取得できました。
Chromeでアクセスするとブラウザ上でindex.htmlの内容が表示されることも確認できました。
リソースの削除
それでは作成したリソースたちを削除していきます。
リソースの一括削除もできることもIaCのいいところですね(本番環境では注意です)。
pulumi destroyを実行します。
リソースを本当に削除するかどうかを確認するプロンプトが表示されます。問題なければyesを選択し、リソースが削除されるまで待機します。
pulumi destroy |
なぜか、バケットが削除されなくてエラーになりました。
pulumi上からオブジェクトは削除されていましたが、Google Cloudのコンソール画面を見るとオブジェクトが削除されていませんでした。。。
Do you want to perform this destroy? yes |
Google Cloudのコンソール画面から手動でオブジェクトを削除し、再度pulumi destroyを実行します。
pulumi destroy |
無事削除されました。
スタック自体を削除するには、pulumi stack rmを実行します。このコマンドによりすべての更新履歴とともに、Pulumi Cloud からスタックが完全に削除されます。
pulumi stack rm |
Pulumi Cloudを確認すると、dev stackが削除されていることが確認できました。
[外伝] Pulumi AI
ちょうど一週間ほど前に、自然言語からIaC(インフラ構成コード)を自動生成する「Pulumi AI」を含む、AIを活用した新サービス群「Pulumi Insights」が発表されました。
タイムリーな内容なので、本記事でも試してみたいと思います。
早速使ってみた。
Pulumi AIの入力に以下の情報を渡してみました。日本語にも対応しています。
Create GCP Resource. |
上記の入力を与えたときには下記のようにPulumi AIが入力内容をもとにPulumiのGoのコードを生成していきます(す、すごい)。。。
以下が、Pulumi AIによって生成されたコードになります。
きちんと作成するリソースごとにコメントアウトも入れてくれて助かります。
package main |
とりあえず、脳死コピーをしてpulumi upを実行すると下記のようにエラーになりました。
pulumi up |
GCE/Firewallのgoの記載方法が誤っていそうなのでGCEについての公式ドキュメントとFirewallについての公式ドキュメントを確認し、エラーを修正します。
また、GCEを構築するゾーン指定が漏れていたので、48行目に追加します。
package main |
修正後、再度pulumi upコマンドを実行し、yesをクリックします。
pulumi up |
下記のように、成功しました。
Do you want to perform this update? yes |
Google Cloudのマネジメントコンソールから「VMインスタンス」に作成されたVMインスタンスの「SSHボタン」をクリックします。
ブラウザがたちが上がり、しばらくすると無事にIAP経由でSSHできることを確認できました。
さいごに
今回は、PulumiでのIaC入門について記載しました。
IaCはインフラリソースをコードで管理できるため、インフラリソースの迅速なデプロイや、品質の担保、オペミスの削減など様々なメリットがありますが、運用上のつらみもあるので利用するにはコードを管理するディレクトリ設計や、コーディング規約などを設けて利用していきましょう。
Pulumiにも入門してみましたが、いかがだったでしょうか。普段Terraformを利用している筆者からすると、アプリケーションコード(Go)を使用してインフラリソースが構築できるのは新鮮でした。普段アプリケーションコードを書いているアプリエンジニアからするとだいぶインフラリソースを構築するハードルが下がったのではと思います。
また、外伝としてPulumi AIにも触れてみましたが、入力する内容が良くなかったのか一発でPulumi upを成功させることができなかったです。しかし、コンソールで対話型で構築したいインフラリソースを入力することでコードが自動生成されたるのは画期的だと思いました。まだまだ精度の問題はあるかと思いますが、いつかコードを自身で0から書かなくなる日もすぐそこなのだろうなと危機感を持ちました。
春の入門祭り2023、次回は小澤泰河さんのCDN 入門とエッジでのアプリケーション実行です。