Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Worker をデプロイする

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、Cloudflare Workers と Pulumi のインフラストラクチャ as Code(IaC)を使い、Hello World アプリケーションをデプロイする手順を進め、リソース管理のライフサイクルを把握します。具体的には Worker、Route、DNS レコードを作成し、アプリケーションへアクセスできるようにしてから、すべてのリソースを後始末します。

始める前に

次を用意してください。

1. プロジェクトを初期化する

Pulumi プロジェクトは、作成したいインフラを記述する専用フォルダー内のファイル群です。Pulumi プロジェクトフォルダーは、必須の Pulumi.yaml ファイルで識別します。新しいプロジェクトの作成と設定には Pulumi CLI を使います。

a. ディレクトリを作成する

このチュートリアルでは、空の新しいディレクトリを使います。

mkdir serverless-cloudflare
cd serverless-cloudflare

b. Pulumi Cloud にログインする

Pulumi Cloud は、インフラストラクチャ as Code を管理するための安全でスケーラブルなホスト型サービスです。Pulumi のバックエンド設定の保存に使います。

プロンプトで Enter を押すと、ブラウザー経由で Pulumi Cloud アカウントにログインします。Pulumi Cloud のアクセストークン を渡すこともできます。

pulumi login

c. 新しいプログラムを作成する

Pulumi プログラムは、対応言語 で書いた、インフラリソースを定義するコードです。

プログラムを作成するには、使う言語を選び、pulumi コマンドを実行します。

pulumi new javascript --name serverless-cloudflare --yes
# wait a few seconds while the project is initialized
pulumi new typescript --name serverless-cloudflare --yes
# wait a few seconds while the project is initialized
pulumi new python --name serverless-cloudflare --yes
# wait a few seconds while the project is initialized
pulumi new go --name serverless-cloudflare --yes
# wait a few seconds while the project is initialized
pulumi new java --name serverless-cloudflare --yes
# wait a few seconds while the project is initialized
pulumi new csharp --name serverless-cloudflare --yes
# wait a few seconds while the project is initialized
pulumi new yaml --name serverless-cloudflare --yes

d. スタックを作成する

Pulumi の スタック は、Pulumi プログラムのインスタンスです。スタックは独立して設定でき、異なる環境(開発、ステージング、本番)や機能ブランチを表せます。このチュートリアルでは dev スタックを使います。

dev スタックを作成するには、次を実行します。

pulumi up --yes
# wait a few seconds for the stack to be instantiated.

この時点ではリソースを定義していないため、空のスタックになります。

e. アプリケーション設定を保存する

この手順では、設定とシークレットを含む YAML ファイルである Pulumi ESC Environment にアプリケーション設定を保存します。Pulumi プログラムを含む複数の方法でアクセスできます。ESC Environment はすべて Pulumi Cloud アカウントに安全に保存され、Pulumi CLI で管理できます。このチュートリアルでは次の値を保存します。

# Give your new ESC Environment a name
E=hello-world/dev-env

# Initialize the new ESC Environment
pulumi config env init --env $E --yes
Creating environment hello-world/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 domain
pulumi env set $E --plaintext pulumiConfig.domain example.com

f. Cloudflare パッケージをインストールする

Pulumi プログラムで Cloudflare リソースを定義するには、使う言語向けの Cloudflare パッケージをインストールする必要があります。

次のコマンドで Cloudflare パッケージをインストールします。

npm install @pulumi/cloudflare
added 1 package ...
npm install @pulumi/cloudflare
added 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/cloudflare
go: downloading github.com/pulumi/pulumi-cloudflare ...

以下は Apache Maven の手順です。Gradle など他の Java プロジェクトマネージャーについては、公式の Maven repository を参照してください。

  1. pom.xml ファイルを開きます。
  2. <dependencies> セクション内に Pulumi Cloudflare の依存関係を追加します。
<dependency>
    <groupId>com.pulumi</groupId>
    <artifactId>cloudflare</artifactId>
    <version>5.38.0</version>
</dependency>
  1. 次を実行します。
