Deploy a Worker·续

Filename: 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}`;

Filename: 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}`;

Filename: __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)

Filename: 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))

Filename: 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()));

Filename: Program.cs

Notice the updated ' return ' statement because you're now exporting a value. Ensure that you also include using System.Collections.Generic; in your imports.

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}")
};

Notice the new top-level outputs section.

  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}"

Note

You may need to use http instead depending on your domain settings.

d. (Optional) Verify your code

Confirm all your changes match the full solution below:

Filename: 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}`;

Filename: 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}`;

Filename: __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)

Filename: 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
    })
}

Filename: 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;
        });
    }
}

Filename: 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}")
    };
});

Filename: 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. Deploy your application

Now that you have defined all the Cloudflare resources, you can deploy the Hello World application to your Cloudflare account using the Pulumi CLI.

To deploy the changes, run:

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

4. Test the Worker

You incrementally added Cloudflare resources to run and access your Hello World application. You can test your application by curling the url output from the Pulumi stack.

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

5. Clean up

In this last step, you will clean up the resources and stack used throughout the tutorial.

a. Delete the Cloudflare resources

pulumi destroy

b. Remove the Pulumi stack

pulumi stack rm dev

Next steps

Visit the Cloudflare package documentation ↗︎ to explore other resources you can define with Pulumi and Cloudflare.

Was this helpful?

YesNo

On this page

Deploy a Worker·续 - 图1Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/pulumi/tutorial/hello-world/#page","headline":"Deploy a Worker","description":"In this tutorial, you will follow step-by-step instructions to deploy a Hello World application using Cloudflare Workers and Pulumi infrastructure as code (IaC).","url":"https://developers.cloudflare.com/pulumi/tutorial/hello-world/","inLanguage":"en","image":"https://developers.cloudflare.com/pulumi/tutorial/hello-world/og.png?v=2c8d2103a26ad584","dateModified":"2025-10-13","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["JavaScript","TypeScript","Python","Go","Java",".NET","YAML"]}


description: Pulumi ESC (Environments, Secrets, and Configuration) is a secure and robust secrets management solution. The tutorial will walk you through how to develop with Wrangler while following security best practices. title: Manage secrets with Pulumi ESC image: https://developers.cloudflare.com/pulumi/tutorial/manage-secrets/og.png?v=9faca02d9fb9255b


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/pulumi/llms.txt
Use this file to discover all available pages before exploring further.