Add a site

Last updated Apr 21, 2026 In this tutorial, you will follow step-by-step instructions to bring an existing site to Cloudflare using Pulumi infrastructure as code (IaC) to familiarize yourself with the resource management lifecycle. In particular, you will create a Zone and a DNS record to resolve your newly added site. This tutorial adopts the IaC principle to complete the steps listed in the Add site tutorial.

Note

You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare.

Before you begin

Ensure you have:

  • A Cloudflare account and API Token with permission to edit the resources in this tutorial. If you need to, sign up for a Cloudflare account ↗︎ before continuing. Your token must have:
  • Zone-Zone-Edit permission
  • Zone-DNS-Edit permission
  • include-All zones from an account-<your account> zone resource
  • A Pulumi Cloud account. You can sign up for an always-free individual tier ↗︎.
  • The Pulumi CLI is installed on your machine.
  • A Pulumi-supported programming language ↗︎ is configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML)
  • A domain name. You may use example.com to complete the tutorial.

1. Initialize your project

A Pulumi project is a collection of files in a dedicated folder that describes the infrastructure you want to create. The Pulumi project folder is identified by the required Pulumi.yaml file. You will use the Pulumi CLI to create and configure a new project.

a. Create a directory

Use a new and empty directory for this tutorial.

mkdir addsite-cloudflare
cd addsite-cloudflare

b. Login to Pulumi Cloud

Pulumi Cloud ↗︎ is a hosted service that provides a secure and scalable platform for managing your infrastructure as code. You will use it to store your Pulumi backend configurations.

At the prompt, press Enter to log into your Pulumi Cloud account via the browser. Alternatively, you may provide a Pulumi Cloud access token ↗︎.

pulumi login

c. Create a new program

A Pulumi program is code written in a supported programming language ↗︎ that defines infrastructure resources.

To create a program, select your language of choice and run the pulumi command:

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

d. Create a stack

A Pulumi stack ↗︎ is an instance of a Pulumi program. Stacks are independently configurable and may represent different environments (development, staging, production) or feature branches. For this tutorial, you'll use the dev stack.

To instantiate your dev stack, run:

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

You have not defined any resources at this point, so you'll have an empty stack.

e. Save your settings

In this step, you will store your settings in a Pulumi ESC Environment ↗︎, a YAML file containing configurations and secrets. These can be accessed in several ways, including a Pulumi program. All ESC Environments securely reside in your Pulumi Cloud account and can be fully managed via the Pulumi CLI. For this tutorial, you will store the following values:

  • Your Cloudflare account ID.
  • A valid Cloudflare API token.
  • A domain. For instance, example.com.
# Define an ESC Environment name
E=cloudflare/my-dev-env

# Create a new Pulumi ESC Environment
pulumi config env init --env $E --yes
Creating 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.com

f. Install the Cloudflare package

You need to install the Cloudflare package for your language of choice in order to define Cloudflare resources in your Pulumi program.

Install the Cloudflare package by running the following command:

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 ...

Below are Apache Maven instructions. For other Java project managers such as Gradle, see the official Maven repository ↗︎

  1. Open your pom.xml file.
  2. Add the Pulumi Cloudflare dependency inside the <dependencies> section.
<dependency>
    <groupId>com.pulumi</groupId>
    <artifactId>cloudflare</artifactId>
    <version>5.38.0</version>
</dependency>
  1. Run:
mvn clean install
...[INFO] BUILD SUCCESS...
dotnet add package Pulumi.Cloudflare
...
info : Adding PackageReference for package 'Pulumi.Cloudflare' into project
...

There are no dependencies to download for YAML. Skip ahead.

2. Define Cloudflare resources in code

With the Cloudflare package installed, you can now define any supported Cloudflare resource ↗︎ in your Pulumi program. You'll define a Zone, and a DNS Record next.

a. Add a Zone

A domain, or site, is known as a Zone in Cloudflare. In Pulumi, the Zone resource ↗︎ represents a Cloudflare Zone.

Replace the contents of your entrypoint file with the following:

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

// 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;

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

// 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;

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

Filename: main.go

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