SecretもPulumiで使いこなしたい! PulumiのSecurityを試してみよう

2023年5月26日(金)
大関 研丞 (Kenneth Ozeki)
第4回となる今回は、PulumiのSecurityについて解説し、ハンズオンではPulumiによる暗号化処理を行い、AWS SecretManagerを利用したRDS接続する流れを実践していきます。

はじめに

前回は、実際にマルチステージ環境のStackを構築して、Stackの概要や活用のメリットについて解説していきました。今回は、第1回でも少し触れたPulumiのArchitectureをおさらいしつつ、PulumiにおけるSecurityについて解説していきます。

なお記事後半のハンズオンでは、Securityに関連してAWS RDS(MySQL)接続のための認証情報についてPulumiによる暗号化処理を行い、AWS SecretManagerを利用してセキュアにRDS接続する流れを実践していきます。

PulumiのArchitecture

Pulumiは大まかに2種類のArchitectureに分類されます。1つは前回のハンズオンまで利用してきた、Pulumi ServerがSaaSとして提供/管理される「Pulumi Service Architecture」と、もう1つはPulumi Serverを自前のインフラ環境に構築する「Self-Hosted Architecture」です。Pulumi Service Architectureは個人利用が無料のプラン(Individual)を含め全てのプランで選択できますが、Self-Hosted Architectureは「BusinessCritical」プランでのみ選択できます。Pulumiの利用プランについてはこちらを参照ください。

Pulumi Service(SaaS) Architecture

Pulumi Service Architecture(Pulumi Cloud)」は、Pulumiで作成したリソースの情報(state)やsecretの管理、監査ログ、CI/CDインテグレーションやアクセスコントロールなどの設定が可能で、SaaSとしてクラウド上で提供されます。個人利用が無料のプラン(Individual)を含め、全てのプランでPulumi Service Architectureを選択できます。「Pulumi Service」は2つのエンドポイント「api.pulumi.com」または「app.pulumi.com」にインターネット経由でアクセスでき、「pulumi up」コマンドなどのPulumi CLIによるアクセスとWebコンソール画面からのアクセスが可能です。

Pulumi Service Webコンソール画面

Pulumi Serviceの実体はAWSで管理されており、以下のArchitectureが組まれているので、世界各国からのアクセスに高可用性が維持されています。

  • Pulumi Serviceの静的コンテンツはcross-regionレプリケーションが有効化されたS3に保存されており、AWS CloudFront CDNにより配信される
  • Pulumi Serviceへのリクエスト処理はオートスケーリングされたAWS Elastic Compute Cloud(EC2)とElastic Container Service(ECS)の組み合わせにより処理される
  • Pulumi ServiceのデータベースはAmazon Relational Database Service(RDS)が利用され、automatic HA/automaticマルチゾーンスケール/インクリメンタルバックアップが実施されている

Pulumi Service Architecture
【引用】Pulumi公式ホームページより

Pulumi Self-Hosted Architecture

Self-Hosted Architecture」は、Pulumi Serviceが提供する同等の機能(Pulumi Server)を自前のインフラ環境に構築するArchitectureです。Self-Hosted ArchitectureでPulumi実行環境を構築する場合は、ユーザ自身でPulumi Serviceが実装しているデータバックアップや可用性の確保について検討する必要がありますが、Pulumiで発生する通信をすべて自前の環境内で完結(Intranet-Only)させることが可能なので、Pulumi Service Architectureよりも、よりセキュアなPulumi実行環境を実現できます。もちろん、インターネット経由でアクセスできるような独自のPulumi実行環境(Internet-Accessible)も構築可能です。ただし、Self-Hosted Architectureは「BusinessCritical」プランでのみ選択可能なので、インターネット通信が制限されるような、より厳格なセキュリティ要件を求められるシステムにおいて利用を検討すると良いでしょう(まずは30日間のトライアルライセンスでお試しいただくと良いかもしれません)。

Pulumi Self-Hosted Architecture
【引用】Pulumi公式ホームページより