mvn clean install
...[INFO] BUILD SUCCESS...
dotnet add package Pulumi.Cloudflare
...
info : Adding PackageReference for package 'Pulumi.Cloudflare' into project
...

YAML ではダウンロードする依存関係はありません。次に進んでください。

2. コードで Cloudflare リソースを定義する

Cloudflare パッケージをインストールしたら、Pulumi プログラムで 対応する任意の Cloudflare リソース を定義できます。次に Worker、Route、DNS レコードを定義します。

a. Workers スクリプトを追加する

Workers Script リソース は、Cloudflare ネットワークへデプロイできる Cloudflare Worker を表します。

エントリポイントファイルの内容を、次に置き換えます。

ファイル名: 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");

const content = `export default {
  async fetch(request) {
    const options = { headers: { 'content-type': 'text/plain' } };
    return new Response("Hello World!", options);
  },
};`;

const worker = new cloudflare.WorkersScript("hello-world-worker", {
	accountId: accountId,
	name: "hello-world-worker",
	content: content,
	module: true, // ES6 module
});

ファイル名: 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");

const content = `export default {
  async fetch(request) {
    const options = { headers: { 'content-type': 'text/plain' } };
    return new Response("Hello World!", options);
  },
};`;

const worker = new cloudflare.WorkersScript("hello-world-worker", {
	accountId: accountId,
	name: "hello-world-worker",
	content: content,
	module: true, // ES6 module
});

ファイル名: __main__.py

"""Pulumi program """
import pulumi
import pulumi_cloudflare as cloudflare

CONFIG = pulumi.Config()
ACCOUNT_ID = CONFIG.get("accountId")
DOMAIN = CONFIG.require("domain")
CONTENT = """
export default {
  async fetch(request) {
    const options = { headers: { 'content-type': 'text/plain' } };
    return new Response("Hello World!", options);
  },
};
"""

worker = cloudflare.WorkersScript("hello-world-worker",
    account_id=ACCOUNT_ID,
    name="hello-world-worker",
    content=CONTENT,
    module=True  # ES6 module
)

ファイル名: main.go

package main

import (
	"github.com/pulumi/pulumi-cloudflare/sdk/v5/go/cloudflare"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		conf := config.New(ctx, "")
		accountID := conf.Get("accountId")
		domain := conf.Get("domain")
		content := `
		export default {
		  async fetch(request) {
		    const options = { headers: { 'content-type': 'text/plain' } };
		    return new Response("Hello World!", options);
		  },
		};
		`
		worker, err := cloudflare.NewWorkersScript(ctx, "hello-world-worker", &cloudflare.WorkersScriptArgs{
			AccountId: pulumi.String(accountID),
			Name:      pulumi.String("hello-world-worker"),
			Content:   pulumi.String(content),
			Module:    pulumi.Bool(true), // ES6 module
		})
		if err != nil {
			return err
		}

		return nil
	})
}

ファイル名: src/main/java/myproject/App.java

package myproject;

import com.pulumi.Pulumi;
import com.pulumi.cloudflare.WorkersScript;
import com.pulumi.cloudflare.WorkersScriptArgs;
import com.pulumi.core.Output;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var content = """
              export default {
                async fetch(request) {
                  const options = { headers: { 'content-type': 'text/plain' } };
                  return new Response("Hello World!", options);
                },
              };
            """;

            var accountId = ctx.config().require("accountId");
            var domain = ctx.config().require("domain");
            var worker = new WorkersScript("hello-world-worker", WorkersScriptArgs.builder()
                .accountId(accountId)
                .name("hello-world-worker")
                .content(content)
                .module(true)
                .build());

            return;
        });
    }
}

ファイル名: Program.cs

using Pulumi;
using Cloudflare = Pulumi.Cloudflare;

return await Deployment.RunAsync(() =>
{
    var config = new Config();
    var accountId = config.Require("accountId");
    var domain = config.Require("domain");
    var content = @"
            export default {
                async fetch(request) {
                    const options = { headers: { 'content-type': 'text/plain' } };
                    return new Response(""Hello World!"", options);
                },
            };
        ";

    var worker = new Cloudflare.WorkersScript("hello-world-worker", new()
    {
        AccountId = accountId,
        Name = "hello-world-worker",
        Content = content,
        Module = true
    });
    return;
});

