PulumiでAWSリソースをデプロイしよう

2023年3月15日(水)
大関 研丞 (Kenneth Ozeki)
第2回となる今回は、Pulumiのアカウント作成からAWSリソースの作成まで、ハンズオンを通して一通り実践していきます。

Pulumi Stackデプロイ

早速、デフォルトのProgramの状態でStackをデプロイ(リソース作成)します。デフォルトのProgramでは、名称が「my-bucket」となるS3 Bucketのリソース作成と、Bucket名をStack outputとしてexportするサンプルコードになっています。

$ cat __main__.py 
"""An AWS Python Pulumi program"""

import pulumi
from pulumi_aws import s3

# Create an AWS resource (S3 Bucket)
bucket = s3.Bucket('my-bucket')

# Export the name of the bucket
pulumi.export('bucket_name', bucket.id)
  1. 「pulumi up」コマンドを実行します。コマンドを実行すると、作成するリソースやその数、outputが表示されます。今回は初めてStackを作成するので、StackとS3 Bucketの2つのリソースが作成されます。outputはリソース数にカウントされません。特に引数を指定しない場合は「yes/no/details/Update Plans」のいずれかを選択するプロンプトも表示されます。
    $ pulumi up
    Previewing update (dev)
    
    View Live: https://app.pulumi.com/*****/pulumi-test/dev/previews/*****
    
         Type                 Name             Plan       
     +   pulumi:pulumi:Stack  pulumi-test-dev  create     
     +   └─ aws:s3:Bucket     my-bucket        create     
    
    
    Outputs:
        bucket_name: output
    
    Resources:
        + 2 to create
    
    Do you want to perform this update?  [Use arrows to move, type to filter]
      yes
    > no
      details
      [experimental] yes, using Update Plans (https://pulumi.com/updateplans)
  2. ここで「details」を選択すると、作成するリソースの詳細が表示されます。また、リソースのURN(Uniform Resource Name)も確認できます。PulumiにおけるURNでは「pulumi up –target <URN>」コマンドを用いた特定リソースのみの更新や、「pulumi state delete <URN>」によるStateからの特定リソースの削除などで利用するケースがあります。
    Do you want to perform this update? details
    + pulumi:pulumi:Stack: (create)
        [urn=urn:pulumi:dev::pulumi-test::pulumi:pulumi:Stack::pulumi-test-dev]
        + aws:s3/bucket:Bucket: (create)
            [urn=urn:pulumi:dev::pulumi-test::aws:s3/bucket:Bucket::my-bucket]
            [provider=urn:pulumi:dev::pulumi-test::pulumi:providers:aws::default_5_29_1::04da6b54-80e4-46f7-96ec-b56ff0331ba9]
            acl         : "private"
            bucket      : "my-bucket-ca3f987"
            forceDestroy: false
        --outputs:--
        bucket_name: output<string>
    
    Do you want to perform this update?  [Use arrows to move, type to filter]
      yes
    > no
      details
      [experimental] yes, using Update Plans (https://pulumi.com/updateplans)
    【参考】Update Plans
    (2023年2月9日現在)プロンプトの「[experimental] yes, using Update Plans」は、Pulumi v3.47.2(2022年11月22日)より追加されたUpdate plans機能で、現在はプレビュー版です。「pulumi up」によるアップデート内容(Plan)を実行する前にファイルへ保存しておき、実際にアップデートする際に保存したファイルを指定すると、ファイルに記載された処理からは逸脱しないようにアップデートが実行されるようになります。アップデート内容の(Plan)確認には「pulumi preview」コマンドが利用されます。
    $ pulumi preview --save-plan=plan.json
    Previewing update (dev)
    
    View Live: https://app.pulumi.com/*****/pulumi-test/dev/previews/*****
    
         Type                 Name             Plan       
     +   pulumi:pulumi:Stack  pulumi-test-dev  create     
     +   └─ aws:s3:Bucket     my-bucket        create     
    
    
    Outputs:
        bucket_name: output<string>
    
    Resources:
        + 2 to create
    
    Update plan written to 'plan.json'
    Run `pulumi up --plan='plan.json'` to constrain the update to the operations planned by this preview
    
    $ pulumi up --plan='plan.json'        
    Previewing update (dev)
    
    View Live: https://app.pulumi.com/*****/pulumi-test/dev/previews/*****
    
         Type                 Name             Plan       Info
     +   pulumi:pulumi:Stack  pulumi-test-dev  create     
         └─ aws:s3:Bucket     dummy-my-bucket             1 error
    
    
    Diagnostics:
      aws:s3:Bucket (dummy-my-bucket):
        error: create is not allowed by the plan: no steps were expected for this resource
    【Plan内容から逸脱したアップデートを実行した際の様子】
  3. リソースの作成内容に問題がなければ、「yes」を選択するとリソースが作成されます。AWSマネジメントコンソールからもリソースが作成されていることを確認できます。
    Do you want to perform this update? yes
    Updating (dev)
    
    View Live: https://app.pulumi.com/*****/pulumi-test/dev/updates/**
    
         Type                 Name             Status           
     +   pulumi:pulumi:Stack  pulumi-test-dev  created (3s)     
     +   └─ aws:s3:Bucket     my-bucket        created (1s)     
    
    
    Outputs:
        bucket_name: "my-bucket-c4e1d9c"
    
    Resources:
        + 2 created
    
    Duration: 4s

    pulumi upにより作成されたS3 Bucket

    リソースを作成した時点で、再度Pulumi Service画面のStack詳細画面、[Activity]タグからは作成時の履歴が、[Resources]タグからは現在Pulumiで管理しているリソースの一覧が確認できます。

    Pulumi Service Stack Activity(リソース作成履歴)画面

    Pulumi Service Stack Resources(リソース一覧)画面

    【参考】Stateの更新確認
    Pulumiは、インフラのあるべき姿(Program)と、今までのリソース状態を記録したファイル(State)を「pulumi up」実行時に比較し、インフラ更新時のアクション(作成/更新/削除)を決定します。「pulumi up」が完了すると、完了時点のインフラの状態がStateに反映されます。Stateの中身は「pulumi stack export」コマンドで確認できます。
    $ pulumi stack export
    
    {
        "version": 3,
        "deployment": {
            "manifest": {
                "time": "2023-02-09T17:45:14.947799+09:00",
                "magic": "375b9a4575c488972efc376a5a54ab60c43297fcce335704037cb8c668a4c864",
                "version": "v3.53.1"
            },
            "secrets_providers": {
    〜〜(略)〜〜
           "resources": [
                {
                    "urn": "urn:pulumi:dev::pulumi-test::pulumi:pulumi:Stack::pulumi-test-dev",
                    "custom": false,
                    "type": "pulumi:pulumi:Stack",
                    "outputs": {
                        "bucket_name": "my-bucket-c4e1d9c"
                    }
                },
    〜〜(略)〜〜
    【参考】Auto-naming
    「pulumi up」で作成されたbucket名「my-bucket-c4e1d9c」について、suffixに付与されている文字列はpulumiのAuto-naming処理により自動的に付与されているランダムの16進数になります。Auto-namingの目的は主に2つです。
    • 同じPulumi Projectで複数Stackを作成する際の、同一リソースのリソース名の衝突(重複)を防ぐため
    • 一部のクラウドプロバイダにおけるPulumiのゼロダウンタイムでのリソース更新を行うため。一部のクラウドプロバイダではリソース更新時に「更新後の設定値でリソースを新規作成して作成後に参照先を新規作成したリソースに変更し、その後古いリソースを削除する」プロセスでリソース更新が行われるため、一時的に同じリソースが2つ作成される際のリソース名の衝突(重複)を防ぐ必要がある
    作成するリソースに「name」プロパティなどを付与して、Auto-naming処理をさせずにリソース名を指定することも可能です。ただし上記の通り、リソース名重複によるエラーがたびたび発生し得るため、Auto-naming処理を実施させるか、または似たような処理としてProject名とStack名をリソース名に含め、リソースに「deleteBeforeReplace: true」プロパティ(リソース更新時先に古いリソースが削除されるプロパティ)を追加するなど、リソース名重複への対策について考慮する必要があります。
    role = iam.Role('my-role', {
        name='my-role-001'
    })
    【nameプロパティ指定によるAuto-namig無効化(Python)】
  4. role = iam.Role('my-role', {
        name=f'my-role-{ pulumi.get_project() }-{ pulumi.get_stack() }')
    }, opts=ResourceOptions(delete_before_replace=True))
    【Project名/Stack名をnameプロパティで指定&delete_before_replace=Trueを付与】
著者
大関 研丞 (Kenneth Ozeki)
クリエーションライン株式会社 Data Platform Team
前職では保険や金融エンタープライズのミッションクリティカルシステム(オンプレミス、仮想サーバー、CDN等のインフラ系業務)の設計/構築を経験。クリエーションラインに転職後はクラウドエンジニアとしてGCP関連の案件でインフラの設計/構築、IaCやCI/CDを用いたDevOpsの導入、コンテナ(Kubernetes)基盤の構築、運用自動化ツールの作成などを担当。
クリエーションラインの技術ブログをチェック

連載バックナンバー

システム運用技術解説
第10回

Pulumiの最新機能「Pulumi ESC」を使ってみよう

2023/12/26
最終回となる今回は、2023年12月時点でリリースされている新機能の紹介と、その新機能の中から「Pulumi ESC」を用いたハンズオンを実践していきます。
システム運用技術解説
第9回

TerraformからPulumiへの移行

2023/11/28
第9回となる今回は、既にTerraformでAWS環境に作成されているリソースをPulumiへ移行するケースを想定して、CoexistenceとConversionのハンズオンを実践していきます
システム運用技術解説
第8回

既に存在するリソースをPulumiで管理してみよう

2023/10/19
第8回となる今回は、既にクラウド環境にデプロイされているリソースをPulumiで管理(import)する方法について、ハンズオンで実践していきます。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています