TerraformからPulumiへの移行

2023年11月28日(火)
大関 研丞 (Kenneth Ozeki)
第9回となる今回は、既にTerraformでAWS環境に作成されているリソースをPulumiへ移行するケースを想定して、CoexistenceとConversionのハンズオンを実践していきます

はじめに

前回は、既にクラウド環境にデプロイされているリソースのPulumi管理化(import)について解説しました。今回は、既存リソースのPulumi管理化(import)に関連して、既存リソースが既に他のIaCツールで管理されている場合の、Pulumiへの移行手順について紹介します。

Pulumiにおける他のIaCツールから移行概要

既に他のIaCツール(TerraformやAWS CloudFormationなど)を利用しているケースで、Pulumiへの移行を検討する際に、Pulumiでは以下3つのコンセプトに着目して、それぞれにおいて移行のための手段を提供しています。

  • Coexistence (Pulumiと他のIaCツールとの共存)
    既存インフラの他のIaCツールによる管理はしばらく続けつつ、新しく作成されるインフラについてはPulumiで作成していくようなケースを、Pulumiでは「Coexistence (Pulumiと他のIaCツールとの共存)」と定義しています。他のIaCツールとPulumiを共存させることでPulumiから他のIaCツールのStateファイル(既存リソースの情報)にアクセスして、例えばAWS VPCIDやSubnetのIPアドレス、EC2のAMI IDなどの既存リソースの情報を読み込んでPulumiで新たに作成するリソースでそれらの情報を利用できます。「Coexistence」が必要な事情は色々と考えられますが、例えば「別のチームがまだしばらく他のIaCツールを使い続ける」場合や「既存リソースは他のIaCツールで管理しているがプロジェクトが終わったら削除する予定なので、わざわざPulumiに移行するメリットが薄い」などの事情が考えられます。
  • Conversion (コード変換)
    他のIaCツールからPulumiへの移行アプローチとして、他のIaCツールでコード化した既存インフラストラクチャのプログラムをPulumiのProgram(コード)に変換する作業があります。このコード変換作業について、PulumiではPulumi CLIのコマンドが用意されています。
  • Importing (Pulumi管理化)
    既存のインフラをPulumi管理化に置く作業をimportと定義しています。前回でimportについて詳しく解説していますが、手動で作成されたリソースでも、他のIaCツールで作成されたリソースでもPulumiでimport処理を実施することで、すべてPulumiのリソースとして管理できます。

また、Pulumi以外の代表的なIaCツールとしてTerraformやAWS CloudFormationなどが存在しますが、この3つのコンセプトのうち「Coexistence」と「Importing」は、例に挙げた代表的なIaCツール含め、すべてのIaCツールで実現可能となっています。ただし、下表のように既存インフラストラクチャのコードをPulumi Programに変換する「Conversion」については、Terraform、AWS CloudFormation、Azure ARM、Kubernetes YAMLでのみ実現可能となります(2023/11現在)。

【Pulumi Programへのコード変換は主要な表内4ツールのみ可能(公式HPより)】

【ハンズオン】Terraformで作成された
リソースのPulumiへの移行(Coexistence/Conversion)

ハンズオンの流れ

今回は、Pulumi以外の代表的なIaCツールとしてTerraformを取り上げ、既にTerraformでAWS環境に作成されているリソースをPulumiへ移行するケースを想定して、CoexistenceとConversionのハンズオンを実施します。本来の移行の流れとしては、Importまで実施した時点で無事にPulumiへの移行は完全に完了しますが、Importについては前回に解説した方法で実施できますので、ここでは割愛します。ハンズオンでは準備段階としてTerraformによるリソースデプロイも手順に含まれます。Pulumi ProgramはPythonで作成します。作業は主にMacOSのターミナルを利用します。

前提

  • ハンズオンを実施する上で必要なAWSのアクセス権限を有する(S3 Bucket / Bucket Object作成など)
  • PCにPythonを導入済み(version 3.7以上)
  • Terraform CLIをインストール済み(筆者の環境ではversion 1.6.4を使用)