ファイル名: Pulumi.yaml

name: serverless-cloudflare
runtime: yaml
resources:
  worker:
    type: cloudflare:WorkersScript
    properties:
      accountId: "${accountId}"
      name: "hello-world-worker"
      content: |
        export default {
            async fetch(request) {
                const options = { headers: { 'content-type': 'text/plain' } };
                return new Response("Hello World!", options);
            },
        };
      module: true

b. Route を追加する

Workers スクリプトにエンドポイントを持たせ、有効にするため、Pulumi プログラムに Workers Route リソース を追加します。Route を正しく設定するため、ドメインのゾーン ID も取得します。

エントリポイントファイルの、Worker スクリプトリソースのあとに、次のコードを追加します。

ファイル名: index.js

const zone = cloudflare.getZone({
	accountId: accountId,
	name: domain,
});

const zoneId = zone.then((z) => z.zoneId);

const route = new cloudflare.WorkersRoute("hello-world-route", {
	zoneId: zoneId,
	pattern: "hello-world." + domain,
	scriptName: worker.name,
});

ファイル名: index.ts

const zone = cloudflare.getZone({
	accountId: accountId,
	name: domain,
});

const zoneId = zone.then((z) => z.zoneId);

const route = new cloudflare.WorkersRoute("hello-world-route", {
	zoneId: zoneId,
	pattern: "hello-world." + domain,
	scriptName: worker.name,
});

ファイル名: __main__.py

zone = cloudflare.get_zone(account_id=ACCOUNT_ID, name=DOMAIN)
zone_id = zone.zone_id
route = cloudflare.WorkersRoute("hello-world-route",
    zone_id=zone_id,
    pattern="hello-world." + DOMAIN,
    script_name=worker.name
)

ファイル名: main.go

zone, err := cloudflare.LookupZone(ctx, &cloudflare.LookupZoneArgs{
  AccountId: &accountID,
  Name:      &domain,
}, nil)
if err != nil {
  return err
}

route, err := cloudflare.NewWorkersRoute(ctx, "hello-world-route", &cloudflare.WorkersRouteArgs{
  ZoneId:     pulumi.String(zone.Id),
  Pattern:    pulumi.String("hello-world." + domain),
  ScriptName: worker.Name,
})
if err != nil {
  return err
}

ファイル名: src/main/java/myproject/App.java

final var zone = CloudflareFunctions.getZone(GetZoneArgs.builder()
  .accountId(accountId)
  .name(domain)
  .build());
var route = new WorkersRoute("hello-world-route", WorkersRouteArgs.builder()
  .zoneId(zone.applyValue(getZoneResult -> getZoneResult.id()))
  .pattern("hello-world." + domain)
  .scriptName(worker.name())
  .build());

ファイル名: Program.cs

var zone = Output.Create(Cloudflare.GetZone.InvokeAsync(new()
{
    AccountId = accountId,
    Name = domain,
}));
var route = new Cloudflare.WorkersRoute("hello-world-route", new()
{
    ZoneId = zone.Apply(z => z.Id),
    Pattern = "hello-world." + domain,
    ScriptName = worker.Name,
});

ファイル名: Pulumi.yaml

runtime キーの下に、次のコードを追加します。

# new top-level section
variables:
  zone:
    fn::invoke:
      function: cloudflare:getZone
      arguments:
        accountId: ${accountId}
        name: ${domain}

worker リソースの下に、次のコードを追加します。

route:
  type: cloudflare:WorkersRoute
  properties:
    zoneId: ${zone.id}
    pattern: "hello-world.${domain}"
    scriptName: ${worker.name}

c. DNS レコードを追加する

先ほど設定した Route を解決する DNS レコードリソース を追加します。次の手順では、アクセスしやすいように Route の URL も出力します。

エントリポイントファイルの、Route リソースのあとに、次のコードを追加します。

ファイル名: index.js

const record = new cloudflare.Record("hello-world-record", {
	name: route.pattern,
	type: "A",
	content: "192.0.2.1",
	zoneId: zoneId,
	proxied: true,
});

