話題の記事

これが次世代プロビジョニングツールの実力か!? PulumiでAWSリソースを作成してみた

2019.05.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

みなさんAWSリソースはどのように作成していますか??

私はツールに対するこだわりがないので、CloudFormationを使ったり、Terraformを使ったり、ときにはAWSコンソールをポチポチすることでリソースを作成しています。制約がなければ、その時の気分で構築方法を決めることが多いです。

と、そんな折、Pulumiなるツールの存在を知りました。そして、少し動かしてみたところ「あぁ、これ使って構築してぇ。。」という思いが溢れてきました。

そこで今回は、Pulumiの使い方を簡単に紹介したいと思います。

Pulumi とは

Pulumiとは、Pulumi社によるオープンソースプロダクトです。

好きな言語(JavaScript,TypeScript,Python,Go)を利用して、アプリケーションとインフラストラクチャをデプロイすることができます。現時点では、以下のクラウドプロバイダに対応しています。

  • AWS
  • Microsoft Azure
  • Google Cloud Platform
  • Kubernetes
  • OpenStack
  • Pulumi Cloud Framework

チームで利用する場合、外部 SaaS と連携する場合には別途費用が発生します。

簡単にまとめると、「好きな言語でマルチクラウドに対して各種リソースをデプロイできるツール」といったところでしょうか。 AWSの公式のツール CDK のマルチクラウド版と捉えることもできます。

CloudFormationやTerraformと違い、好きな言語を使ってIaCができるというのは魅力的ですね。

やってみた

公式のチュートリアルをベースに進めていきます。

検証環境

macOS で言語は TypeScriptを利用します。

$ node -v
v10.15.3

インストール

まずはコマンドラインツールをインストールします。

$ curl -fsSL https://get.pulumi.com | sh
$ pulumi version
v0.17.10

プロジェクトの初期化

新規にプロジェクトを作成します。初回実行時にはGitHubやGitLab等による認証を求められまので、コンソールの指示に従い自身のアカウントで認証してください。

$ mkdir ahoy-pulumi && cd ahoy-pulumi
$ pulumi new aws-typescript
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: (ahoy-pulumi)
project description: (A minimal AWS TypeScript Pulumi program)
Created project 'ahoy-pulumi'

stack name: (dev)
Created stack 'dev'

aws:region: The AWS region to deploy into: (us-east-1) ap-northeast-1
Saved config

Installing dependencies...

Finished installing dependencies

Your new project is ready to go! ✨

To perform an initial deployment, run 'pulumi up'

この操作において、1つのプロジェクト(ahoy-pulumi)と 1つのスタック(dev)が作成されます。プロジェクトとスタックは 1 対多の関係です。スタック利用することで環境毎(本番、検証、開発)のリソース作成が可能になります。

コマンドでスタックが作成されたことを確認してみましょう。

$ pulumi stack ls
NAME  LAST UPDATE    RESOURCE COUNT  URL
dev*  3 minutes ago  3               https://app.pulumi.com/jogannaoki/ahoy-pulumi/dev

1つしかスタックがないのでわかりにくいですが、*が付いているところがカレントのスタックになります。 コンソールに表示されるURLよりGUIでスタックを確認することもできます。

生成されたファイルは以下になります。

$ ll
total 136
-rw-r--r-- 1 jogan.naoki staff 37B 5 12 14:05 Pulumi.dev.yaml
-rw------- 1 jogan.naoki staff 87B 5 12 14:04 Pulumi.yaml
-rw------- 1 jogan.naoki staff 273B 5 12 14:04 index.ts
drwxr-xr-x 92 jogan.naoki staff 2.9K 5 12 14:05 node_modules
-rw-r--r-- 1 jogan.naoki staff 48K 5 12 14:05 package-lock.json
-rw------- 1 jogan.naoki staff 228B 5 12 14:04 package.json
-rw------- 1 jogan.naoki staff 522B 5 12 14:04 tsconfig.json

Pulumi.yamlPulumi.dev.yamlおよびindex.tsの内容を確認してみましょう。

Pulumi.yaml

name: ahoy-pulumi
runtime: nodejs
description: A minimal AWS TypeScript Pulumi program

Pulumi.dev.yaml

config:
  aws:region: ap-northeast-1

Pulumi.yamlには、プロジェクトに関する情報が、Pulumi.dev.yamlにはconfigが記載されています。configには任意の値を追加しプログラムから読み込ませることも可能です。

index.ts

import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
import * as awsx from '@pulumi/awsx';

// Create an AWS resource (S3 Bucket)
const bucket = new aws.s3.Bucket('my-bucket');

// Export the name of the bucket
export const bucketName = bucket.id;

index.tsは、S3バケットを作成する簡単なコードとなっています。

スタックのプレビュー

Pulumiでは、リソースを作成する前に事前にスタックをプレビューすることができます。terraform planと同じような機能ですね。

$ pulumi preview
Previewing update (dev):

     Type                 Name             Plan       
 +   pulumi:pulumi:Stack  ahoy-pulumi-dev  create     
 +   └─ aws:s3:Bucket     my-bucket        create     
 
Resources:
    + 2 to create

Permalink: https://app.pulumi.com/jogannaoki/ahoy-pulumi/dev/previews/af267474-0e94-4513-9cde-6d0f5ab589e4

スタックのデプロイ

pulumi upによりスタックをデプロイします。

$ pulumi up
Previewing update (dev):

     Type                 Name             Plan       
 +   pulumi:pulumi:Stack  ahoy-pulumi-dev  create     
 +   └─ aws:s3:Bucket     my-bucket        create     
 
Resources:
    + 2 to create