事前準備

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

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

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

  • Terraformによるリソースデプロイ

Terraformによるリソースデプロイ

Pulumiへの移行の前準備として、TerraformでS3 BucketをAWS環境に作成します。Terraformを実行するためのAWSへの認証情報の設定は、事前準備の「AWSアカウントへのPulumiアクセス設定」で既に実施している想定なので、今回のハンズオンでは割愛します。Terraformのstateファイルはローカル環境に用意します。

  1. 作業用ディレクトリ「terraform-aws-s3」を新規で作成して、ディレクトリを移動します。
    $ mkdir terraform-aws-s3 && cd terraform-aws-s3
  2. terraformファイルを作成してリソースを定義します。
    $ vi main.tf
    以下のコードを記載します。bucket名が一意となるため、suffixにランダムの文字列を付与するリソース「random_string」も作成します。最後に、Pulumi Programに渡す情報としてbucket_idをoutput値として設定します。
    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 4.16"
        }
      }
      required_version = ">= 1.2.0"
    }
    
    provider "aws" {
      region  = "ap-northeast-1"
    }
    
    resource "random_string" "bucket_suffix" {
      length = 8
      special = false
      upper = false
    }
    
    resource "aws_s3_bucket" "tf_s3_bucket" {
      bucket = "tf-bucket-${random_string.bucket_suffix.result}"
      tags = {
        Name = "terraform-s3-bucket"
      }
    }
    
    output "bucket_id" {
        value = aws_s3_bucket.tf_s3_bucket.id
    }
    【Terraform file (main.tf)】
  3. ディレクトリを初期化して、AWSプロバイダーをダウンロードします。
    $ terraform init        
    ~~~
    Initializing the backend...
    
    Initializing provider plugins...
    - Reusing previous version of hashicorp/aws from the dependency lock file
    - Finding latest version of hashicorp/random...
    - Using previously-installed hashicorp/aws v4.67.0
    - Installing hashicorp/random v3.5.1...
    - Installed hashicorp/random v3.5.1 (signed by HashiCorp)
    ~~(中略)~~
    If you ever set or change modules or backend configuration for Terraform,
    rerun this command to reinitialize your working directory. If you forget, other
    commands will detect it and remind you to do so if necessary.
  4. 準備が整ったので、Terraformでリソースをデプロイします。コマンド実行後「yes」を入力します。
    $ terraform apply
    ~~~
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      + create
    
    Terraform will perform the following actions:
    
      # aws_s3_bucket.tf_s3_bucket will be created
      + resource "aws_s3_bucket" "tf_s3_bucket" {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = false
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = {
              + "Name" = "terraform-s3-bucket"
            }
          + tags_all                    = {
              + "Name" = "terraform-s3-bucket"
            }
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        }
    
      # random_string.bucket_suffix will be created
      + resource "random_string" "bucket_suffix" {
          + id          = (known after apply)
          + length      = 8
          + lower       = true
          + min_lower   = 0
          + min_numeric = 0
          + min_special = 0
          + min_upper   = 0
          + number      = true
          + numeric     = true
          + result      = (known after apply)
          + special     = false
          + upper       = false
        }
    
    Plan: 2 to add, 0 to change, 0 to destroy.
    
    Changes to Outputs:
      + bucket_id = (known after apply)
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    random_string.bucket_suffix: Creating...
    random_string.bucket_suffix: Creation complete after 0s [id=8o8ezl7s]
    aws_s3_bucket.tf_s3_bucket: Creating...
    aws_s3_bucket.tf_s3_bucket: Creation complete after 2s [id=tf-bucket-8o8ezl7s]
    
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    bucket_id = "tf-bucket-8o8ezl7s"
    terraform apply後は、AWSマネジメントコンソールで該当のS3 Bucketが作成されていることが確認できます。

著者
大関 研丞 (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メルマガ会員のサービス内容を見る

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