exports.url = pulumi.interpolate`https://${record.hostname}`;

ファイル名: index.ts

const record = new cloudflare.Record("hello-world-record", {
	name: route.pattern,
	type: "A",
	content: "192.0.2.1",
	zoneId: zoneId,
	proxied: true,
});

export const url = pulumi.interpolate`https://${record.hostname}`;

ファイル名: __main__.py

record = cloudflare.Record("hello-world-record",
    name=route.pattern,
    type="A",
    content="192.0.2.1",
    zone_id=zone_id,
    proxied=True
)

url = pulumi.Output.concat("https://", record.hostname)
pulumi.export('url', url)

ファイル名: main.go

record, err := cloudflare.NewRecord(ctx, "hello-world-record", &cloudflare.RecordArgs{
  Name:    route.Pattern,
  Type:    pulumi.String("A"),
  Content: pulumi.String("192.0.2.1"),
  ZoneId:  pulumi.String(zone.Id),
  Proxied: pulumi.Bool(true),
})
if err != nil {
  return err
}

ctx.Export("url", pulumi.Sprintf("https://%s", record.Hostname))

ファイル名: src/main/java/myproject/App.java

var record = new Record("hello-world-record", RecordArgs.builder()
    .name(route.pattern())
    .type("A")
    .content("192.0.2.1")
    .zoneId(zone.applyValue(getZoneResult -> getZoneResult.id()))
    .proxied(true)
    .build());

ctx.export("url", Output.format("https://%s", record.hostname()));

ファイル名: Program.cs

値をエクスポートするため、return 文が更新されています。インポートに using System.Collections.Generic; も含めてください。

var record = new Cloudflare.Record("hello-world-record", new()
{
    Name = route.Pattern,
    Type = "A",
    Content = "192.0.2.1",
    ZoneId = zone.Apply(z => z.Id),
    Proxied = true
});

return new Dictionary<string, object?>
{
    ["url"] = Output.Format($"https://{record.Hostname}")
};

トップレベルの outputs セクションが追加されます。

  record:
    type: cloudflare:Record
    properties:
      name: ${route.pattern}
      type: A
      content: "192.0.2.1"
      zoneId: ${zone.id}
      proxied: true

outputs:
  url: "https://${record.hostname}"

d. (任意)コードを確認する

変更内容が、次の完成形と一致することを確認します。

ファイル名: 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");

const content = `export default {
  async fetch(request) {
    const options = { headers: { 'content-type': 'text/plain' } };
    return new Response("Hello World!", options);
  },
};`;

const worker = new cloudflare.WorkersScript("hello-world-worker", {
	accountId: accountId,
	name: "hello-world-worker",
	content: content,
	module: true, // ES6 module
});

const zone = cloudflare.getZone({
	accountId: accountId,
	name: domain,
});

const zoneId = zone.then((z) => z.zoneId);

const route = new cloudflare.WorkersRoute("hello-world-route", {
	zoneId: zoneId,
	pattern: "hello-world." + domain,
	scriptName: worker.name,
});

const record = new cloudflare.Record("hello-world-record", {
	name: route.pattern,
	type: "A",
	content: "192.0.2.1",
	zoneId: zoneId,
	proxied: true,
});

exports.url = pulumi.interpolate`https://${record.hostname}`;

ファイル名: 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");

const content = `export default {
  async fetch(request) {
    const options = { headers: { 'content-type': 'text/plain' } };
    return new Response("Hello World!", options);
  },
};`;

const worker = new cloudflare.WorkersScript("hello-world-worker", {
	accountId: accountId,
	name: "hello-world-worker",
	content: content,
	module: true, // ES6 module
});

const zone = cloudflare.getZone({
	accountId: accountId,
	name: domain,
});

const zoneId = zone.then((z) => z.zoneId);

const route = new cloudflare.WorkersRoute("hello-world-route", {
	zoneId: zoneId,
	pattern: "hello-world." + domain,
	scriptName: worker.name,
});

const record = new cloudflare.Record("hello-world-record", {
	name: route.pattern,
	type: "A",
	content: "192.0.2.1",
	zoneId: zoneId,
	proxied: true,
});

