kt.log

Azure Infrastructure as Code with Pulumi in TypeScript - Get Started

Azure の Infrastructure as Code を Pulumi と TypeScript で実現する - Get Started 編

本記事では、オープンソースソフトウェア Pulumi を使った AzureInfrastructure as Code (IaC) のうち、公式ドキュメントの中の Get Started with Pulumi に沿った手順を解説します。

IaC といえば、古くは Chef, Puppet, Ansible があります。
今日、IaC を実現するよりモダンなツールはいくつかあり、最もメジャーで勢いがあるのは Terraform でしょう。Terraform と Pulumi の比較については詳しく述べませんので、 検索 してみてください。

また、Azure には Bicep という IaC のための言語があります。こちらも Terraform と同じ方向性のツールであると思われます。

一方、AWS には CDK という IaC フレームワークがあります。こちらは最終的には CloudFormation のテンプレート JSON ファイルを出力するものですが、その特徴は一般的なプログラミング言語で記述できるところにあります。本記事執筆時点では、 JavaScript, TypeScript, Python, Java, C# が GA、Go が開発者プレビューとのことです。つまり、宣言的な DSL ではなく、一般的なプログラミング言語で手続き的に記述できるということです。これは特に開発者など、プログラミング言語を習得済みの方には大きなエクスペリエンスとなります。

Pulumi は AWS CDK に近い性質を持っています。言い換えると、Terraform (HCL) や Bicep とは大きく異なります。

確かに Terraform も Custom Privider を Go で記述できたり、エコシステムには Python ラッパーがあったり、もっというと Cloud Development Kit for Terraform (CDKTF)2022年8月1日に一般提供されたので、実は Pulumi や AWS CDK の領域を丸ごとカバーできていたりします。

だからといって、CDKTF よりも 5年前に生まれた、「マルチクラウド×一般的なプログラミング言語による手続き型の記述」の草分けである Pulumi (2017年に Microsoft, Amazon, Google のソフトウェアのベテランが設立したそうです) を、比較もしないまま切り捨てるのは早急でしょう。

ポイントは変化めまぐるしいクラウドサービスへのキャッチアップ、書き味、そして利用条件であると思います。
本記事を皮切りに、実際に書いて動かして理解しながら、比較につなげていきたいと思います。

前提

  • Microsoft Azure に利用可能なサブスクリプションを持っており、かつ、所有者のロールが割り当てられている
  • Pulumi の開発・実行環境に以下がインストールされている

免責

  • 本記事では macOS での操作を示します

手順

準備

Pulumi のインストール

Install Pulumi | Before You Begin に沿ってインストールします。

1
brew install pulumi/tap/pulumi

Azure へのログインとサブスクリプションの設定

Pulumi は Azure SDK を使って Azure への認証と操作を行いますが、Azure CLI も併用することで、開発が便利になります。また、複数のサブスクリプションを利用している場合、対象のサブスクリプションを明示的に指定することができます。その方法を以下に示します。

1
az login
1
az account list
1
az account set --subscription ${SUBSCRIPTION_ID}

プロジェクトの作成

Create a New Project に沿ってプロジェクトを作成します。今回、言語は TypeScript を使います。

1
2
mkdir pulumi-quickstart-ts && cd pulumi-quickstart-ts
pulumi new quickstart-ts-20220825a

pulumi new によるプロジェクトの作成は対話形式で行われ、すべての入力が完了すると、コードや設定ファイルが生成されます。

プロジェクトのレビュー

Review the New Project に沿って index.ts にデフォルトで記述されているコードを確認します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import * as pulumi from "@pulumi/pulumi";
import * as resources from "@pulumi/azure-native/resources";
import * as storage from "@pulumi/azure-native/storage";

// Create an Azure Resource Group
const resourceGroup = new resources.ResourceGroup("resourceGroup");

// Create an Azure resource (Storage Account)
const storageAccount = new storage.StorageAccount("sa", {
resourceGroupName: resourceGroup.name,
sku: {
name: storage.SkuName.Standard_LRS,
},
kind: storage.Kind.StorageV2,
});

// Export the primary key of the Storage Account
const storageAccountKeys = storage.listStorageAccountKeysOutput({
resourceGroupName: resourceGroup.name,
accountName: storageAccount.name
});

これをそのままデプロイすると、 resourceGroup という名前のリソースグループが作成され、その中に sa という名前のストレージアカウントが作成されます。

本記事では、Azure リソースの種類に推奨される省略形 - Cloud Adoption Framework | Microsoft Docs にならい、以下のように指定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import * as pulumi from "@pulumi/pulumi";
import * as resources from "@pulumi/azure-native/resources";
import * as storage from "@pulumi/azure-native/storage";

// Create an Azure Resource Group
const resourceGroup = new resources.ResourceGroup("rg-20220825a-pulumi-quickstart");