自前のインフラ環境に構築するためのPulumiの機能(Frontend UIとBackend API)は、Dockerコンテナイメージとして提供されるので、以下のようなOCI互換性のある様々なサービスにホストできます。詳細は公式HPを参照ください。

  • クイックスタート用Docker Compose(Pulumiが提供するdocker-composeとbashスクリプトを利用したテスト用Pulumi環境の構築)
  • Amazon ECS(Elastic Container Service)
  • Amazon EKS(Elastic Kubernetes Service)
  • AKS(Azure Kubernetes Service)
  • GKE(Google Kubernetes Engine)
  • 自前のKubernetes
  • ローカルのDocker

PulumiのSecurity

PulumiではどのようなSecurityが考慮されているのか、またユーザ自身でどのようなSecurity対策を実施できるのかなど、公式が発表している「Pulumi Cloud Security Whitepaper」をベースに紹介します。

Pulumi側で実施されるSecurity対策

・Pulumi Service(SaaS) Security
前述したPulumiのArchitectureのうち、Pulumiの全プランで利用可能なPulumi Service Architecture(Pulumi Cloud)では、下図のようなSecurity対策が施されています。図の左側「Client」が「pulumi up」コマンドなどの「Pulumi CLI」を実行するユーザを指します。認証、通信の暗号化、データの暗号化、不要な通信の制限など、ひと通りのSecurity対策が実施されていることが分かります。

Pulumi Service ArchitectureのSecurity対策

  1. 全てのインターネット経由の通信(PulumiCLI↔Pulumi Service、Pulumi CLI↔管理対象のクラウドインフラ(Cloud APIs))はTLSで暗号化される
  2. Pulumi CLIを実行するPC(マシン)でPulumi Serviceとの認証と管理対象のクラウドインフラとの認証が実行される。管理対象のクラウドインフラとの認証情報はPulumi Serviceに共有されない
  3. Pulumi Serviceと管理対象のクラウドインフラとで直接通信は発生しない
  4. 顧客情報が含まれるデータは全て暗号化
  5. 外部からのアクセスを無効化。NIST(アメリカ国立標準技術研究所)制定の暗号化方式AES256を採用

その他のSecurity対策としては「Pulumi Serviceのサービスやアプリケーションに対する年1回のペネトレーションテスト」「SOC 2 Type 2フレームワークに準拠したセキュリティ活動」などが挙げられます。Pulumi ServiceはAWSにホストされているので、AWSが管理するITインフラストラクチャは、AWSの厳格なSecurity対策に基づき「SOC 1/SSAE16/ISAE 3402(formerly SAS 70)、SOC 2、SOC 3…」など(キリがないのですが)、数多くのITセキュリティスタンダードに準拠しています。

ユーザで実施可能なSecurity対策

Pulumiでは以下の機能が提供されており、ユーザの要件次第でSecurityを強化できます。

・Role Based Access Control
「PulumiTeam」「Enterprise」「BusinessCritical」プランで利用可能な「RoleBasedAccessControl(RBAC)」は、Pulumi Serviceを利用するチームにStackへのアクセス権限をコントロールする機能です。権限は以下の4種類に分類されます。

  • None→Stackに対するアクセス権限(read/write)を付与しない
  • Read-only→Stackに対するアクセス権限(read)を付与する
  • Read-write→Stackに対するアクセス権限(read/write)を付与する
  • Administrator→Stackに対する管理者権限を付与する

Pulumi Serviceのデフォルト設定では(2023年5月現在)、組織(Organization)レベルで全てのStackに対するRead-write権限が付与されており、組織に所属する全てのチームにそのRead-write権限が継承されています。さらに細かい単位(Stack単位)でチームに権限を設定することで組織レベルの権限設定をオーバーライドさせることもできます。

組織レベルでStackに対するRead-write権限がデフォルトで付与されている

チームレベルで個々のStackに対する権限を設定できる

・Secrets Management
前回でも紹介したように、Pulumiでデプロイするリソースの設定をStackで保持させたいケースがあります(AWS EC2のサイズやStack毎に異なる変数の値など)。その中でも、センシティブなデータ(DatabaseのパスワードやSaaSサービスのトークンなど)もStackで保持させたい場合、Stackの設定コマンド「pulumi config set」に「--secret」フラグを付与することでStack設定ファイルで保持するデータが暗号化されます。