export const url = pulumi.interpolate`https://${record.hostname}`;

ファイル名: __main__.py

"""Pulumi program """
import pulumi
import pulumi_cloudflare as cloudflare

CONFIG = pulumi.Config()
ACCOUNT_ID = CONFIG.get("accountId")
DOMAIN = CONFIG.require("domain")
CONTENT = """
export default {
  async fetch(request) {
    const options = { headers: { 'content-type': 'text/plain' } };
    return new Response("Hello World!", options);
  },
};
"""

worker = cloudflare.WorkersScript("hello-world-worker",
    account_id=ACCOUNT_ID,
    name="hello-world-worker",
    content=CONTENT,
    module=True  # ES6 module
)

zone = cloudflare.get_zone(account_id=ACCOUNT_ID, name=DOMAIN)
zone_id = zone.zone_id
route = cloudflare.WorkersRoute("hello-world-route",
    zone_id=zone_id,
    pattern="hello-world." + DOMAIN,
    script_name=worker.name
)

record = cloudflare.Record("hello-world-record",
    name=route.pattern,
    type="A",
    content="192.0.2.1",
    zone_id=zone_id,
    proxied=True
)

url = pulumi.Output.concat("https://", record.hostname)
pulumi.export('url', url)

ファイル名: main.go

package main

import (
	"github.com/pulumi/pulumi-cloudflare/sdk/v5/go/cloudflare"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		conf := config.New(ctx, "")
		accountID := conf.Get("accountId")
		domain := conf.Get("domain")
		content := `
		export default {
		  async fetch(request) {
		    const options = { headers: { 'content-type': 'text/plain' } };
		    return new Response("Hello World!", options);
		  },
		};
		`
		worker, err := cloudflare.NewWorkersScript(ctx, "hello-world-worker", &cloudflare.WorkersScriptArgs{
			AccountId: pulumi.String(accountID),
			Name:      pulumi.String("hello-world-worker"),
			Content:   pulumi.String(content),
			Module:    pulumi.Bool(true), // ES6 module
		})
		if err != nil {
			return err
		}
		zone, err := cloudflare.LookupZone(ctx, &cloudflare.LookupZoneArgs{
			AccountId: &accountID,
			Name:      &domain,
		}, nil)
		if err != nil {
			return err
		}

		route, err := cloudflare.NewWorkersRoute(ctx, "hello-world-route", &cloudflare.WorkersRouteArgs{
			ZoneId:     pulumi.String(zone.Id),
			Pattern:    pulumi.String("hello-world." + domain),
			ScriptName: worker.Name,
		})
		if err != nil {
			return err
		}

		record, err := cloudflare.NewRecord(ctx, "hello-world-record", &cloudflare.RecordArgs{
			Name:    route.Pattern,
			Type:    pulumi.String("A"),
			Content: pulumi.String("192.0.2.1"),
			ZoneId:  pulumi.String(zone.Id),
			Proxied: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}

		ctx.Export("url", pulumi.Sprintf("https://%s", record.Hostname))

		return nil
	})
}

ファイル名: src/main/java/myproject/App.java

package myproject;

import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.cloudflare.WorkersScript;
import com.pulumi.cloudflare.WorkersScriptArgs;
import com.pulumi.cloudflare.CloudflareFunctions;
import com.pulumi.cloudflare.inputs.GetZoneArgs;
import com.pulumi.cloudflare.WorkersRoute;
import com.pulumi.cloudflare.WorkersRouteArgs;
import com.pulumi.cloudflare.Record;
import com.pulumi.cloudflare.RecordArgs;

