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

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

【ハンズオン】既存リソースのPulumi管理化

ハンズオンの流れ

今回は、AWS環境に既に作成されているS3 Bucketを、Pulumiで管理させるケースを想定して検証を実施します。Pulumi ProgramはPythonで作成します。作業は主にMacOSのターミナルを利用します。

前提

  • ハンズオンを実施する上で必要なAWSのアクセス権限を有する(S3 Bucket作成など)
  • PCにPythonを導入済み(version 3.7以上)

事前準備

Pulumiを利用したAWSリソースデプロイのハンズオンを実施するには、事前に以下の作業が実施済みである必要があります。前回で事前準備の手順を紹介していますので、まだ実施されていない方はそちらをご確認ください。

  • Pulumi CLIのインストール
  • Pulumiアカウント新規作成
  • AWSアカウントへのPulumiアクセス設定

今回は、以下の事前準備の手順を紹介します。

  • 既存リソース(S3 Bucket)の用意
  • Pulumi Project & Stack 新規作成

・既存リソース(S3 Bucket)の用意
Pulumi管理化のリソース(S3 Bucket)をあらかじめ手動で作成します。今回のハンズオンではAWSリージョン「ap-northeast-1」の「my-bucket-pulumi」という名前でS3 Bucketを作成しました。

・Pulumi Project & Stack 新規作成
既存リソースをPulumiで管理するためのPulumi ProjectとStackを作成します。

  1. 作業用ディレクトリ「pulumi-import」を新規で作成して、ディレクトリを移動します。
    1$ mkdir pulumi-import && cd pulumi-import
  2. 「pulumi new」コマンドを実行して、Program(Project)の雛形を作成します。「project name」「project description」「stack name」はデフォルト値で設定し、「aws:region:」については「ap-northeast-1」を設定しました。
    01$ pulumi new aws-python
    02 
    03This command will walk you through creating a new Pulumi project.
    04 
    05Enter a value or leave blank to accept the (default), and press <ENTER>.
    06Press ^C at any time to quit.
    07 
    08project name: (operator-test)
    09project description: (A minimal AWS Python Pulumi program)
    10Created project 'operator-test'
    11 
    12Please enter your desired stack name.
    13To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`).
    14stack name: (dev)
    15Created stack 'dev'
    16 
    17aws:region: The AWS region to deploy into: (us-east-1) ap-northeast-1
    18Saved config
    19 
    20Installing dependencies…
    21~~~
    22Your new project is ready to go! ✨
    23 
    24To perform an initial deployment, run `pulumi up`</stack-name></org-name>
  3. Stack作成直後はPulumiでリソースのデプロイは実施していないので、リソースに関する情報は記載されていないことを確認します。
    01$ pulumi stack export
    02 
    03{
    04    "version": 1,
    05    "deployment": {
    06        "manifest": {
    07            "time": "0001-01-01T00:00:00Z",
    08            "magic": "",
    09            "version": ""
    10        }
    11    }
    12}

Programにimport option(リソースID)を
付与しない場合のPulumi up

既にAWS環境に作成されているリソースについて、stateに情報が記載されていない状態でpulumi upを実施するとどうなるか確認します。

  1. 既存リソースの設定値(名前、ロケーションなど)に合わせて、Program(__main__.py)を編集します。
    1$ pwd
    2/***/pulumi-import
    3 
    4$ vi __main__.py
    以下コードに編集(__main__.py)
    1import pulumi
    2from pulumi_aws import s3
    3 
    4bucket = s3.Bucket('my-bucket-pulumi')
    5 
    6pulumi.export('bucket_name', bucket.id)
    【Pulumi Program (__main__.py)】
  2. pulumi upを実行します。
    01$ pulumi up
    02Previewing update (***/dev)
    03 
    04View in Browser (Ctrl+O): https://app.pulumi.com/***/pulumi-import/dev/previews/***
    05 
    06     Type                 Name               Plan      
    07 +   pulumi:pulumi:Stack  pulumi-import-dev  create    
    08 +   └─ aws:s3:Bucket     my-bucket-pulumi   create    
    09 
    10 
    11Outputs:
    12    bucket_name: output<string>
    13 
    14Resources:
    15    + 2 to create
    16 
    17Do you want to perform this update? yes
    18Updating (***/dev)
    19 
    20View in Browser (Ctrl+O): https://app.pulumi.com/***/pulumi-import/dev/updates/1
    21 
    22     Type                 Name               Status          
    23 +   pulumi:pulumi:Stack  pulumi-import-dev  created (4s)    
    24 +   └─ aws:s3:Bucket     my-bucket-pulumi   created (2s)    
    25 
    26 
    27Outputs:
    28    bucket_name: "my-bucket-pulumi-fcd164b"
    29 
    30Resources:
    31    + 2 created
    32 
    33Duration: 8s
  3. 上記pulumi upの実行結果の通り、stateにリソースの情報がないため、pulumiでは新しくリソースが作成(create)されてしまいます。pulumi up後のstateは以下のようになります。
    001$ pulumi stack export
    002{
    003    "version": 3,
    004    "deployment": {
    005        "manifest": {
    006            "time": "2023-09-28T16:01:51.629695+09:00",
    007            "magic": "1fce246d436c6e46d168db13ed1014131c96be0ccf8401639052718fba57ac37",
    008            "version": "v3.72.2"
    009        },
    010        "secrets_providers": {
    011            "type": "service",
    012            "state": {
    013                "url": "https://api.pulumi.com",
    014                "owner": "***",
    015                "project": "pulumi-import",
    016                "stack": "dev"
    017            }
    018        },
    019        "resources": [
    020            {
    021                "urn": "urn:pulumi:dev::pulumi-import::pulumi:pulumi:Stack::pulumi-import-dev",
    022                "custom": false,
    023                "type": "pulumi:pulumi:Stack",
    024                "outputs": {
    025                    "bucket_name": "my-bucket-pulumi-fcd164b"
    026                },
    027                "created": "2023-09-28T07:01:47.453547Z",
    028                "modified": "2023-09-28T07:01:47.453547Z"
    029            },
    030            {
    031                "urn": "urn:pulumi:dev::pulumi-import::pulumi:providers:aws::default_6_2_1",
    032                "custom": true,
    033                "id": "69044939-2182-498b-9919-b3a529f1ce10",
    034                "type": "pulumi:providers:aws",
    035                "inputs": {
    036                    "region": "ap-northeast-1",
    037                    "skipCredentialsValidation": "false",
    038                    "skipMetadataApiCheck": "true",
    039                    "skipRegionValidation": "true",
    040                    "version": "6.2.1"
    041                },
    042                "outputs": {
    043                    "region": "ap-northeast-1",
    044                    "skipCredentialsValidation": "false",
    045                    "skipMetadataApiCheck": "true",
    046                    "skipRegionValidation": "true",
    047                    "version": "6.2.1"
    048                },
    049                "created": "2023-09-28T07:01:49.057079Z",
    050                "modified": "2023-09-28T07:01:49.057079Z"
    051            },
    052            {
    053                "urn": "urn:pulumi:dev::pulumi-import::aws:s3/bucket:Bucket::my-bucket-pulumi",
    054                "custom": true,
    055                "id": "my-bucket-pulumi-fcd164b",
    056                "type": "aws:s3/bucket:Bucket",
    057                "inputs": {
    058                    "__defaults": [
    059                        "acl",
    060                        "bucket",
    061                        "forceDestroy"
    062                    ],
    063                    "acl": "private",
    064                    "bucket": "my-bucket-pulumi-fcd164b",
    065                    "forceDestroy": false
    066                },
    067                "outputs": {
    068                    "accelerationStatus": "",
    069                    "acl": "private",
    070                    "arn": "arn:aws:s3:::my-bucket-pulumi-fcd164b",
    071                    "bucket": "my-bucket-pulumi-fcd164b",
    072                    "bucketDomainName": "my-bucket-pulumi-fcd164b.s3.amazonaws.com",
    073                    "bucketRegionalDomainName": "my-bucket-pulumi-fcd164b.s3.ap-northeast-1.amazonaws.com",
    074                    "corsRules": [],
    075                    "forceDestroy": false,
    076                    "grants": [],
    077                    "hostedZoneId": "Z2M4EHUR26P7ZW",
    078                    "id": "my-bucket-pulumi-fcd164b",
    079                    "lifecycleRules": [],
    080                    "loggings": [],
    081                    "objectLockConfiguration": null,
    082                    "region": "ap-northeast-1",
    083                    "replicationConfiguration": null,
    084                    "requestPayer": "BucketOwner",
    085                    "serverSideEncryptionConfiguration": {
    086                        "rule": {
    087                            "applyServerSideEncryptionByDefault": {
    088                                "kmsMasterKeyId": "",
    089                                "sseAlgorithm": "AES256"
    090                            },
    091                            "bucketKeyEnabled": false
    092                        }
    093                    },
    094                    "versioning": {
    095                        "enabled": false,
    096                        "mfaDelete": false
    097                    },
    098                    "website": null
    099                },
    100                "parent": "urn:pulumi:dev::pulumi-import::pulumi:pulumi:Stack::pulumi-import-dev",
    101                "provider": "urn:pulumi:dev::pulumi-import::pulumi:providers:aws::default_6_2_1::69044939-2182-498b-9919-b3a529f1ce10",
    102                "additionalSecretOutputs": [
    103                    "tagsAll"
    104                ],
    105                "created": "2023-09-28T07:01:51.619949Z",
    106                "modified": "2023-09-28T07:01:51.619949Z"
    107            }
    108        ]
    109    }
    110}
  4. ここで一度作成されたbucketを削除して、元に状態に戻します。
    01$ pulumi destroy
    02         
    03Previewing destroy (***/dev)
    04 
    05View in Browser (Ctrl+O): https://app.pulumi.com/***/pulumi-import/dev/previews/***
    06 
    07     Type                 Name               Plan      
    08 -   pulumi:pulumi:Stack  pulumi-import-dev  delete    
    09 -   └─ aws:s3:Bucket     my-bucket-pulumi   delete    
    10 
    11 
    12Outputs:
    13  - bucket_name: "my-bucket-pulumi-fcd164b"
    14 
    15Resources:
    16    - 2 to delete
    17 
    18Do you want to perform this destroy? yes
    19Destroying (***/dev)
    20 
    21View in Browser (Ctrl+O): https://app.pulumi.com/***/pulumi-import/dev/updates/3
    22 
    23     Type                 Name               Status             
    24 -   pulumi:pulumi:Stack  pulumi-import-dev  deleted            
    25 -   └─ aws:s3:Bucket     my-bucket-pulumi   deleted (0.64s)    
    26 
    27 
    28Outputs:
    29  - bucket_name: "my-bucket-pulumi-fcd164b"
    30 
    31Resources:
    32    - 2 deleted
    33 
    34Duration: 3s
  5. リソースを削除すると、再度stateの中身からリソースの情報が削除されます。
    01$ pulumi stack export
    02    
    03{
    04    "version": 3,
    05    "deployment": {
    06        "manifest": {
    07            "time": "2023-09-28T16:51:21.248956+09:00",
    08            "magic": "1fce246d436c6e46d168db13ed1014131c96be0ccf8401639052718fba57ac37",
    09            "version": "v3.72.2"
    10        },
    11        "secrets_providers": {
    12            "type": "service",
    13            "state": {
    14                "url": "https://api.pulumi.com",
    15                "owner": "***",
    16                "project": "pulumi-import",
    17                "stack": "dev"
    18            }
    19        }
    20    }
    21}
著者
大関 研丞 (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メルマガ会員のサービス内容を見る

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