どっちのYAMLで書く?Pulumi と CloudFormation で簡易的なネットワークを構成してみた

2022.06.24

こんにちは、AWSコンサルティング部の森田です。

先日PulumiがYAMLに対応するアップデートがありました。

Pulumiがアップデート。 Java,YAML言語に対応しました。

ここで私はふと疑問に思いました。

AWSが提供しているIaCツールCloudFormationも同じYAMLでの記述ができるため、YAMLで書きたいならCloudFormationでいいのではと。

そこで、実際にPulumiとCloudFormationそれぞれで同様の簡易的なネットワークを構成し、両者の違いを見てみます。

作成するネットワーク

以下のようなシンプルなネットワークを構成してみます。

やってみる

CloudFormation

以下のYAMLファイルを作成します。

Description: A minimal AWS CloudFormation YAML program
Parameters:
  prjName:
    Type: String
Resources: 
  VPC: 
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags: 
        - Key: Name
          Value: !Sub ${prjName}-vpc
  PublicSubnet1a:
    Type: AWS::EC2::Subnet
    Properties: 
      AvailabilityZone: ap-northeast-1a
      CidrBlock:  10.0.1.0/24
      VpcId: !Ref VPC
      Tags: 
        - Key: Name
          Value: !Sub ${prjName}-public-subnet-1a
  PrivateSubnet1c:
    Type: AWS::EC2::Subnet
    Properties: 
      AvailabilityZone: ap-northeast-1c
      CidrBlock:  10.0.2.0/24
      VpcId: !Ref VPC
      Tags: 
        - Key: Name
          Value: !Sub ${prjName}-private-subnet-1c
  IGW: 
    Type: AWS::EC2::InternetGateway
    Properties: 
      Tags: 
        - Key: Name
          Value: !Sub ${prjName}-igw
  IGWAttach: 
    Type: AWS::EC2::VPCGatewayAttachment
    Properties: 
      InternetGatewayId: !Ref IGW
      VpcId: !Ref VPC 
  Routetable:
    Type: AWS::EC2::RouteTable
    Properties: 
      VpcId: !Ref VPC
      Tags: 
        - Key: Name
          Value: !Sub ${prjName}-ryb
  PublicSubnetARouteTableAssociation: 
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties: 
      SubnetId: !Ref PublicSubnet1a
      RouteTableId: !Ref Routetable

ファイル作成後、AWSコンソールからCloudFormationのスタック作成を行います。スタック作成時には、パラメータの入力が求められます。 しばらく待つと、リソースの作成が完了します。

Pulumi

Pulumiでは、以下のコマンドを実行し、プロジェクトの作成から行います。

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

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) ap-northeast-1
Saved config

Your new project is ready to go! ✨

To perform an initial deployment, run 'pulumi up'

上記コマンドの実行が完了するとPulumi.yamlPulumi.dev.yamlのファイルが作成されております。 Pulumi.yamlについてはAWSリソースを定義するファイルとなっております。 ファイルの中身を以下のように書き換えます。

Pulumi.yaml

name: minimalNW
runtime: yaml
description: A minimal AWS Pulumi YAML program
configuration:
  prjName:
    type: String
resources:
  VPC:
    type: aws:ec2:Vpc
    properties:
      cidrBlock: 10.0.0.0/16
      tags:
        Name: ${prjName}-vpc
  PublicSubnet1a:
    type: aws:ec2:Subnet
    properties:
      vpcId: ${VPC.id}
      cidrBlock: 10.0.1.0/24
      availabilityZone: ap-northeast-1a
      tags:
        Name: ${prjName}-public-subnet-1a
  PrivateSubnet1c:
    type: aws:ec2:Subnet
    properties:
      vpcId: ${VPC.id}
      cidrBlock: 10.0.2.0/24
      availabilityZone: ap-northeast-1c
      tags:
        Name: ${prjName}-private-subnet-1c
  IGW:
    type: aws:ec2:InternetGateway
    properties:
      vpcId: ${VPC.id}
      tags:
        Name: ${prjName}-igw
  Routetable:
    type: aws:ec2:RouteTable
    properties:
      vpcId: ${VPC.id}
      routes:
        - cidrBlock: 0.0.0.0/0
          gatewayId: ${IGW.id}
      tags:
        Name: ${prjName}-rtb
  RoutetableAssociation:
    type: aws:ec2:RouteTableAssociation
    properties:
      subnetId: ${PublicSubnet1a.id}
      routeTableId: ${Routetable.id}

続いて、Pulumi.dev.yamlですが、こちらでは、環境変数などを記述するファイルとなっております。 ファイルに直接記述することもできますが、以下のようにコマンドでも設定可能です。

使用する AWS CLI の Profileを設定する

$ pulumi config set aws:profile プロファイル名

パラメータの設定

$ pulumi config set prjName pulumi-dev-test

最後に、作成したリソースを以下のコマンドでデプロイします。

$ pulumi up
Previewing update (dev)

View Live: https://app.pulumi.com/**************

     Type                              Name                   Plan
 +   pulumi:pulumi:Stack               minimalNW-dev          create
 +   ├─ aws:ec2:Vpc                    VPC                    create
 +   ├─ aws:ec2:InternetGateway        IGW                    create
 +   ├─ aws:ec2:Subnet                 PrivateSubnet1c        create
 +   ├─ aws:ec2:Subnet                 PublicSubnet1a         create
 +   ├─ aws:ec2:RouteTable             Routetable             create
 +   └─ aws:ec2:RouteTableAssociation  RoutetableAssociation  create

Resources:
    + 7 to create

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

View Live: https://app.pulumi.com/**************

     Type                              Name                   Status
 +   pulumi:pulumi:Stack               minimalNW-dev          created
 +   ├─ aws:ec2:Vpc                    VPC                    created
 +   ├─ aws:ec2:InternetGateway        IGW                    created
 +   ├─ aws:ec2:Subnet                 PrivateSubnet1c        created
 +   ├─ aws:ec2:Subnet                 PublicSubnet1a         created
 +   ├─ aws:ec2:RouteTable             Routetable             created
 +   └─ aws:ec2:RouteTableAssociation  RoutetableAssociation  created

Resources:
    + 7 created

Duration: 8s

Pulumiのコンソールからスタックの確認を行います。

見えてきたそれぞれのメリット

実際に試してみた結果、以下のように感じました。

  • CloudFormation
    • 慣れ親しんだ書き方で迷うことはないが、コード量がやや長くなりがち
    • 基本的にローカル環境での環境構築は不要
    • AWSマネジメントコンソールからスタックの確認が行える
  • Pulumi
    • CloudFormationよりコードの量が短くなる場合がある
    • ローカル環境での環境構築が必要
    • Pulumiのコンソールでスタックの確認が行える

両者ともメリットがあり、結局どちらを使用するかは好みだと感じました。

まとめ

個人的には、PulumiでIaCするならば、できるならTypeScriptなどプログラミング言語で記述した方が良いと思いました。

YAMLで記述してしまうと、プログラミング言語を使用するメリット(型推論や繰り返しなどの処理)が活用できなくなってしまいます。

一方で、Pulumi触ったことない方でも、YAMLであれば非常に簡単に始めることができるので、とりあえずPulumi触ってみたい方にはおすすめです!

参考資料