// Create an Azure resource (Storage Account)
const storageAccount = new storage.StorageAccount("st20220825a", {
resourceGroupName: resourceGroup.name,
sku: {
name: storage.SkuName.Standard_LRS,
},
kind: storage.Kind.StorageV2,
});

// Export the primary key of the Storage Account
const storageAccountKeys = storage.listStorageAccountKeysOutput({
resourceGroupName: resourceGroup.name,
accountName: storageAccount.name
});

ここで注意する必要があるのが、命名の制約です。特にストレージアカウント名は半角英数字小文字のみ、かつ3文字以上24文字以下と、タイトな制約があります。実は Pulumi はデプロイするリソース名に自動的に 8文字の suffix を付加するため、使用できる文字列長は最大 16文字となります。

上記の例でいうと、デプロイされるリソース名はそれぞれ以下の要領になります。

  • リソースグループ: rg-20220825a-pulumi-quickstart123abc4d
  • ストレージアカウント: st20220825a567efg8h

もし上記制約を超えてしまうような名前の指定が行われた場合、プロビジョニングの時点でエラーとなります。

スタックのデプロイ

Deploy the Stack に沿って、スタックをデプロイします。

1
pulumi up

すると、プロビジョニングが開始され、プレビューが表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Previewing update (dev)

View Live: https://app.pulumi.com/****/quickstart-ts-20220825a/dev/previews/********-****-****-****-************

Type Name Plan
+ pulumi:pulumi:Stack quickstart-20220825a-dev create
+ ├─ azure-native:resources:ResourceGroup rg-20220825a-pulumi-quickstart create
+ └─ azure-native:storage:StorageAccount st20220825a create

Outputs:
primaryStorageKey: output<string>

Resources:
+ 3 to create

Do you want to perform this update? [Use arrows to move, enter to select, type to filter]
yes
> no
details

ここで no を選択したままにして Enter キーを押すと、デプロイは中止されます。 details を選択すると、詳細を表示することができます。 yes を選択することで、実際のデプロイが開始されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Do you want to perform this update? yes
Updating (dev)

View Live: https://app.pulumi.com/****/quickstart-20220825a/dev/updates/1

Type Name Status
+ pulumi:pulumi:Stack quickstart-20220825a-dev created
+ ├─ azure-native:resources:ResourceGroup rg-20220825a-pulumi-quickstart created
+ └─ azure-native:storage:StorageAccount st20220825a created

Outputs:
primaryStorageKey: "****************************************************************************************"

Resources:
+ 3 created

Duration: 34s

スタックの破棄

Destroy the Stack に沿って、スタックを破棄します。これにより、Azure 上からリソース(リソースグループを含む)が削除されます。

1
pulumi destroy

デプロイのときと同様に、プロビジョニングとプレビューが行われ、 yes を選択することで実際のリソースの削除が行われます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Previewing destroy (dev)

View Live: https://app.pulumi.com/****/quickstart-20220825a/dev/previews/********-****-****-****-************

Type Name Plan
- pulumi:pulumi:Stack quickstart-20220825a-dev delete
- ├─ azure-native:storage:StorageAccount st20220825a delete
- └─ azure-native:resources:ResourceGroup rg-20220825a-pulumi-quickstart delete

Outputs:
- primaryStorageKey: "****************************************************************************************"

Resources:
- 3 to delete

Do you want to perform this destroy? [Use arrows to move, enter to select, type to filter]
yes
> no
details

リソースの削除を進める場合は、 yes を選択します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Do you want to perform this destroy? yes
Destroying (dev)

View Live: https://app.pulumi.com/****/quickstart-20220825a/dev/updates/1

Type Name Status
- pulumi:pulumi:Stack quickstart-20220825a-dev deleted
- ├─ azure-native:storage:StorageAccount st20220825a deleted
- └─ azure-native:resources:ResourceGroup rg-20220825a-pulumi-quickstart deleted

Outputs:
- primaryStorageKey: "****************************************************************************************"

Resources:
- 3 deleted

Duration: 1m19s

The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained.
If you want to remove the stack completely, run 'pulumi stack rm dev'.

これで、デプロイしたリソースはすべて削除されました。

まとめ

マルチクラウド対応で一般的なプログラミング言語が利用できる IaC ツールの草分けである Pulumi について、Get Started with Pulumi に沿って、TypeScript のコードにより Azure のリソースのデプロイと削除を行いました。

個人的には過去に AWS CDK で衝撃を受けて以来、IaC は一般的なプログラミング言語でやりたいと考えており、2021年に Pulumi を見つけて、Azure で利用したいと考えてきました。

2022年8月現在では CDKTF も登場しましたし、AWS CDK も継続的にアップデートがされているため、この手のツールには開発者をはじめとした一定のニーズがあると考えています。また、一般的なプログラミング言語であるがゆえの生産性に関わるベネフィットもあると考えています。

今後、他の言語での利用や、CDKTF の検証も通して、自分にとってベストなツールを見つけていきたいと思います。

See also