public class App {
    public static void main(String[] args) {
        Pulumi.run(ctx -> {
            var content = """
				export default {
				  async fetch(request) {
				    const options = { headers: { 'content-type': 'text/plain' } };
				    return new Response("Hello World!", options);
				  },
				};
			""";

            var accountId = ctx.config().require("accountId");
            var domain = ctx.config().require("domain");

            var worker = new WorkersScript("hello-world-worker", WorkersScriptArgs.builder()
                .accountId(accountId)
                .name("hello-world-worker")
                .content(content)
                .module(true)
                .build());
            final var zone = CloudflareFunctions.getZone(GetZoneArgs.builder()
                .accountId(accountId)
                .name(domain)
                .build());
            var route = new WorkersRoute("hello-world-route", WorkersRouteArgs.builder()
                .zoneId(zone.applyValue(getZoneResult -> getZoneResult.id()))
                .pattern("hello-world." + domain)
                .scriptName(worker.name())
                .build());
            var record = new Record("hello-world-record", RecordArgs.builder()
                .name(route.pattern())
                .type("A")
                .content("192.0.2.1")
                .zoneId(zone.applyValue(getZoneResult -> getZoneResult.id()))
                .proxied(true)
                .build());

            ctx.export("url", Output.format("https://%s", record.hostname()));
            return;
        });
    }
}

ファイル名: Program.cs

using System.Collections.Generic;
using Pulumi;
using Cloudflare = Pulumi.Cloudflare;

return await Deployment.RunAsync(() =>
{
    var config = new Config();
    var accountId = config.Require("accountId");
    var domain = config.Require("domain");
    var content = @"
            export default {
                async fetch(request) {
                    const options = { headers: { 'content-type': 'text/plain' } };
                    return new Response(""Hello World!"", options);
                },
            };
        ";

    var worker = new Cloudflare.WorkersScript("hello-world-worker", new()
    {
        AccountId = accountId,
        Name = "hello-world-worker",
        Content = content,
        Module = true
    });
    var zone = Output.Create(Cloudflare.GetZone.InvokeAsync(new()
    {
        AccountId = accountId,
        Name = domain,
    }));
    var route = new Cloudflare.WorkersRoute("hello-world-route", new()
    {
        ZoneId = zone.Apply(z => z.Id),
        Pattern = "hello-world." + domain,
        ScriptName = worker.Name,
    });

    var record = new Cloudflare.Record("hello-world-record", new()
    {
        Name = route.Pattern,
        Type = "A",
        Content = "192.0.2.1",
        ZoneId = zone.Apply(z => z.Id),
        Proxied = true
    });

    return new Dictionary<string, object?>
    {
        ["url"] = Output.Format($"https://{record.Hostname}")
    };
});

ファイル名: Pulumi.yaml

name: serverless-cloudflare
runtime: yaml
variables:
  zone:
    fn::invoke:
      function: cloudflare:getZone
      arguments:
        accountId: ${accountId}
        name: ${domain}

resources:
  worker:
    type: cloudflare:WorkersScript
    properties:
      accountId: "${accountId}"
      name: "hello-world-worker"
      content: |
        export default {
            async fetch(request) {
                const options = { headers: { 'content-type': 'text/plain' } };
                return new Response("Hello World!", options);
            },
        };
      module: true
  route:
    type: cloudflare:WorkersRoute
    properties:
      zoneId: ${zone.id}
      pattern: "hello-world.${domain}"
      scriptName: ${worker.name}
  record:
    type: cloudflare:Record
    properties:
      name: ${route.pattern}
      type: A
      content: "192.0.2.1"
      zoneId: ${zone.id}
      proxied: true

outputs:
  url: "https://${record.hostname}"

3. アプリケーションをデプロイする

Cloudflare リソースをすべて定義したので、Pulumi CLI で Hello World アプリケーションを Cloudflare アカウントへデプロイできます。

変更をデプロイするには、次を実行します。

pulumi up --yes
wait for the dev stack to become ready

4. Worker をテストする

Hello World アプリケーションを動かしてアクセスできるよう、Cloudflare リソースを段階的に追加しました。Pulumi スタックの url 出力を curl して、アプリケーションをテストできます。

curl $(pulumi stack output url)
Hello, World!

5. 後始末する

最後に、チュートリアルで使ったリソースとスタックを削除します。

a. Cloudflare リソースを削除する

pulumi destroy

b. Pulumi スタックを削除する

pulumi stack rm dev

次のステップ

Pulumi と Cloudflare で定義できるほかのリソースは、Cloudflare パッケージのドキュメント を参照してください。

役に立ちましたか?