$ pulumi config set my-password 123456
$ cat Pulumi.dev.yaml                 
config:
  test-project:my-password: "123456"
【Stack設定ファイルの暗号化されていないKey(my-password)】
$ pulumi config set my-password 123456 --secret
$ cat Pulumi.dev.yaml                          
config:
  test-project:my-password:
    secure: AAABAKPkoCCr1b2mP3S34TC7mj7ElYd2MixU8yYzs1+gQwwt0qg=
【Stack設定ファイルの暗号化されたKey(my-password)】

また、リソースデプロイ後はリソースの状態がStateファイルとして記録されますが、このStateファイルに記録されるセンシティブデータもPulumi Programで暗号化できます。

$ cat __main__.py    
import pulumi

config = pulumi.Config()
pulumi.export('my-password', config.get("my-password"))

—
$ pulumi stack export
~~(略)~~
        "resources": [
            {
                "urn": "urn:pulumi:dev::4-pulumi-security::pulumi:pulumi:Stack::4-pulumi-security-dev",
                "custom": false,
                "type": "pulumi:pulumi:Stack",
                "outputs": {
                    "my-password": "123456"
                }
            }
        ]
【Stack設定ファイルから取得したKeyをplaintextでデプロイ】
$ cat __main__.py 
import pulumi

config = pulumi.Config()
pulumi.export('my-password', config.require_secret("my-password"))

—
$ pulumi stack export
~~(略)~~
        "resources": [
            {
                "urn": "urn:pulumi:dev::4-pulumi-security::pulumi:pulumi:Stack::4-pulumi-security-dev",
                "custom": false,
                "type": "pulumi:pulumi:Stack",
                "outputs": {
                    "my-password": {
                        "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270",
                        "ciphertext": "AAABAKJxhTMcSzu7bH0/UqYgHb+FeXN0ERpVbuY/Tt9QQ0IlBGGwGQ=="
                    }
                }
            }
        ]
【Stack設定ファイルから取得したKeyをsecretとしてデプロイ】

暗号化の際に利用されるキーは、デフォルトでPulumi ServiceがホストされているAWSのKMS-basedの暗号化キー(AES256GCM)が利用されます。また、オプションとして暗号化の際に利用されるsecret providerもユーザ自身で以下より選択できます。

  • AWS KMS
  • Google Cloud KMS
  • Azure Key Vault
  • HashiCorp Vault
  • ユーザ自身が入力するパスフレーズを利用したPBKDF2によるsecret provider
$ pulumi stack init stg --secrets-provider passphrase
Enter your passphrase to protect config/secrets:
Re-enter your passphrase to confirm:
Created stack 'stg'
【ユーザ自身が入力するパスフレーズを利用したPBKDF2によるsecret provider】

・Pulumi CrossGuard
「Policy as Code」サービスとしてPulumiが提供する「Pulumi CrossGuard」を利用してPulumiでデプロイするリソースのコンプライアンスを強化し、結果的にSecurityを確保できます。また「Pulumi CrossGuard」を利用してユーザが所属する組織や会社のセキュリティコンプライアンスに沿ったポリシーを事前に定義することで、例えばSecurity要件に厳しい環境でPulumiによる「インターネット上で誰でも読み取り可能なAWS S3の作成」を事前にブロックできます。Pulumi CrossGuardの詳細は次回以降で紹介します。

$ pulumi preview --policy-pack ../policypack
Previewing update (dev)

View Live: https://app.pulumi.com/***/test-program/dev/previews/***

     Type                 Name              Plan       Info
 +   pulumi:pulumi:Stack  test-program-dev  create     1 error
 +   └─ aws:s3:Bucket     my-bucket         create     


Diagnostics:
  pulumi:pulumi:Stack (test-program-dev):
    error: preview failed

Policy Violations:
    [mandatory]  aws-python v0.0.1  s3-no-public-read (aws:s3/bucket:Bucket: my-bucket)
    Prohibits setting the publicRead or publicReadWrite permission on AWS S3 buckets.
    You cannot set public-read or public-read-write on an S3 bucket. Read more about ACLs here: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html
【ポリシーによりインターネット公開でread-write可能なS3の作成がブロックされた様子】
著者
大関 研丞 (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メルマガ会員のサービス内容を見る

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