Do you want to perform this update? yes
Updating (dev):

     Type                 Name             Status      
 +   pulumi:pulumi:Stack  ahoy-pulumi-dev  created     
 +   └─ aws:s3:Bucket     my-bucket        created     
 
Outputs:
    bucketName: "my-bucket-6e519a1"

Resources:
    + 2 created

Duration: 10s

Permalink: https://app.pulumi.com/jogannaoki/ahoy-pulumi/dev/updates/1

上記のコマンドによりS3バケットが作成されました。

$ aws s3 ls | grep my-bucket
2019-05-12 15:02:07 my-bucket-c2df6ac

また、コマンドの実行結果はPulumiが管理するサーバーにも保存されます。それにより、誰がどのタイミングでどのようなオペレーションを実行したのか履歴を追うことができます。

リソースに対するAWSコンソールへのリンクもついています。これも非常に便利です。

リソースの変更

先ほど作成したリソースを変更します。が、その前にちょっとブレイク、、

みなさん、リソースに対しどのようなパラメーターがあるのか?は何を見て判断していますか??CloudFormationであってもTerraformであっても公式マニュアルを参照することが多いのではないでしょうか??

ではPulumiではどうなるか。。

なんとIDEだけで確認できちゃいます!そして、TypeScriptであれば型のチェックも可能です。これは嬉しい!!

コードの修正

ちょっと脱線しましたが修正後のコードは以下とします。先ほど作成したS3バケットに対してpublic-read属性を追加しています。

index.ts

import * as pulumi from '@pulumi/pulumi';
import * as aws from '@pulumi/aws';
import * as awsx from '@pulumi/awsx';

// Create an AWS resource (S3 Bucket)
const bucket = new aws.s3.Bucket('my-bucket', { acl: 'public-read' });

// Export the name of the bucket
export const bucketName = bucket.id;

スタックのプレビュー

事前にプレビューをします。

$ pulumi preview
Previewing update (dev):

     Type                 Name             Plan       Info
     pulumi:pulumi:Stack  ahoy-pulumi-dev             
 ~   └─ aws:s3:Bucket     my-bucket        update     [diff: ~acl]
 
Resources:
    ~ 1 to update
    1 unchanged

Permalink: https://app.pulumi.com/jogannaoki/ahoy-pulumi/dev/previews/5e95df00-3649-4759-98f8-59170585e379

デプロイ実行時にはS3バケットが更新されることが確認できます。デプロイ実行前のS3バケットの状態は以下となっています。

$aws s3api get-bucket-acl --bucket my-bucket-c2df6ac
{
    "Owner": {
        "DisplayName": "XXXXXXXXXXXXXXXXXX",
        "ID": "XXXXXXXXXXXXXXXXXX"
    },
    "Grants": [
        {
            "Grantee": {
                "DisplayName": "XXXXXXXXXXXXXXXXXX",
                "ID": "XXXXXXXXXXXXXXXXXX",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        }
    ]
}

スタックのデプロイ

それではUpdateしてみましょう!

$pulumi up
Previewing update (dev):

     Type                 Name             Plan       Info
     pulumi:pulumi:Stack  ahoy-pulumi-dev             
 ~   └─ aws:s3:Bucket     my-bucket        update     [diff: ~acl]
 
Resources:
    ~ 1 to update
    1 unchanged

Do you want to perform this update? yes
Updating (dev):

     Type                 Name             Status      Info
     pulumi:pulumi:Stack  ahoy-pulumi-dev              
 ~   └─ aws:s3:Bucket     my-bucket        updated     [diff: ~acl]
 
Outputs:
    bucketName: "my-bucket-6e519a1"

Resources:
    ~ 1 updated
    1 unchanged

Duration: 7s

Permalink: https://app.pulumi.com/jogannaoki/ahoy-pulumi/dev/updates/2

S3バケットが更新されpublic-readが付与されていることが確認できます!

$aws s3api get-bucket-acl --bucket my-bucket-c2df6ac
{
    "Owner": {
        "DisplayName": "XXXXXXXXXXXXXXXXXX",
        "ID": "XXXXXXXXXXXXXXXXXX"
    },
    "Grants": [
        {
            "Grantee": {
                "DisplayName": "XXXXXXXXXXXXXXXXXX",
                "ID": "XXXXXXXXXXXXXXXXXX",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        },
        {
            "Grantee": {
                "Type": "Group",
                "URI": "http://acs.amazonaws.com/groups/global/AllUsers"
            },
            "Permission": "READ"
        }
    ]
}

もちろんGUIでも実行結果を確認できます。

リソースの削除

最後はdestroyコマンドでリソースを削除します。

$pulumi destroy
Previewing destroy (dev):

     Type                 Name             Plan       
 -   pulumi:pulumi:Stack  ahoy-pulumi-dev  delete     
 -   └─ aws:s3:Bucket     my-bucket        delete     
 
Resources:
    - 2 to delete

Do you want to perform this destroy? yes
Destroying (dev):

     Type                 Name             Status      
 -   pulumi:pulumi:Stack  ahoy-pulumi-dev  deleted     
 -   └─ aws:s3:Bucket     my-bucket        deleted     
 
Resources:
    - 2 deleted

Duration: 6s

Permalink: https://app.pulumi.com/jogannaoki/ahoy-pulumi/dev/updates/3

さいごに

「これ使って構築したい」という思いが溢れるツールPulumiの紹介でした。YAMLやJsonではなくプログラミング言語でインフラをコード化できるので、条件分岐などの細かな処理も記述することができ柔軟な運用ができそうです。CloudFormationやTerraformに辛さを感じてきた方は試してみてはいかがでしょうか。

参考