このチュートリアルでは、既存サイトを Cloudflare に取り込む手順を、Pulumi のインフラストラクチャ as Code(IaC)で進め、リソース管理のライフサイクルを把握します。具体的には、Zone(ゾーン)と DNS レコードを作成し、追加したサイトを解決できるようにします。手順は サイトを追加するチュートリアル と同じ内容を、IaC の原則で実施します。
次を用意してください。
- このチュートリアルのリソースを編集できる権限を持つ Cloudflare アカウントと API トークン。まだの場合は、先に Cloudflare アカウント ↗ に登録します。トークンには次が必要です。
Zone-Zone-Edit権限Zone-DNS-Edit権限include-All zones from an account-<your account>ゾーンリソース
- Pulumi Cloud アカウント。常時無料の個人プラン ↗ に登録できます。
- マシンに Pulumi CLI がインストールされていること。
- Pulumi が対応するプログラミング言語 ↗ が設定されていること(TypeScript、JavaScript、Python、Go、.NET、Java、または YAML)。
- ドメイン名。チュートリアルでは
example.comを使えます。
Pulumi プロジェクトは、作成したいインフラを記述する専用フォルダー内のファイル群です。Pulumi プロジェクトフォルダーは、必須の Pulumi.yaml ファイルで識別します。新しいプロジェクトの作成と設定には Pulumi CLI を使います。
このチュートリアルでは、空の新しいディレクトリを使います。
mkdir addsite-cloudflare
cd addsite-cloudflarePulumi Cloud ↗ は、インフラストラクチャ as Code を管理するための安全でスケーラブルなホスト型サービスです。Pulumi のバックエンド設定の保存に使います。
プロンプトで Enter を押すと、ブラウザー経由で Pulumi Cloud アカウントにログインします。Pulumi Cloud のアクセストークン ↗ を渡すこともできます。
pulumi loginPulumi プログラムは、対応言語 ↗ で書いた、インフラリソースを定義するコードです。
プログラムを作成するには、使う言語を選び、pulumi コマンドを実行します。
pulumi new javascript --name addsite-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new typescript --name addsite-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new python --name addsite-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new go --name addsite-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new java --name addsite-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new csharp --name addsite-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new yaml --name addsite-cloudflare --yesPulumi の スタック ↗ は、Pulumi プログラムのインスタンスです。スタックは独立して設定でき、異なる環境(開発、ステージング、本番)や機能ブランチを表せます。このチュートリアルでは dev スタックを使います。
dev スタックを作成するには、次を実行します。
pulumi up --yes
# wait a few seconds for the stack to be instantiated.この時点ではリソースを定義していないため、空のスタックになります。
この手順では、設定とシークレットを含む YAML ファイルである Pulumi ESC Environment ↗ に設定を保存します。Pulumi プログラムを含む複数の方法でアクセスできます。ESC Environment はすべて Pulumi Cloud アカウントに安全に保存され、Pulumi CLI で管理できます。このチュートリアルでは次の値を保存します。
# Define an ESC Environment name
E=cloudflare/my-dev-env
# Create a new Pulumi ESC Environment
pulumi config env init --env $E --yesCreating environment cloudflare/my-dev-env for stack dev...# Replace abc123 with your Cloudflare Account ID
pulumi env set $E --plaintext pulumiConfig.accountId abc123
# Replace API_TOKEN with your Cloudflare API Token
pulumi env set $E --secret pulumiConfig.cloudflare:apiToken API_TOKEN
# Replace example.com with your registered domain, or leave as is
pulumi env set $E --plaintext pulumiConfig.domain example.comPulumi プログラムで Cloudflare リソースを定義するには、使う言語向けの Cloudflare パッケージをインストールする必要があります。
次のコマンドで Cloudflare パッケージをインストールします。
npm install @pulumi/cloudflareadded 1 package ...npm install @pulumi/cloudflareadded 1 package ...echo "pulumi_cloudflare>=5.38,<6.0.0" >> requirements.txt
source venv/bin/activate
pip install -r requirements.txt...Collecting pulumi-cloudflare...go get github.com/pulumi/pulumi-cloudflare/sdk/v3/go/cloudflarego: downloading github.com/pulumi/pulumi-cloudflare ...以下は Apache Maven の手順です。Gradle など他の Java プロジェクトマネージャーについては、公式の Maven repository ↗ を参照してください。
pom.xmlファイルを開きます。<dependencies>セクション内に Pulumi Cloudflare の依存関係を追加します。
<dependency>
<groupId>com.pulumi</groupId>
<artifactId>cloudflare</artifactId>
<version>5.38.0</version>
</dependency>- 次を実行します。
mvn clean install...[INFO] BUILD SUCCESS...dotnet add package Pulumi.Cloudflare...
info : Adding PackageReference for package 'Pulumi.Cloudflare' into project
...YAML ではダウンロードする依存関係はありません。次に進んでください。
Cloudflare パッケージをインストールしたら、Pulumi プログラムで 対応する任意の Cloudflare リソース ↗ を定義できます。次に Zone と DNS レコードを定義します。
Cloudflare では、ドメイン(サイト)を Zone(ゾーン)と呼びます。Pulumi では、Zone リソース ↗ が Cloudflare Zone を表します。
エントリポイントファイルの内容を、次に置き換えます。
ファイル名: index.js
"use strict";
const pulumi = require("@pulumi/pulumi");
const cloudflare = require("@pulumi/cloudflare");
const config = new pulumi.Config();
const accountId = config.require("accountId");
const domain = config.require("domain");
// Create a Cloudflare resource (Zone)
const zone = new cloudflare.Zone("my-zone", {
zone: domain,
accountId: accountId,
plan: "free",
jumpStart: true,
});
exports.zoneId = zone.id;
exports.nameservers = zone.nameServers;
exports.status = zone.status;ファイル名: index.ts
import * as pulumi from "@pulumi/pulumi";
import * as cloudflare from "@pulumi/cloudflare";
const config = new pulumi.Config();
const accountId = config.require("accountId");
const domain = config.require("domain");
// Create a Cloudflare resource (Zone)
const zone = new cloudflare.Zone("my-zone", {
zone: domain,
accountId: accountId,
plan: "free",
jumpStart: true,
});
export const zoneId = zone.id;
export const nameservers = zone.nameServers;
export const status = zone.status;ファイル名: __main__.py
import pulumi
import pulumi_cloudflare as cloudflare
account_id = pulumi.Config().require("accountId")
domain = pulumi.Config().require("domain")
# Create a Cloudflare resource (Zone)
zone = cloudflare.Zone("my-zone",
zone=domain,
account_id=account_id,
plan="free",
jump_start=True)
pulumi.export("zoneId", zone.id)
pulumi.export('nameservers', zone.name_servers)
pulumi.export('status', zone.status)ファイル名: main.go
package main
import (
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
cloudflare "github.com/pulumi/pulumi-cloudflare/sdk/v3/go/cloudflare"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
domain, _ := ctx.GetConfig("domain")
// Create a Cloudflare resource (Zone)
zone, err := cloudflare.NewZone(ctx, "my-zone", &cloudflare.ZoneArgs{
Zone: pulumi.String(domain),
Plan: pulumi.String("free"),
JumpStart: pulumi.Bool(true),
})
if err != nil {
return err
}
ctx.Export("zoneId", zone.ID())
ctx.Export("nameservers", zone.NameServers)
ctx.Export("status", zone.Status)
return nil
})
}ファイル名: src/main/java/myproject/App.java
package myproject;
import com.pulumi.Pulumi;
import com.pulumi.Context;
import com.pulumi.cloudflare.ZoneArgs;
import com.pulumi.cloudflare.Zone;
public class App {
public static void main(String[] args) {
Pulumi.run(ctx -> {
var config = ctx.config();
String accountId = config.require("accountId");
String domain = config.require("domain");
var zone = new Zone("my-zone", ZoneArgs.builder()
.zone(domain)
.accountId(accountId)
.plan("free")
.jumpStart(true)
.build());
ctx.export("zoneId", zone.id());
ctx.export("nameservers", zone.nameServers());
ctx.export("status", zone.status());
});
}
}ファイル名: Program.cs
using System.Threading.Tasks;
using System.Collections.Immutable;
using Pulumi;
using Pulumi.Cloudflare;
class Program
{
static Task<int> Main() => Deployment.RunAsync<MyStack>();
class MyStack : Stack
{
public MyStack()
{
var config = new Pulumi.Config();
var accountId = config.Require("accountId");
var domain = config.Require("domain");
var zone = new Zone("my-zone", new ZoneArgs
{
ZoneName = domain,
AccountId = accountId,
Plan = "free",
JumpStart = true
});
this.ZoneId = zone.Id;
this.Nameservers = zone.NameServers;
this.Status = zone.Status;
}
[Output]
public Output<string> ZoneId { get; set; }
public Output<ImmutableArray<string>> Nameservers { get; set; }
public Output<string> Status { get; set; }
}
}ファイル名: Pulumi.yaml
name: addsite-cloudflare
runtime: yaml
resources:
myZone:
type: cloudflare:Zone
properties:
zone: ${domain}
accountId: ${accountId}
plan: "free"
jumpStart: true
outputs:
zoneId: ${myZone.id}
nameservers: ${exampleZone.nameServers}
status: ${exampleZone.status}このコードは、Zone リソースから zoneId、nameservers、status などのプロパティも出力するため、後続の手順で簡単に参照できます。
設定済みの Zone をテストするため、DNS の Record リソース ↗ を追加します。
エントリポイントファイルの Zone リソース定義の あと に、次のコードを追加します。
ファイル名: index.js
const record = new cloudflare.Record("my-record", {
zoneId: zone.id,
name: domain,
content: "192.0.2.1",
type: "A",
proxied: true,
});ファイル名: index.ts
const record = new cloudflare.Record("my-record", {
zoneId: zone.id,
name: domain,
content: "192.0.2.1",
type: "A",
proxied: true,
});ファイル名: __main__.py
record = cloudflare.Record("my-record",
zone_id=zone.id,
name=domain,
content="192.0.2.1",
type="A",
proxied=True
)ファイル名: main.go
_, err = cloudflare.NewRecord(ctx, "my-record", &cloudflare.RecordArgs{
ZoneId: zone.ID(),
Name: pulumi.String(domain),
Content: pulumi.String("192.0.2.1"),
Type: pulumi.String("A"),
Proxied: pulumi.Bool(true),
})
if err != nil {
return err
}ファイル名: src/main/java/myproject/App.java
// Add imports
import com.pulumi.cloudflare.Record;
import com.pulumi.cloudflare.RecordArgs;
// Below the Zone resource, add
new Record("my-record", RecordArgs.builder()
.zoneId(zone.id())
.name(domain)
.content("192.0.2.1")
.type("A")
.proxied(true)
.build());ファイル名: Program.cs
new Record("my-record", new RecordArgs
{
ZoneId = zone.Id,
Name = domain,
Content = "192.0.2.1",
Type = "A",
Proxied = true
});ファイル名: Pulumi.yaml
myRecord:
type: cloudflare:Record
properties:
zoneId: ${myZone.id}
name: ${domain}
content: 192.0.2.1
type: A
proxied: trueリソースを定義したら、Pulumi CLI で変更をデプロイし、Cloudflare アカウントに反映します。
変更をデプロイするには、次を実行します。
pulumi up --yeswait for the dev stack to become readyドメインを Cloudflare に追加すると、そのドメインに 2 つの権威ネームサーバーが割り当てられます。
割り当てられた nameservers を取得するには、次を実行します。
pulumi stack outputドメインで Cloudflare のサービスを有効にするには、レジストラのネームサーバーを更新します。手順はレジストラごとに異なります。よくあるレジストラの一覧 に案内がある場合があります。
登録が完了すると、ドメインの status は active になります。
pulumi stack outputCloudflare が割り当てたネームサーバーに対して、nslookup を 2 回実行します。
サイトをテストするには、次を実行します。
DOMAIN=$(pulumi config get domain)
NS1=$(pulumi stack output nameservers | jq '.[0]' -r)
NS2=$(pulumi stack output nameservers | jq '.[1]' -r)
nslookup $DOMAIN $NS1
nslookup $DOMAIN $NS2.NET では、Output として Nameservers を使います。
レスポンスに、サイトの IP アドレスが返ることを確認します。
最後に、チュートリアルで使ったリソースとスタックを削除します。
pulumi destroy --yespulumi stack rm devサイトを Cloudflare に追加するために必要な Cloudflare リソースを、段階的に定義しました。使う言語でリソースを宣言し、残りは Pulumi に任せます。
Pulumi でサーバーレスアプリをデプロイするには、Worker をデプロイするチュートリアル を参照してください。