「Pulumi Stack」とは ー Pulumiによるマルチステージ環境の構築方法
$ pulumi stack export --file stack.json
現在Pulumiで管理されているインフラストラクチャの情報(state)をjson形式で確認できます。デフォルトでstateは標準出力されますが、「--file」オプションで特定のファイルに出力することもできます。
$ pulumi stack export { "version": 3, "deployment": { "manifest": { "time": "2023-03-22T14:10:58.208949+09:00", "magic": "f798c0****", "version": "v3.55.0" }, 〜〜(略)〜〜 "resources": [ { "urn": "urn:pulumi:dev::test1::pulumi:pulumi:Stack::test1-dev", "custom": false, "type": "pulumi:pulumi:Stack", "outputs": { "project_name": "test1", "stack_name": "dev" } } ] } }
●Stackの設定(clear text)
複数のStackを利用する場合、Stackごとに一部異なる値を設定したいケースがあります。例えば、ステージング用のStackと本番環境用のStackとでAWS EC2のサイズを変更したいケースなどが挙げられます。その場合はProgramに直接サイズなどの値をハードコーディングせず、各Stackに値を設定して、それをProgramから呼び込むような運用が適しています。
Pulumi Stackのkey-value形式の設定ファイル「Pulumi.<stack名>.yaml」に直接値を書き込むこともできますが、「pulumi config set」コマンドを実行すると自動的にStackの設定ファイルにkey-value形式で値が追加されます。値は自動的に「<project名>:<key>: <value>」のフォーマットが適用されます。<project名>はPulumi Projectのメタデータが記述されたファイル「Pulumi.yaml」から参照されます。
$ cat Pulumi.yaml name: pulumi-test 〜〜(略)〜〜 $ pulumi config set key1 value1 $ cat Pulumi.dev.yaml config: aws:region: ap-northeast-1 pulumi-test:key1: value1
ちなみに、今まで設定したkeyを以下のように指定することでコマンドから値を確認できます。
$ pulumi config get key1 value1
Stackの設定およびコマンドの詳細は、こちらを確認してください。
●Stackの設定(secret)
前述の「Stackの設定」をシークレット値として暗号化します。データベースパスワードやサービストークンなど、センシティブなデータをハッシュ化した状態でStackの設定ファイルやstateファイルに記録されます。
前述の「Stackの設定」のコマンドに「--secret」フラグを追加することで暗号化が実行されます。暗号化の際に利用されるキーは、デフォルトでPulumiがStackごとに自動的に生成するものが利用されますが、AWSやGCPなどの主要なクラウドサービスが提供する暗号化キー(KMS、Cloud Key Managementなど)を利用することもできます。シークレットに関する詳細は、こちらを確認してください。
$ pulumi config set --secret key1 value1 $ cat Pulumi.dev.yaml config: aws:region: ap-northeast-1 pulumi-test:key1: secure: AAABAFo1lMSgf/iv/OtxLPLTF1IcuXF4J+n4Rz+Zzo6jBANQ6lw=
Pulumi Programによる操作
PythonでPulumi Programを作成する場合はPulumi Python SDKを利用します。Pulumi Python SDKはPythonでインフラストラクチャの状態を定義したり、Pulumi CLIで設定した情報を受け取ることができます。PulumiはPythonをはじめ、GoやNode.js、Javaなど複数の主要な開発言語がサポートされていますが、ここではPythonに関するStackの操作について解説します。
●Pulumi Project/Stack名取得import pulumi # project名取得 project = pulumi.get_project() pulumi.export('project_name', project) # stack名取得 stack = pulumi.get_stack() pulumi.export('stack_name', stack)
「pulumi.export(name: str, value: Any)」でStackのoutputを設定できます。上記では、取得したproject名とstack名をoutputとして設定しています。
●Pulumi Stack設定取得import pulumi # Stack設定取得 conf = pulumi.Config() pulumi.export('key_output', conf.get("test-key"))
以下のように、事前にStackに設定した値「test-key: test-value」を取得するコードになります。「pulumi.Config(name: str | None = None)」クラスでStackの設定情報を取得し、「get(key: str)」により特定のkeyで値を取得しています。
$ cat Pulumi.dev.yaml config: pulumi-test:test-key: test-value
【参考】APIを通じたPulumiの操作「Pulumi Automation API」
一般的に、Pulumiでは事前にStackなどに設定した情報をProgramで呼び出して実行する方法を取ることで、例えばインフラ担当者がPulumi Project/Stackの用意やStack設定などのインフラ構成を担当し、アプリ担当者はそのあらかじめ用意された構成情報をアプリケーション(Program)から読み込んで利用する、などの役割分担が可能です。
ただし、Pulumi 3.0からリリースされた「Pulumi Automation API」の機能を利用することで、アプリケーションからPulumiを用いてインフラ構成を操作(pulumi up / pulumi destroy / pulumi stack init などに相当する操作)できるようになりました。詳細は次回以降で紹介しますが、例えば公式が紹介するサンプルコードのように、コード内でStackの作成や選択などが可能になります。
〜〜(略)〜〜 stack = auto.create_or_select_stack(stack_name=stack_name, project_name=project_name, program=pulumi_program) 〜〜(略)〜〜【Pulumi Program(main.py)】
【ハンズオン】複数Stackのデプロイ
ハンズオンの流れ
ここからは、ハンズオンで実際に複数のStackをデプロイしていきます。ハンズオンの流れと関連するサービス/リソースの全体象は以下のとおりです。ハンズオン実施前には「事前準備」、ハンズオン完了後は「クリーンアップ作業」を行います。
- Program/Stack(dev)を新規で作成
- 新規にStack(prod)を作成し、Stack(dev/prod)に値を設定
- Programを更新
- Stack(dev)をデプロイ
- Stack(prod)をデプロイ
また、ハンズオン実施時の最終的なディレクトリ構成は以下のようになります。
pulumi-stack ← Pulumi Project directory ├── __main__.py ├── Pulumi.yaml ├── Pulumi.dev.yaml ├── Pulumi.prod.yaml ├── requirements.txt └── venv
【前提】
- ハンズオンを実施する上で必要なAWSのアクセス権限を有する
- AmazonEC2FullAccess: EC2インスタンスを作成、停止、開始、削除
- AmazonVPCFullAccess: VPCとサブネットを作成するために必要な権限
- PCにPythonを導入済み(version 3.7以上)
事前準備
Pulumiを利用したAWSリソースデプロイのハンズオンを実施するには、事前に以下の作業が実施済みである必要があります。事前準備の手順は前回で解説しているので、まだ実施されていない方はそちらを確認してください。
- Pulumi CLIのインストール
- Pulumiアカウント新規作成
- AWSアカウントへのPulumiアクセス設定
Pulumi Project/Stackの新規作成
Pulumi CLIを用いて、新規でPulumi ProjectとStackを作成します。
- Pulumi Project用のディレクトリを作成します。ディレクトリ名はお好みで問題ありませんが、次に実施するPulumi Project作成コマンドでディレクトリ名がProject名として参照されるようになります(コマンド実施時に別のProject名を指定することも可能)。ここでは「pulumi-stack」をディレクトリ名とProject名に設定します。
$ mkdir pulumi-stack && cd pulumi-stack
- Pulumi Project作成コマンド「pulumi new <テンプレート名>」を実行します。今回はAWSリソースをpythonで作成するので、テンプレート名は「aws-python」のようになります。テンプレート名を正しく設定し、以降のプロンプトでProject名やStack名などを指定すると、AWSリソースの作成に必要な基本的な設定ファイル(Project定義ファイル、Stack設定ファイルなど)が作成されます。
$ pulumi new aws-python This command will walk you through creating a new Pulumi project. Enter a value or leave blank to accept the (default), and press <ENTER>. Press ^C at any time to quit.
- 「pulumi new <テンプレート名>」コマンド実行後は「Pulumi Project名(project name)」「Pulumi Projectの説明(project description)」「Pulumi Stack名(stack name)」「AWSのデフォルトリージョン(aws:region)」をプロンプトに従って設定していきます。各項目右の括弧内の値は、特に指定がない場合のデフォルト値を示します。ここでは「Pulumi Project名(project name)」「Pulumi Projectの説明(project description)」「Pulumi Stack名(stack name)」はデフォルト値を設定するため、各プロンプトでそのまま<ENTER>を押下し、「AWSのデフォルトリージョン(aws:region)」では「アジアパシフィック (東京)」に設定するため、「ap-northeast-1」を設定してから<ENTER>を押下しました。
project name: (pulumi-test) project description: (A minimal AWS Python Pulumi program) Created project 'pulumi-test' Please enter your desired stack name. To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`). stack name: (dev) Created stack 'dev' aws:region: The AWS region to deploy into: (us-east-1) ap-northeast-1 Saved config
以降は自動的にPulumiの実行に必要なファイルやpythonのdependenciesなどが自動的にインストール/作成され、Pulumi ProjectおよびStackの作成が完了します。Installing dependencies... Creating virtual environment... Finished creating virtual environment Updating pip, setuptools, and wheel in virtual environment... Requirement already satisfied: pip in ./venv/lib/python3.10/site-packages (22.2.2) Collecting pip Using cached pip-23.0.1-py3-none-any.whl (2.1 MB) Requirement already satisfied: setuptools in ./venv/lib/python3.10/site-packages (65.4.1) Collecting setuptools Downloading setuptools-67.6.0-py3-none-any.whl (1.1 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 7.8 MB/s eta 0:00:00 〜〜(略)〜〜 Building wheels for collected packages: pulumi-aws Building wheel for pulumi-aws (setup.py) ... done Created wheel for pulumi-aws: filename=pulumi_aws-5.32.0-py3-none-any.whl size=10395539 sha256=0f968d1992b61454d3ac2c5add13d6e923c94fd81df09007085d183781d7bd81 Stored in directory: /Users/k-ozeki/Library/Caches/pip/wheels/31/6b/44/7b334e00c871c127c372dc2e515bd751bd3e3b20a44e70ec37 Successfully built pulumi-aws Installing collected packages: arpeggio, six, semver, pyyaml, protobuf, grpcio, dill, attrs, pulumi, parver, pulumi-aws Successfully installed arpeggio-2.0.0 attrs-22.2.0 dill-0.3.6 grpcio-1.51.3 parver-0.4 protobuf-4.22.1 pulumi-3.59.0 pulumi-aws-5.32.0 pyyaml-6.0 semver-2.13.0 six-1.16.0 Finished installing dependencies Finished installing dependencies Your new project is ready to go! ✨ To perform an initial deployment, run `pulumi up`
この時点で「Pulumi.yaml (Pulumi Projectのメタデータが記述されたファイル)」「Pulumi.dev.yaml (Pulumi Stackのkey-value形式の設定ファイル、dev環境用)」「__main__.py (Python用のPulumi Program)」「requirements.txt / venv (開発言語(runtime)特有のファイル/ディレクトリ)」が生成されます。$ ls -F Pulumi.dev.yaml Pulumi.yaml __main__.py requirements.txt venv/
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- SecretもPulumiで使いこなしたい! PulumiのSecurityを試してみよう
- Policy as Codeでインフラのコンプライアンスを自動実現! 「Pulumi CrossGuard」を活用してみよう
- PulumiでAWSリソースをデプロイしよう
- 既に存在するリソースをPulumiで管理してみよう
- Pulumi Kubernetes Operatorを活用してPulumiのCI/CDを実現しよう
- TerraformからPulumiへの移行
- 「Pulumi Automation API」でPulumi CLIの機能をコード化しよう
- 「Terraform」のコードを自分で書けるようになろう
- kustomizeで復数環境のマニフェストファイルを簡単整理
- マシン・イメージを自動構築し、作業効率を高めるPacker入門