← Pulumi / pulumi / tutorial
Развертывание Worker
В этом руководстве вы пошагово развернете приложение Hello World с помощью Cloudflare Workers и инфраструктуры как кода (IaC) Pulumi и познакомитесь с жизненным циклом управления ресурсами. В частности, вы создадите Worker, Route и DNS Record для доступа к приложению, а затем удалите все ресурсы.
Перед началом работы
Убедитесь, что у вас есть:
- Аккаунт Cloudflare и API-токен с разрешением на редактирование ресурсов, используемых в этом руководстве. При необходимости зарегистрируйте Аккаунт Cloudflare ↗ перед тем как продолжить. Ваш токен должен обладать следующими правами:
Account-Workers Scripts-EditразрешениеZone-Workers Route-EditразрешениеZone-DNS-Editразрешение
- Аккаунт Pulumi Cloud. Вы можете зарегистрировать постоянно бесплатный индивидуальный тариф ↗.
- Pulumi CLI установлен на вашем компьютере.
- A Язык программирования, поддерживаемый Pulumi ↗ настроен. (TypeScript, JavaScript, Python, Go, .NET, Java или используйте YAML)
- Домен, управляемый Cloudflare. Выполните Руководство по добавлению сайта чтобы подключить существующий домен к Cloudflare.
1. Инициализируйте проект
Проект Pulumi представляет собой набор файлов в отдельной папке, описывающий инфраструктуру, которую требуется создать. Папка проекта Pulumi определяется обязательным Pulumi.yaml файл. Вы будете использовать Pulumi CLI для создания и настройки нового проекта.
a. Создайте каталог
Для этого руководства используйте новый пустой каталог.
mkdir serverless-cloudflare
cd serverless-cloudflareb. Войдите в Pulumi Cloud
Pulumi Cloud ↗ это размещённый сервис, который предоставляет безопасную и масштабируемую платформу для управления инфраструктурой как кодом. Вы будете использовать его для хранения конфигураций бэкенда Pulumi.
В командной строке нажмите Enter, чтобы войти в аккаунт Pulumi Cloud через браузер. Также вы можете указать Токен доступа Pulumi Cloud ↗.
pulumi loginc. Создайте новую программу
Программа Pulumi представляет собой код, написанный на поддерживаемый язык программирования ↗ который определяет ресурсы инфраструктуры.
Чтобы создать программу, выберите нужный язык и выполните команду pulumi команда:
pulumi new javascript --name serverless-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new typescript --name serverless-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new python --name serverless-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new go --name serverless-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new java --name serverless-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new csharp --name serverless-cloudflare --yes
# wait a few seconds while the project is initializedpulumi new yaml --name serverless-cloudflare --yesd. Создайте стек
Pulumi стек ↗ это экземпляр программы Pulumi. Стеки настраиваются независимо друг от друга и могут представлять разные окружения (development, staging, production) или ветки функциональности. В этом руководстве вы будете использовать dev стек.
Чтобы создать экземпляр своего dev стек, выполните:
pulumi up --yes
# wait a few seconds for the stack to be instantiated.На данный момент вы еще не определили ни одного ресурса, поэтому стек будет пустым.
e. Сохраните настройки приложения
На этом шаге вы сохраните настройки приложения в Pulumi ESC Environment ↗, YAML-файл с конфигурациями и секретами. Доступ к ним можно получить несколькими способами, включая программу Pulumi. Все ESC Environments надёжно хранятся в вашем аккаунте Pulumi Cloud и полностью управляются через Pulumi CLI. В этом руководстве вы сохраните следующие значения:
- Ваш Cloudflare ID аккаунта.
- Действительный API Cloudflare токен.
- Домен. Например,
example.com.
# Give your new ESC Environment a name
E=hello-world/dev-env
# Initialize the new ESC Environment
pulumi config env init --env $E --yesCreating 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.comf. Установите пакет Cloudflare
Чтобы определять ресурсы Cloudflare в программе Pulumi, установите пакет 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. Для других менеджеров проектов Java, таких как Gradle, см. официальную Репозиторий Maven ↗
- Откройте свой
pom.xmlфайл. - Добавьте зависимость Pulumi Cloudflare внутри
<dependencies>раздел.
<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 не требуется загружать никаких зависимостей. Переходите к следующему шагу.
2. Опишите ресурсы Cloudflare в коде
После установки пакета Cloudflare вы можете определить любой поддерживаемый ресурс Cloudflare ↗ в своей программе Pulumi. Далее определите Worker, Route и DNS-запись.
a. Добавьте скрипт Workers
Ресурс Workers Script ↗ представляет собой Cloudflare Worker, который можно развернуть в сети Cloudflare.
Замените содержимое файла точки входа следующим:
Имя файла: 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: trueb. Добавьте маршрут
Теперь добавьте Ресурс Workers Route ↗ в свою программу Pulumi, чтобы у скрипта Workers появилась конечная точка и он стал активным. Чтобы правильно настроить Route, вы также найдёте идентификатор зоны для своего домена.
Добавьте следующий фрагмент кода в файл точки входа после ресурс скрипта 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
Теперь добавьте DNS Ресурс Record ↗ чтобы разрешить ранее настроенный Route. На следующем шаге вы также выведете URL-адрес Route, чтобы его было удобно открыть.
Добавьте следующий фрагмент кода в файл точки входа после ресурс 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 определены, вы можете развернуть приложение Hello World в своей учетной записи Cloudflare с помощью Pulumi CLI.
Чтобы развернуть изменения, выполните:
pulumi up --yeswait for the dev stack to become ready4. Протестируйте Worker
Вы последовательно добавили ресурсы Cloudflare для запуска приложения Hello World и доступа к нему. Проверить приложение можно с помощью команды curl для url вывод из стека Pulumi.
curl $(pulumi stack output url)Hello, World!5. Очистка
На этом последнем шаге вы очистите ресурсы и стек, использованные в этом руководстве.
a. Удалите ресурсы Cloudflare
pulumi destroyb. Удалите стек Pulumi
pulumi stack rm devСледующие шаги
Перейдите в Документация пакета Cloudflare ↗ чтобы изучить другие ресурсы, которые можно определить с помощью Pulumi и Cloudflare.