はじめに
最近、Terraformを触る機会があったのですが、独自言語(HCL)を覚えるのに時間が
かかりそうで手を付けられずにいました。
そのような時にPulumiは、Pulumi AIでコードを自動生成できてかつ、
YAMLで書けるということを知りました。学習コストが低そうだったので実際に使ってみることにしました。
TL;DR
- Pulumiはプログラミング言語でインフラを構築可能なプロビジョニングツールであり、
慣れ親しんだ開発言語(Python/TypeScript/Goなど)やマークアップ言語(YAMLなど)で記述可能 - さらにAWS、Azure、GCP、Kubernetes など、さまざまなクラウドプラットフォームをサポートしている
- Pulumi AIは、コードを自動生成してくれる。ただし、多少の修正は必要
- YAMLで書けてAIも使えるので、個人的には学習コストを低く抑えられたと感じる
前提条件
PulumiでAWSを操作するには以下が必要です
- Pulumiのアカウントを所持していること
- AWSにてIAMユーザーのアクセスキーが作成してあること
実行環境
- Amazon マシンイメージ(AMI)
- Amazon Linux 2023 AMI
- Pulumi
- v3.112.0
詳細
1. アクセストークンの作成
- 以下にアクセスする
- [Create token]を選択する
-
Description
にトークン名を入力し、[Create token]を選択する - トークンの内容をコピーしておく
2. EC2インスタンスにPulumiをインストール
-
TeraTermなどでEC2インスタンスにログインする
-
Pulumiをインストールする
$ wget https://get.pulumi.com/releases/sdk/pulumi-v3.112.0-linux-x64.tar.gz $ mkdir -p ~/.pulumi/bin $ tar -xzvf pulumi-v3.112.0-linux-x64.tar.gz -C ~/.pulumi/bin --strip-components=1
-
PATHを通す
$ echo 'export PATH="$HOME/.pulumi/bin:$PATH"' >> ~/.bashrc
-
変更したPATHを有効化する
$ source ~/.bashrc
3. Pulumi Projectの作成
-
Pulumiにログインする。ここで、作成したトークンを入力する
$ pulumi login
-
作業用ディレクトリを作成する
$ mkdir quickstart && cd quickstart
-
作業用Projectを作成する
- 今回はYAMLでAWS用の定義ファイルを書くので
aws-yaml
としています
$ pulumi new aws-yaml
- 色々と聞かれますが、特に何も入力せずに
Enter
でも問題ありません(ここではRegionをus-west-2
に変更しました)
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. project name (quickstart): project description (A minimal AWS Pulumi YAML program): Created project 'quickstart' 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): us-west-2 Saved config Your new project is ready to go! To perform an initial deployment, run `pulumi up`
- 今回はYAMLでAWS用の定義ファイルを書くので
-
Pulumi.dev.yaml
とPulumi.yaml
が作成されたことを確認する- Pulumi.yaml: AWSリソースの定義ファイル
- Pulumi.dev.yaml: 環境変数などを記述するファイル
$ ls Pulumi.dev.yaml Pulumi.yaml
なお、
Pulumi.dev.yaml
は以下のようになっているので、そのまま使います。Pulumi.dev.yamlconfig: aws:region: us-west-2
4. Pulumi AIでAWSリソースの定義ファイル作成
-
Pulumiのホーム画面右上の[Pulumi AI]を選択する
-
[YAML]を選択し、処理内容を記述して[Update program]を選択する。処理内容は可能な限り具体的に書くとよい
- 記述した内容
- AWSでインターネット経由で接続可能なEC2インスタインス、VPC、サブネット、セキュリティグループを作成する
-
出力結果
name: aws-ec2-instance-with-internet-access runtime: yaml description: A program to create an AWS EC2 instance within a VPC with a subnet and security group, accessible over the internet. resources: # Create a new VPC myVpc: type: aws:ec2:Vpc properties: cidrBlock: "10.0.0.0/16" tags: Name: "my-vpc" options: provider: aws # Explicitly choose the aws provider # Create an Internet Gateway myInternetGateway: type: aws:ec2:InternetGateway properties: vpcId: ${myVpc.id} tags: Name: "my-internet-gateway" # Create a new Subnet within the VPC mySubnet: type: aws:ec2:Subnet properties: vpcId: ${myVpc.id} cidrBlock: "10.0.1.0/24" mapPublicIpOnLaunch: true tags: Name: "my-subnet" # Create a new Route Table myRouteTable: type: aws:ec2:RouteTable properties: vpcId: ${myVpc.id} routes: - destinationCidrBlock: "0.0.0.0/0" gatewayId: ${myInternetGateway.id} tags: Name: "my-route-table" # Associate the Route Table with the Subnet myRouteTableAssociation: type: aws:ec2:RouteTableAssociation properties: subnetId: ${mySubnet.id} routeTableId: ${myRouteTable.id} # Create a Security Group within the VPC mySecurityGroup: type: aws:ec2:SecurityGroup properties: vpcId: ${myVpc.id} description: "Allow SSH inbound traffic" tags: Name: "my-security-group" ingress: - protocol: "tcp" fromPort: 22 toPort: 22 cidrBlocks: ["0.0.0.0/0"] egress: - protocol: "-1" # Allow all outbound traffic fromPort: 0 toPort: 0 cidrBlocks: ["0.0.0.0/0"] # Launch an EC2 instance within the subnet myInstance: type: aws:ec2:Instance properties: ami: ami-0c55b159cbfafe1f0 # Replace with the correct AMI for your region instanceType: "t2.micro" subnetId: ${mySubnet.id} securityGroupIds: [${mySecurityGroup.id}] tags: Name: "my-instance" outputs: vpcId: ${myVpc.id} subnetId: ${mySubnet.id} internetGatewayId: ${myInternetGateway.id} routeTableId: ${myRouteTable.id} routeTableAssociationId: ${myRouteTableAssociation.id} securityGroupId: ${mySecurityGroup.id} instanceId: ${myInstance.id} instancePublicIp: ${myInstance.publicIp}
- 記述した内容
-
Pulumi AIの結果をPulumiのドキュメント(Pulumi > AWS > API Docs)などをもとに修正し、
Pulumi.yaml
に記入する-
細かい修正をしたい場合は、別途Pulumi AIで作成した定義ファイルを参考にしてもよい
--- name: quickstart # 修正 runtime: yaml description: A program to create an AWS EC2 instance within a VPC with a subnet and security group, accessible over the internet. resources: # Create a new VPC myVpc: type: aws:ec2:Vpc properties: cidrBlock: "10.0.0.0/16" tags: Name: "my-vpc" # options: # 削除 # provider: aws # Create an Internet Gateway myInternetGateway: type: aws:ec2:InternetGateway properties: vpcId: ${myVpc.id} tags: Name: "my-internet-gateway" # Create a new Subnet within the VPC mySubnet: type: aws:ec2:Subnet properties: vpcId: ${myVpc.id} cidrBlock: "10.0.1.0/24" mapPublicIpOnLaunch: true availabilityZone: ${aws:region}a # 追加 tags: Name: "my-subnet" # Create a new Route Table myRouteTable: type: aws:ec2:RouteTable properties: vpcId: ${myVpc.id} # routes: # 削除 # - destinationCidrBlock: "0.0.0.0/0" # gatewayId: ${myInternetGateway.id} tags: Name: "my-route-table" # Create a route that directs 0.0.0.0/0 to the Internet Gateway(追加) myRoute: type: aws:ec2:Route properties: destinationCidrBlock: "0.0.0.0/0" gatewayId: ${myInternetGateway.id} routeTableId: ${myRouteTable.id} # Associate the Route Table with the Subnet myRouteTableAssociation: type: aws:ec2:RouteTableAssociation properties: subnetId: ${mySubnet.id} routeTableId: ${myRouteTable.id} # Create a Security Group within the VPC mySecurityGroup: type: aws:ec2:SecurityGroup properties: vpcId: ${myVpc.id} description: "Allow SSH inbound traffic" tags: Name: "my-security-group" ingress: - protocol: "tcp" fromPort: 22 toPort: 22 cidrBlocks: ["0.0.0.0/0"] egress: - protocol: "-1" # Allow all outbound traffic fromPort: 0 toPort: 0 cidrBlocks: ["0.0.0.0/0"] # Launch an EC2 instance within the subnet myInstance: type: aws:ec2:Instance properties: ami: ami-0395649fbe870727e # 修正 instanceType: "t2.micro" subnetId: ${mySubnet.id} # securityGroupIds: [${mySecurityGroup.id}] # 削除 securityGroups: ["${mySecurityGroup.id}"] # 追加 availabilityZone: ${aws:region}a # 追加 keyName: my-key # 追加 tags: Name: "my-instance" outputs: vpcId: ${myVpc.id} subnetId: ${mySubnet.id} internetGatewayId: ${myInternetGateway.id} routeTableId: ${myRouteTable.id} routeTableAssociationId: ${myRouteTableAssociation.id} routeID: ${myRoute.id} # 追加 securityGroupId: ${mySecurityGroup.id} instanceId: ${myInstance.id} instancePublicIp: ${myInstance.publicIp}
-
補足として、Pulumi.dev.yaml
にあるaws:region
の値は、
${aws:region}
と記載します(詳細は、Pulumi > Configurationを参照)
5. Pulumiによるリソースの作成
-
IAMユーザーのアクセスキーを登録する
$ export AWS_ACCESS_KEY_ID="<YOUR_ACCESS_KEY_ID>" $ export AWS_SECRET_ACCESS_KEY="<YOUR_SECRET_ACCESS_KEY>"
-
リソースを作成する
$ pulumi up
-
リソースが作成されていることを確認する(以下はログの一部)
Type Name Status Info + pulumi:pulumi:Stack quickstart-dev created (52s) + ├─ aws:ec2:Vpc myVpc created (2s) + ├─ aws:ec2:RouteTable myRouteTable created (1s) + ├─ aws:ec2:SecurityGroup mySecurityGroup created (2s) 1 warning + ├─ aws:ec2:InternetGateway myInternetGateway created (1s) + ├─ aws:ec2:Subnet mySubnet created (12s) + ├─ aws:ec2:Route myRoute created (1s) + ├─ aws:ec2:Instance myInstance created (33s) + └─ aws:ec2:RouteTableAssociation myRouteTableAssociation created (1s)
6. Pulumiマイページからの結果確認
7. Pulumiによるリソースの削除
-
リソースを削除する
$ pulumi down
-
リソースが削除されていることを確認する(以下はログの一部)
Type Name Status - pulumi:pulumi:Stack quickstart-dev deleted (0.19s) - ├─ aws:ec2:Instance myInstance deleted (41s) - ├─ aws:ec2:RouteTableAssociation myRouteTableAssociation deleted (1s) - ├─ aws:ec2:Route myRoute deleted (1s) - ├─ aws:ec2:Subnet mySubnet deleted (0.71s) - ├─ aws:ec2:RouteTable myRouteTable deleted (1s) - ├─ aws:ec2:InternetGateway myInternetGateway deleted (1s) - ├─ aws:ec2:SecurityGroup mySecurityGroup deleted (1s) - └─ aws:ec2:Vpc myVpc deleted (1s)
さいごに
- Pulumiの定義ファイルの書き方がよくわからなくても、Pulumi AIの結果を少し修正するだけでAWSに対するリソースの作成ができました
- AIを活用することで、学習コストや作業時間の削減が期待できそうです
参考URL
-
Think IT > Infrastructure-as-Codeアプローチと「Pulumi」の概要
- Pulumiの構成・料金体系
-
PulumiはIaCの革命児になれるか
- TerraformやAWS CDKとの比較
- Pulumi AIの説明
-
Pulumi > Download & install Pulumi
- Pulumiのインストール方法(1)
-
GitHub > pulumi > pulumi install for linux does not work
- Pulumiのインストール方法(2)
- 今回はこちらを採用
- Pulumiのインストール方法(2)
-
テラフォーム vs プルミ
- TerraformとPulumiの比較
-
Pulumi > Pulumi & AWS: Create new project
- AWSにおけるPulumiプログラムの作成
-
Pulumi > AWS > API Docs
- PulumiでAWSを操作するための記述方法
-
Pulumi > Configuration
- Pulumiで環境ごとに異なる変数を使用する方法