From 5e68329a7b6e41c372dede4c189f9bee6c44175b Mon Sep 17 00:00:00 2001 From: diana esteves Date: Wed, 11 Sep 2024 16:16:23 -0500 Subject: [PATCH 01/17] wip --- src/content/docs/pulumi/tutorial/add-site.mdx | 2 +- .../docs/pulumi/tutorial/hello-world.mdx | 276 +++++++++++------- 2 files changed, 179 insertions(+), 99 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index c3a5d406c46956..b637fb08680494 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -921,4 +921,4 @@ You have incrementally defined Cloudflare resources needed to add a site to Clou ## Next steps -Follow the [Hello World tutorial](/pulumi/tutorial/hello-world/) to deploy a serverless app with Pulumi. +Follow the [Deploy a Worker tutorial](/pulumi/tutorial/hello-world/) to deploy a serverless app with Pulumi. diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index ed931d4c5b9686..b67e93d1a275c1 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -1,13 +1,18 @@ --- -title: Deploy a Worker with Pulumi +title: Deploy a Worker pcx_content_type: tutorial products: - Workers updated: 2024-01-08 -content_type: đź“ť Tutorial difficulty: Beginner languages: + - JavaScript - TypeScript + - Python + - Go + - Java + - .NET + - YAML sidebar: order: 3 head: @@ -17,8 +22,6 @@ head: In this tutorial, you will go through step-by-step instructions to deploy a Hello World web application using Cloudflare Workers and Pulumi Infrastructure as Code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. -![alt_text](~/assets/images/pulumi/hello-world-tutorial/sn2.png "Running Cloudflare Workers application deployed with Pulumi") - :::note You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. @@ -31,27 +34,15 @@ 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. - A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). -- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and the [Pulumi CLI](/pulumi/installing/) installed on your machine. -- A Cloudflare Zone. Complete the [Add a Site tutorial](/pulumi/tutorial/add-site/) to create one. - -:::note[Link to the full solution] - -You can find the complete solution of this tutorial under [this Pulumi repo and branch](https://github.com/pulumi/tutorials/tree/cloudflare-typescript-hello-world-end). To deploy the final version, run the following: - -```sh -mkdir serverless-cloudflare && cd serverless-cloudflare -pulumi new https://github.com/pulumi/tutorials/tree/cloudflare-typescript-hello-world-end -npm install -pulumi up --yes -``` - -::: +- The [Pulumi CLI](/pulumi/installing/) is installed on your machine. +- A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) is configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) +- A domain name. You may use `example.com` to complete the tutorial. -## Initialize Pulumi +## 1. Initialize Pulumi ### a. Create a directory -You'll use a new and empty directory for this tutorial. +Use a new and empty directory for this tutorial. ```sh mkdir serverless-cloudflare @@ -70,65 +61,196 @@ pulumi login :::note -A Pulumi program is code written in a [supported programming language](https://www.pulumi.com/docs/languages-sdks/) that defines infrastructure resources. We'll use TypeScript. - +A Pulumi program is code written in a [supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) that defines infrastructure resources. ::: -To create a program, run: +To create a program, select your language of choice and run the `pulumi` command: + + + ```sh -pulumi new https://github.com/pulumi/tutorials/tree/cloudflare-typescript-hello-world-begin +pulumi new javascript --name serverless-cloudflare --yes +# wait a few seconds while the project is initialized ``` -Complete the prompts with defaults where available; otherwise, provide the requested information. You will need: + -- Your Cloudflare [account ID](/fundamentals/setup/find-account-and-zone-ids/). -- Your Cloudflare [Zone ID](/fundamentals/setup/find-account-and-zone-ids/). -- A registered domain. For instance, `example.com` -- A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). +```sh +pulumi new typescript --name serverless-cloudflare --yes +# wait a few seconds while the project is initialized +``` -### d. Create a stack + -:::note +```sh +pulumi new python --name serverless-cloudflare --yes +# wait a few seconds while the project is initialized +``` -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. + -::: +```sh +pulumi new go --name serverless-cloudflare --yes +# wait a few seconds while the project is initialized +``` -To create a stack, run: + ```sh -pulumi up --yes +pulumi new java --name serverless-cloudflare --yes +# wait a few seconds while the project is initialized +``` + + + +```sh +pulumi new csharp --name serverless-cloudflare --yes +# wait a few seconds while the project is initialized +``` + + + +```sh +pulumi new yaml --name serverless-cloudflare --yes ``` -After the above command completes, review the value of `myFirstOutput` for correctness. + -### e. (Optional) Review the stack +### d. Save your settings -From the output above, follow **your** _View in Browser_ link to get familiar with the Pulumi stack. +You will need: + +- Your Cloudflare [account ID](/fundamentals/setup/find-account-and-zone-ids/). +- A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). +- A domain. For instance, `example.com`. :::note -You have not yet created any Cloudflare resources but have defined a variable, `myFirstOutput`, and the Pulumi stack. +A Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/) is a YAML file containing configurations and secrets that pertain to your application and infrastructure. These can be accessed in several ways, including a Pulumi program. All ESC Environments reside in your Pulumi Cloud account. +::: + +todo todo todo todo todo todo!! + +### e. Create a stack + +:::note +A Pulumi [stack](https://www.pulumi.com/docs/concepts/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. ::: -Example: +To instantiate your `dev` stack, run: -```bash -View in Browser (Ctrl+O): -https://app.pulumi.com/diana-pulumi-corp/serverless-cloudflare/dev/updates/1 +```sh +pulumi up --yes --stack dev +# wait a few seconds for the stack to be instantiated. ``` -![alt_text](~/assets/images/pulumi/hello-world-tutorial/sn3.png "Pulumi Cloud stack") +At this point, you have not defined any resources so you'll have an empty stack. + +TODO next step here ## Add a Worker -You will now add a Cloudflare Worker to the Pulumi stack, `dev`. +You will now add the Pulumi Cloudflare package and a Cloudflare Worker to your Pulumi program. -### a. Add Cloudflare Worker to index.ts -Replace the contents of your `index.ts` file with the following: +### a. Install dependencies + + + +```sh +npm install @pulumi/cloudflare +``` + +```sh output +added 1 package ... +``` + + + +```sh +npm install @pulumi/cloudflare +``` + +```sh output +added 1 package ... +``` + + + +```sh +echo "pulumi_cloudflare>=5.35,<6.0.0" >> requirements.txt +source venv/bin/activate +pip install -r requirements.txt +``` + +```sh output +... +Collecting pulumi-cloudflare +... +``` + + + +```sh +go get github.com/pulumi/pulumi-cloudflare/sdk/v3/go/cloudflare +``` + +```sh output +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](https://central.sonatype.com/artifact/com.pulumi/cloudflare/overview) + +1. Open your `pom.xml` file. +2. Add the Pulumi Cloudflare dependency inside the `` section. + +```xml + + com.pulumi + cloudflare + 5.35.1 + +``` + +1. Run: + +```sh +mvn clean install +``` + +```sh output +... +[INFO] BUILD SUCCESS +... +``` + + + +```sh +dotnet add package Pulumi.Cloudflare +``` + +```sh output +... +info : Adding PackageReference for package 'Pulumi.Cloudflare' into project +... +``` + + + +There are no dependencies to download for YAML. Skip ahead. + + + +### b. Modify the program + +Replace the contents of your entrypoint file with the following: + + ```typescript import * as pulumi from "@pulumi/pulumi"; @@ -146,29 +268,17 @@ export const script = new cloudflare.WorkerScript("hello-world-script", { content: fs.readFileSync("./app/worker.ts", "utf8"), }); ``` + -### b. Install dependencies +TODO -- ADD OTHER LANGUAGES -```sh -npm install @pulumi/cloudflare -``` -### c. Apply the changes +### b. Apply the changes ```sh -pulumi up --yes +pulumi up --yes --stack dev ``` -### d. (Optional) View the Cloudflare Dashboard - -You can view your Cloudflare resource directly in the Cloudflare Dashboard to validate its existence. - -1. Log into the [Cloudflare dashboard](https://dash.cloudflare.com/). -2. Select your account. -3. Go to **Workers & Pages**. -4. Open the "hello-world" application. Example: - ![alt_text](~/assets/images/pulumi/hello-world-tutorial/sn4.png) - ## Add a Worker route You will now add a Worker Route to the Pulumi stack, `dev` so the script can have an endpoint. @@ -203,28 +313,11 @@ export const route = new cloudflare.WorkerRoute("hello-world-route", { }); ``` -### b. Apply changes - -```sh -pulumi up --yes -``` - -### c. (Optional) View the Cloudflare Worker route in the dashboard - -In the Cloudflare Dashboard, the Worker application now contains the previously defined Worker Route. - -1. Log into the [Cloudflare dashboard](https://dash.cloudflare.com/). -2. Select your account. -3. Go to **Workers & Pages**. -4. Select your application. -5. For **Routes**, select **View** to verify the Worker Route details match your definition. - ![alt_text](~/assets/images/pulumi/hello-world-tutorial/sn5.png "Cloudflare Dashboard - Worker Route") ## Add a DNS record You will now add a DNS record to your domain so the previously configured route can be accessed via a URL. -### a. Add DNS Record to index.ts Replace the contents of your `index.ts` file with the following: @@ -277,14 +370,6 @@ The last line in the code will create an output with the endpoint for the Hello pulumi up --yes ``` -### c. (Optional) View all the resources in Pulumi Cloud - -1. In your browser, open your [Pulumi Cloud](https://app.pulumi.com/) -2. Navigate to your stack, `serverless-cloudflare/dev`. -3. Confirm all the defined resources are created and healthy. Example: - -![alt_text](~/assets/images/pulumi/hello-world-tutorial/sn6.png "Pulumi Cloud stack") - ## Test the app You have incrementally added all the Cloudflare resources needed to run and access your Hello World application. This was done by defining the resources in TypeScript and letting Pulumi handle the rest. @@ -297,9 +382,6 @@ You can test your application via the terminal or browser. pulumi stack output url ``` -```sh output -hello-world.atxyall.com -``` ```sh curl "https://$(pulumi stack output url)" @@ -325,12 +407,6 @@ Depending on your domain settings, you may need to use "http" instead. ::: -- In your browser, open `hello-world.YOUR_DOMAIN.com` - -Example: - -![alt_text](~/assets/images/pulumi/hello-world-tutorial/sn2.png "Hello World app browser screenshot") - ## Clean up In this last step, you will run a couple of commands to clean up the resources and stack you used throughout the tutorial. @@ -346,3 +422,7 @@ pulumi destroy ```sh pulumi stack rm dev ``` + +## Next steps + +TODO \ No newline at end of file From 4906b71c41d201beb65ac7d322ee988b89ebd36e Mon Sep 17 00:00:00 2001 From: diana esteves Date: Wed, 11 Sep 2024 20:08:42 -0500 Subject: [PATCH 02/17] heading formatting --- src/content/docs/pulumi/tutorial/add-site.mdx | 12 ++++++------ .../docs/pulumi/tutorial/hello-world.mdx | 18 ++++++++---------- .../docs/pulumi/tutorial/manage-secrets.mdx | 12 ++++++------ 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index b637fb08680494..78aa0c8f56d823 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -39,7 +39,7 @@ Ensure you have: - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) is configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) - A domain name. You may use `example.com` to complete the tutorial. -## Initialize Pulumi +## 1. Initialize Pulumi ### a. Create a directory @@ -173,7 +173,7 @@ pulumi up --yes --stack dev At this point, you have not defined any resources so you'll have an empty stack. -## Add a Zone +## 2. Add a Zone :::note @@ -483,7 +483,7 @@ pulumi stack output zoneId d8fcb6d731fe1c2d75e2e8d6ad63fad5 ``` -## Update your nameservers +## 3. Update your nameservers Once you have added a domain to Cloudflare, that domain will receive two assigned authoritative nameservers. @@ -595,7 +595,7 @@ Once successfully registered, your domain `status` will change to `active`. pulumi stack output ``` -## Add a DNS record +## 4. Add a DNS record You will now add a DNS record to your domain. @@ -883,7 +883,7 @@ outputs: pulumi up --yes --stack dev ``` -## Verify your setup +## 5. Verify your setup You will run two `nslookup` commands against the Cloudflare-assigned nameservers. @@ -901,7 +901,7 @@ For .NET use `Nameservers` as the Output. Confirm your response returns the IP address(es) for your site. -## Clean up +## 6. Clean up In this last step, you will remove the resources and stack used throughout the tutorial. diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index b67e93d1a275c1..bfdd015f226ac5 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -20,12 +20,10 @@ head: content: Deploy a Worker --- -In this tutorial, you will go through step-by-step instructions to deploy a Hello World web application using Cloudflare Workers and Pulumi Infrastructure as Code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. +In this tutorial, you will go through step-by-step instructions to deploy a Hello World web application using Cloudflare Workers and Pulumi infrastructure as code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. :::note - You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. - ::: ## Before you begin @@ -35,7 +33,7 @@ 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. - A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. -- A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) is configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) +- A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) - A domain name. You may use `example.com` to complete the tutorial. ## 1. Initialize Pulumi @@ -150,7 +148,7 @@ At this point, you have not defined any resources so you'll have an empty stack. TODO next step here -## Add a Worker +## 2. Add a Worker You will now add the Pulumi Cloudflare package and a Cloudflare Worker to your Pulumi program. @@ -268,7 +266,7 @@ export const script = new cloudflare.WorkerScript("hello-world-script", { content: fs.readFileSync("./app/worker.ts", "utf8"), }); ``` - + TODO -- ADD OTHER LANGUAGES @@ -279,7 +277,7 @@ TODO -- ADD OTHER LANGUAGES pulumi up --yes --stack dev ``` -## Add a Worker route +## 3. Add a Worker route You will now add a Worker Route to the Pulumi stack, `dev` so the script can have an endpoint. @@ -314,7 +312,7 @@ export const route = new cloudflare.WorkerRoute("hello-world-route", { ``` -## Add a DNS record +## 4. Add a DNS record You will now add a DNS record to your domain so the previously configured route can be accessed via a URL. @@ -370,7 +368,7 @@ The last line in the code will create an output with the endpoint for the Hello pulumi up --yes ``` -## Test the app +## 5. Test the app You have incrementally added all the Cloudflare resources needed to run and access your Hello World application. This was done by defining the resources in TypeScript and letting Pulumi handle the rest. @@ -407,7 +405,7 @@ Depending on your domain settings, you may need to use "http" instead. ::: -## Clean up +## 6. Clean up In this last step, you will run a couple of commands to clean up the resources and stack you used throughout the tutorial. diff --git a/src/content/docs/pulumi/tutorial/manage-secrets.mdx b/src/content/docs/pulumi/tutorial/manage-secrets.mdx index 13fcb676fbe8ba..3c2ebceceb061d 100644 --- a/src/content/docs/pulumi/tutorial/manage-secrets.mdx +++ b/src/content/docs/pulumi/tutorial/manage-secrets.mdx @@ -27,7 +27,7 @@ Ensure you have: - The [Pulumi ESC CLI](https://www.pulumi.com/docs/install/esc/) installed. - A Wrangler project. To create one, follow the [Create a New Worker project step](/workers/get-started/guide/#1-create-a-new-worker-project). -## Set up a new Environment +## 1. Set up a new Environment A [Pulumi ESC Environment](https://www.pulumi.com/docs/esc/environments/), or Environment, is a YAML file containing configurations and secrets for your application and infrastructure. These can be accessed in several ways, including shell commands. All ESC Environments reside in your Pulumi Cloud account. @@ -58,7 +58,7 @@ esc env init $ESC_ENV Environment created. ``` -## Log into Cloudflare +## 2. Log into Cloudflare Now that the Pulumi ESC Environment has been created, it can be consumed in various ways. For instance, to log into your Cloudflare account without needing to predefine credentials in your shell. @@ -80,7 +80,7 @@ esc env set $ESC_ENV environmentVariables.CLOUDFLARE_API_TOKEN 123abc --secret The API token is declared as a `secret`. Once the Environment is saved, Pulumi will encrypt its value and replace it with ciphertext. ::: -### a. Log out +### b. Log out Ensure you're not currently logged in to your Cloudflare account. @@ -92,7 +92,7 @@ npx wrangler logout Not logged in, exiting... ``` -### a. Log in +### c. Log in Pass ESC-stored Cloudflare credentials to Wrangler. @@ -107,7 +107,7 @@ Getting User settings... When you use the `esc run` command, it opens the Environment and sets the specified Environment variables into a temporary environment. After that, it uses those variables in the context of the `wrangler` command. This is especially helpful when running `wrangler` commands in a CI/CD environment but wanting to avoid storing credentials directly in your pipeline. -## Add Worker secrets +## 3, Add Worker secrets Pulumi ESC centralizes secrets, and Wrangler can be used to pass them on to Workers and other Cloudflare resources. You will use the `wrangler secret put` command for this purpose. @@ -125,7 +125,7 @@ esc run -i ${ESC_ENV} -- sh -c 'echo "$TOP_SECRET" | npx wrangler secret put TOP By using an external secrets management solution, commonly used Worker secrets can be stored in a single shared Environment that is accessed by the relevant Workers. You can use shell commands with `esc` to incorporate scripting and integrate them into deployment pipelines or `make` commands. Use `esc [command] --help` for more information about the various commands available in the CLI. -## Load `.dev.vars` +## 4, Load `.dev.vars` In this step, you will configure an Environment to load your `.dev.vars` file programmatically. From 07486892a803efc8c8574b7fe4a062cef258f734 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Wed, 11 Sep 2024 20:55:47 -0500 Subject: [PATCH 03/17] wip --- src/content/docs/pulumi/tutorial/add-site.mdx | 3 + .../docs/pulumi/tutorial/hello-world.mdx | 158 +++++------------- 2 files changed, 48 insertions(+), 113 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index 78aa0c8f56d823..1e6ef3cfc34ba5 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -155,6 +155,9 @@ pulumi env open $E "domain": "example.com" } } + +# Add the ESC Environment to your Pulumi stack +pulumi config env add $E --yes --non-interactive ``` ### e. Create a stack diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index bfdd015f226ac5..cb9a19325c0928 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -57,14 +57,10 @@ pulumi login ### c. Create a program -:::note - A Pulumi program is code written in a [supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) that defines infrastructure resources. -::: To create a program, select your language of choice and run the `pulumi` command: - ```sh @@ -115,27 +111,37 @@ pulumi new yaml --name serverless-cloudflare --yes -### d. Save your settings +### d. Save your application settings -You will need: +In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is a YAML file containing configurations and secrets. These can be accessed in several ways, including a Pulumi program. All ESC Environments security reside in your Pulumi Cloud account and can be fully managed via the Pulumi CLI. For this tutorial, you will save the following: - Your Cloudflare [account ID](/fundamentals/setup/find-account-and-zone-ids/). - A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). - A domain. For instance, `example.com`. -:::note +```sh +# Define an ESC Environment name +E=my-dev-env -A Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/) is a YAML file containing configurations and secrets that pertain to your application and infrastructure. These can be accessed in several ways, including a Pulumi program. All ESC Environments reside in your Pulumi Cloud account. -::: +# Create a new Pulumi ESC Environment +pulumi config env init --env $E --yes --stack dev -todo todo todo todo todo todo!! +# Replace abc123 with your Cloudflare account ID +pulumi env set $E --plaintext pulumiConfig.accountId abc123 -### e. Create a stack +# Replace API_TOKEN with your Cloudflare API token +pulumi env set $E --secret pulumiConfig.cloudflare:apiToken API_TOKEN -:::note +# Replace example.com with your registered domain, or leave as is +pulumi env set $E --plaintext pulumiConfig.domain example.com + +# Add the ESC Environment to your Pulumi stack +pulumi config env add $E --yes --non-interactive +``` + +### e. Create a stack A Pulumi [stack](https://www.pulumi.com/docs/concepts/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: @@ -146,14 +152,11 @@ pulumi up --yes --stack dev At this point, you have not defined any resources so you'll have an empty stack. -TODO next step here - -## 2. Add a Worker - -You will now add the Pulumi Cloudflare package and a Cloudflare Worker to your Pulumi program. +### f. Install the Cloudflare package +In order to define Cloudflare resources in your Pulumi program, you need to install the Cloudflare package for your language of choice. -### a. Install dependencies +Install the Cloudflare package by running the following command: @@ -214,7 +217,7 @@ Below are Apache Maven instructions. For other Java project managers such as Gra ``` -1. Run: +3. Run: ```sh mvn clean install @@ -244,7 +247,7 @@ There are no dependencies to download for YAML. Skip ahead. -### b. Modify the program +## 2. Add a Worker Replace the contents of your entrypoint file with the following: @@ -253,56 +256,32 @@ Replace the contents of your entrypoint file with the following: ```typescript import * as pulumi from "@pulumi/pulumi"; import * as cloudflare from "@pulumi/cloudflare"; -import * as fs from "fs"; const config = new pulumi.Config(); const accountId = config.require("accountId"); +const domain = config.require("domain"); // A Worker script to invoke export const script = new cloudflare.WorkerScript("hello-world-script", { accountId: accountId, name: "hello-world", // Read the content of the worker from a file - content: fs.readFileSync("./app/worker.ts", "utf8"), + // content: fs.readFileSync("./app/worker.ts", "utf8"), // TODO: Use inline code }); ``` + TODO -- ADD OTHER LANGUAGES - -### b. Apply the changes - -```sh -pulumi up --yes --stack dev -``` - ## 3. Add a Worker route You will now add a Worker Route to the Pulumi stack, `dev` so the script can have an endpoint. -### a. Add Worker Route to index.ts - -Replace the contents of your `index.ts` file with the following: +Append the following code to your entrypoint file: + ```typescript -import * as pulumi from "@pulumi/pulumi"; -import * as cloudflare from "@pulumi/cloudflare"; -import * as fs from "fs"; - -const config = new pulumi.Config(); -const accountId = config.require("accountId"); -const zoneId = config.require("zoneId"); -const domain = config.require("domain"); - -// A Worker script to invoke -export const script = new cloudflare.WorkerScript("hello-world-script", { - accountId: accountId, - name: "hello-world", - // Read the content of the worker from a file - content: fs.readFileSync("./app/worker.ts", "utf8"), -}); - // A Worker route to serve requests and the Worker script export const route = new cloudflare.WorkerRoute("hello-world-route", { zoneId: zoneId, @@ -310,40 +289,15 @@ export const route = new cloudflare.WorkerRoute("hello-world-route", { scriptName: script.name, }); ``` - + ## 4. Add a DNS record -You will now add a DNS record to your domain so the previously configured route can be accessed via a URL. - +You will now add a DNS record so the previously configured route can be accessed via a URL. -Replace the contents of your `index.ts` file with the following: +Append the following code to your entrypoint file: ```typescript -import * as pulumi from "@pulumi/pulumi"; -import * as cloudflare from "@pulumi/cloudflare"; -import * as fs from "fs"; - -const config = new pulumi.Config(); -const accountId = config.require("accountId"); -const zoneId = config.require("zoneId"); -const domain = config.require("domain"); - -// A Worker script to invoke -export const script = new cloudflare.WorkerScript("hello-world-script", { - accountId: accountId, - name: "hello-world", - // Read the content of the worker from a file - content: fs.readFileSync("./app/worker.ts", "utf8"), -}); - -// A Worker route to serve requests and the Worker script -export const route = new cloudflare.WorkerRoute("hello-world-route", { - zoneId: zoneId, - pattern: "hello-world." + domain, - scriptName: script.name, -}); - // A DNS record to access the route from the domain export const record = new cloudflare.Record("hello-world-record", { zoneId: zoneId, @@ -356,58 +310,36 @@ export const record = new cloudflare.Record("hello-world-record", { export const url = route.pattern; ``` -:::note +## 5. Deploy the changes -The last line in the code will create an output with the endpoint for the Hello World app. - -::: +Now that you have defined the resources, you can deploy the changes to your Cloudflare account using the Pulumi CLI. -### b. Apply the changes +To deploy the changes, run: ```sh -pulumi up --yes +$ pulumi up --yes +waiting for stack to become ready ``` -## 5. Test the app +## 6. Test the Worker -You have incrementally added all the Cloudflare resources needed to run and access your Hello World application. This was done by defining the resources in TypeScript and letting Pulumi handle the rest. - -You can test your application via the terminal or browser. - -- In the terminal +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. ```sh -pulumi stack output url -``` - - -```sh -curl "https://$(pulumi stack output url)" -``` - -```sh output - - - - Hello World - - -

Serverless with Pulumi

-

The current time is: Thu Oct 05 2023 22:02:17 GMT+0000 (Coordinated Universal Time).

- - - +$ pulumi stack output url +$ curl "https://$(pulumi stack output url)" +TODO ``` :::note -Depending on your domain settings, you may need to use "http" instead. +Depending on your domain settings, you may need to use "http" in the curl command instead. ::: ## 6. Clean up -In this last step, you will run a couple of commands to clean up the resources and stack you used throughout the tutorial. +In this last step, you will clean up the resources and stack used throughout the tutorial. ### a. Delete the Cloudflare resources @@ -423,4 +355,4 @@ pulumi stack rm dev ## Next steps -TODO \ No newline at end of file +Explore other resources you can define with Pulumi and Cloudflare by visiting the [Cloudflare package documentation](https://www.pulumi.com/docs/reference/pkg/cloudflare/). \ No newline at end of file From e0d7b74b64a4baa8c2a9a6c34cc1334065fe46a8 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Wed, 11 Sep 2024 21:14:13 -0500 Subject: [PATCH 04/17] wip --- src/content/docs/pulumi/tutorial/add-site.mdx | 24 +++--------- .../docs/pulumi/tutorial/hello-world.mdx | 38 ++++++++++--------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index 1e6ef3cfc34ba5..dbe32de0b85754 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -135,7 +135,7 @@ A Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/) is a Y E=my-dev-env # Create a new Pulumi ESC Environment -pulumi config env init --env $E --yes --stack dev +pulumi config env init --env $E --yes # Replace API_TOKEN with your Cloudflare API Token pulumi env set $E --secret pulumiConfig.cloudflare:apiToken API_TOKEN @@ -170,7 +170,7 @@ A Pulumi [stack](https://www.pulumi.com/docs/concepts/stack/) is an instance of To instantiate your `dev` stack, run: ```sh -pulumi up --yes --stack dev +pulumi up --yes # wait a few seconds for the stack to be instantiated. ``` @@ -470,22 +470,10 @@ outputs: ### c. Apply the changes ```sh -pulumi up --yes --stack dev +pulumi up --yes # wait a few seconds while the changes take effect ``` -### d. (Optional) Review the zone - -Review the value of `zoneId` to confirm the Zone creation. - -```sh -pulumi stack output zoneId -``` - -```sh output -d8fcb6d731fe1c2d75e2e8d6ad63fad5 -``` - ## 3. Update your nameservers Once you have added a domain to Cloudflare, that domain will receive two assigned authoritative nameservers. @@ -565,7 +553,7 @@ status: ${exampleZone.status} ### b. Apply the changes ```sh -pulumi up --yes --stack dev +pulumi up --yes ``` ### c. Obtain the nameservers @@ -573,7 +561,7 @@ pulumi up --yes --stack dev Review the value of `nameservers` to retrieve the assigned nameservers: ```sh -pulumi stack output --stack dev +pulumi stack output ``` ### d. Update your registrar @@ -883,7 +871,7 @@ outputs: ### b. Apply the changes ```sh -pulumi up --yes --stack dev +pulumi up --yes ``` ## 5. Verify your setup diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index cb9a19325c0928..b4cb5a1bb94b53 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -20,6 +20,8 @@ head: content: Deploy a Worker --- +import { TabItem, Tabs } from "~/components"; + In this tutorial, you will go through step-by-step instructions to deploy a Hello World web application using Cloudflare Workers and Pulumi infrastructure as code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. :::note @@ -111,7 +113,20 @@ pulumi new yaml --name serverless-cloudflare --yes -### d. Save your application settings +### e. Create a stack + +A Pulumi [stack](https://www.pulumi.com/docs/concepts/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: + +```sh +pulumi up --yes +# wait a few seconds for the stack to be instantiated. +``` + +At this point, you have not defined any resources so you'll have an empty stack. + +### e. Save your application settings In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is a YAML file containing configurations and secrets. These can be accessed in several ways, including a Pulumi program. All ESC Environments security reside in your Pulumi Cloud account and can be fully managed via the Pulumi CLI. For this tutorial, you will save the following: @@ -124,7 +139,7 @@ In this step, you will store your application settings in a Pulumi [ESC Environm E=my-dev-env # Create a new Pulumi ESC Environment -pulumi config env init --env $E --yes --stack dev +pulumi config env init --env $E --yes # Replace abc123 with your Cloudflare account ID pulumi env set $E --plaintext pulumiConfig.accountId abc123 @@ -139,19 +154,6 @@ pulumi env set $E --plaintext pulumiConfig.domain example.com pulumi config env add $E --yes --non-interactive ``` -### e. Create a stack - -A Pulumi [stack](https://www.pulumi.com/docs/concepts/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: - -```sh -pulumi up --yes --stack dev -# wait a few seconds for the stack to be instantiated. -``` - -At this point, you have not defined any resources so you'll have an empty stack. - ### f. Install the Cloudflare package In order to define Cloudflare resources in your Pulumi program, you need to install the Cloudflare package for your language of choice. @@ -318,7 +320,7 @@ To deploy the changes, run: ```sh $ pulumi up --yes -waiting for stack to become ready +wait for stack to become ready ``` ## 6. Test the Worker @@ -337,7 +339,7 @@ Depending on your domain settings, you may need to use "http" in the curl comman ::: -## 6. Clean up +## 7. Clean up In this last step, you will clean up the resources and stack used throughout the tutorial. @@ -355,4 +357,4 @@ pulumi stack rm dev ## Next steps -Explore other resources you can define with Pulumi and Cloudflare by visiting the [Cloudflare package documentation](https://www.pulumi.com/docs/reference/pkg/cloudflare/). \ No newline at end of file +Explore other resources you can define with Pulumi and Cloudflare by visiting the [Cloudflare package documentation](https://www.pulumi.com/docs/reference/pkg/cloudflare/). From 953f89a390aabdb464210dbe5890664a83c41f0d Mon Sep 17 00:00:00 2001 From: diana esteves Date: Wed, 11 Sep 2024 21:37:24 -0500 Subject: [PATCH 05/17] wip --- src/content/docs/pulumi/tutorial/add-site.mdx | 4 +- .../docs/pulumi/tutorial/hello-world.mdx | 137 ++++++++++++++++-- 2 files changed, 126 insertions(+), 15 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index dbe32de0b85754..4366dd71fe2463 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -210,7 +210,7 @@ added 1 package ... ```sh -echo "pulumi_cloudflare>=5.35,<6.0.0" >> requirements.txt +echo "pulumi_cloudflare>=5.38,<6.0.0" >> requirements.txt source venv/bin/activate pip install -r requirements.txt ``` @@ -242,7 +242,7 @@ Below are Apache Maven instructions. For other Java project managers such as Gra com.pulumi cloudflare - 5.35.1 + 5.38.0 ``` diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index b4cb5a1bb94b53..6cee23b830f29f 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -183,7 +183,7 @@ added 1 package ... ```sh -echo "pulumi_cloudflare>=5.35,<6.0.0" >> requirements.txt +echo "pulumi_cloudflare>=5.38,<6.0.0" >> requirements.txt source venv/bin/activate pip install -r requirements.txt ``` @@ -215,7 +215,7 @@ Below are Apache Maven instructions. For other Java project managers such as Gra com.pulumi cloudflare - 5.35.1 + 5.38.0 ``` @@ -255,6 +255,11 @@ Replace the contents of your entrypoint file with the following: +```javascript +``` + + + ```typescript import * as pulumi from "@pulumi/pulumi"; import * as cloudflare from "@pulumi/cloudflare"; @@ -263,18 +268,53 @@ const config = new pulumi.Config(); const accountId = config.require("accountId"); const domain = config.require("domain"); +const content = ` +addEventListener('fetch', event => { + event.respondWith(handleRequest(event.request)) +}) + +async function handleRequest(request) { + return new Response('Hello, World!', { + headers: { 'content-type': 'text/plain' }, + }) +} +`; // A Worker script to invoke -export const script = new cloudflare.WorkerScript("hello-world-script", { +const script = new cloudflare.WorkerScript("hello-world-script", { accountId: accountId, name: "hello-world", // Read the content of the worker from a file - // content: fs.readFileSync("./app/worker.ts", "utf8"), // TODO: Use inline code + content: content }); ``` - + + +```python +``` + + + +```go +``` + + + +```java +``` + + + +```csharp +``` + + + +```yaml +``` -TODO -- ADD OTHER LANGUAGES + + ## 3. Add a Worker route @@ -282,7 +322,13 @@ You will now add a Worker Route to the Pulumi stack, `dev` so the script can hav Append the following code to your entrypoint file: - + + +```javascript +``` + + + ```typescript // A Worker route to serve requests and the Worker script export const route = new cloudflare.WorkerRoute("hello-world-route", { @@ -291,7 +337,32 @@ export const route = new cloudflare.WorkerRoute("hello-world-route", { scriptName: script.name, }); ``` - + + +```python +``` + + + +```go +``` + + + +```java +``` + + + +```csharp +``` + + + +```yaml +``` + + ## 4. Add a DNS record @@ -299,6 +370,14 @@ You will now add a DNS record so the previously configured route can be accessed Append the following code to your entrypoint file: + + + +```javascript +``` + + + ```typescript // A DNS record to access the route from the domain export const record = new cloudflare.Record("hello-world-record", { @@ -312,6 +391,33 @@ export const record = new cloudflare.Record("hello-world-record", { export const url = route.pattern; ``` + + +```python +``` + + + +```go +``` + + + +```java +``` + + + +```csharp +``` + + + +```yaml +``` + + + ## 5. Deploy the changes Now that you have defined the resources, you can deploy the changes to your Cloudflare account using the Pulumi CLI. @@ -319,7 +425,10 @@ Now that you have defined the resources, you can deploy the changes to your Clou To deploy the changes, run: ```sh -$ pulumi up --yes +pulumi up --yes +``` + +```sh output wait for stack to become ready ``` @@ -328,14 +437,16 @@ wait for stack to become ready 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. ```sh -$ pulumi stack output url -$ curl "https://$(pulumi stack output url)" -TODO +curl "https://$(pulumi stack output url)" +``` + +```sh output +Hello, World! ``` :::note -Depending on your domain settings, you may need to use "http" in the curl command instead. +Depending on your domain settings, you may need to use `http` in the curl command instead. ::: From b7f3e31d9aaf199c702c84064a327cf2281f22f1 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Thu, 12 Sep 2024 13:37:26 -0500 Subject: [PATCH 06/17] updated worker script code --- src/content/docs/pulumi/tutorial/add-site.mdx | 17 +- .../docs/pulumi/tutorial/hello-world.mdx | 246 ++++++++++++++---- 2 files changed, 212 insertions(+), 51 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index 4366dd71fe2463..0f0087ecc68f9d 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -10,6 +10,7 @@ languages: - .NET - YAML updated: 2024-08-02 +difficulty: Beginner sidebar: order: 1 head: @@ -136,18 +137,27 @@ E=my-dev-env # Create a new Pulumi ESC Environment pulumi config env init --env $E --yes +``` -# Replace API_TOKEN with your Cloudflare API Token -pulumi env set $E --secret pulumiConfig.cloudflare:apiToken API_TOKEN +```sh output +Creating environment my-dev-env for stack dev... +``` +```sh # 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 # Review your ESC Environment pulumi env open $E +``` + +```sh output { "pulumiConfig": { "accountId": "111222333", @@ -155,9 +165,6 @@ pulumi env open $E "domain": "example.com" } } - -# Add the ESC Environment to your Pulumi stack -pulumi config env add $E --yes --non-interactive ``` ### e. Create a stack diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 6cee23b830f29f..c453f3b4653579 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -3,7 +3,7 @@ title: Deploy a Worker pcx_content_type: tutorial products: - Workers -updated: 2024-01-08 +updated: 2024-09-12 difficulty: Beginner languages: - JavaScript @@ -22,7 +22,7 @@ head: import { TabItem, Tabs } from "~/components"; -In this tutorial, you will go through step-by-step instructions to deploy a Hello World web application using Cloudflare Workers and Pulumi infrastructure as code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. +In this tutorial, you will go through step-by-step instructions to deploy a Hello World application using Cloudflare Workers and Pulumi infrastructure as code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. :::note You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. @@ -32,13 +32,17 @@ You will provision resources that qualify under free tier offerings for both Pul 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. +- 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must have: + - `Account-Workers Scripts-Edit` permission + - `Zone-Workers Route-Edit` permission - A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) - A domain name. You may use `example.com` to complete the tutorial. -## 1. Initialize Pulumi +## 1. Initialize your project + +A Pulumi project is a collection of files in a dedicated folder that describe the infrastructure you want to create. The Pulumi project folder is identified by the presenece of the required `Pulumi.yaml` file. You will use the Pulumi CLI to create a new project and configure it. ### a. Create a directory @@ -49,7 +53,9 @@ mkdir serverless-cloudflare cd serverless-cloudflare ``` -### b. Login +### b. Login to Pulumi Cloud + +[Pulumi Cloud](https://www.pulumi.com/product/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](https://www.pulumi.com/docs/pulumi-cloud/access-management/access-tokens/). @@ -57,7 +63,7 @@ At the prompt, press Enter to log into your Pulumi Cloud account via the browser pulumi login ``` -### c. Create a program +### c. Create a new program A Pulumi program is code written in a [supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) that defines infrastructure resources. @@ -113,7 +119,7 @@ pulumi new yaml --name serverless-cloudflare --yes -### e. Create a stack +### d. Create a stack A Pulumi [stack](https://www.pulumi.com/docs/concepts/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. @@ -128,30 +134,34 @@ At this point, you have not defined any resources so you'll have an empty stack. ### e. Save your application settings -In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is a YAML file containing configurations and secrets. These can be accessed in several ways, including a Pulumi program. All ESC Environments security reside in your Pulumi Cloud account and can be fully managed via the Pulumi CLI. For this tutorial, you will save the following: +In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is 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 save the following: - Your Cloudflare [account ID](/fundamentals/setup/find-account-and-zone-ids/). - A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). - A domain. For instance, `example.com`. ```sh -# Define an ESC Environment name -E=my-dev-env +# Give your new ESC Environment a name +E=hello-world-dev-env -# Create a new Pulumi ESC Environment +# Initialize the new ESC Environment pulumi config env init --env $E --yes +``` + +```sh output +Creating environment hello-world-dev-env for stack dev... +``` +```sh # 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 +pulumi env set $E --secret pulumiConfig.cloudflare:apiToken API_TOKEN +# TODO CHECK IF THIS IS NEEDED? # Replace example.com with your registered domain, or leave as is pulumi env set $E --plaintext pulumiConfig.domain example.com - -# Add the ESC Environment to your Pulumi stack -pulumi config env add $E --yes --non-interactive ``` ### f. Install the Cloudflare package @@ -189,9 +199,7 @@ pip install -r requirements.txt ``` ```sh output -... -Collecting pulumi-cloudflare -... +...Collecting pulumi-cloudflare... ``` @@ -226,9 +234,7 @@ mvn clean install ``` ```sh output -... -[INFO] BUILD SUCCESS -... +...[INFO] BUILD SUCCESS... ``` @@ -249,13 +255,39 @@ There are no dependencies to download for YAML. Skip ahead. -## 2. Add a Worker +## 3. Define Cloudflare resources in code + +With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. You'll define a Worker script and a Worker route to serve requests. + +### a. Add a Workers Script + +The [Workers Script resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersscript/) represents a Cloudflare Worker that can be deployed to the Cloudflare network. Replace the contents of your entrypoint file with the following: ```javascript +"use strict"; +const pulumi = require("@pulumi/pulumi"); +const cloudflare = require("@pulumi/cloudflare"); + +const config = new pulumi.Config(); +const accountId = config.require("accountId"); + +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 +}); ``` @@ -266,59 +298,181 @@ import * as cloudflare from "@pulumi/cloudflare"; const config = new pulumi.Config(); const accountId = config.require("accountId"); -const domain = config.require("domain"); -const content = ` -addEventListener('fetch', event => { - event.respondWith(handleRequest(event.request)) -}) - -async function handleRequest(request) { - return new Response('Hello, World!', { - headers: { 'content-type': 'text/plain' }, - }) -} -`; -// A Worker script to invoke -const script = new cloudflare.WorkerScript("hello-world-script", { - accountId: accountId, - name: "hello-world", - // Read the content of the worker from a file - content: content +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 }); ``` ```python +"""Pulumi program """ +import pulumi +import pulumi_cloudflare as cloudflare + +CONFIG = pulumi.Config() +ACCOUNT_ID = CONFIG.get("accountId") +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-py", + content=CONTENT, + module=True # ES6 module +) ``` ```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") + content := ` + export default { + async fetch(request) { + const options = { headers: { 'content-type': 'text/plain' } }; + return new Response("Hello World!", options); + }, + }; + ` + _, err := cloudflare.NewWorkersScript(ctx, "hello-world-worker", &cloudflare.WorkersScriptArgs{ + AccountId: pulumi.String(accountId), + Name: pulumi.String("hello-world-worker-go"), + Content: pulumi.String(content), + Module: pulumi.Bool(true), // ES6 module + }) + if err != nil { + return err + } + + return nil + }) +} ``` ```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 helloWorldWorker = new WorkersScript("hello-world-worker", WorkersScriptArgs.builder() + .accountId(accountId) + .name("hello-world-worker-java") + .content(content) + .module(true) + .build()); + + return; + }); + } +} ``` ```csharp +using Pulumi; +using Cloudflare = Pulumi.Cloudflare; + +return await Deployment.RunAsync(() => +{ + var config = new Config(); + var accountId = config.Require("accountId"); + 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-cs", + Content = content, + Module = true + }); + return; +}); ``` ```yaml +name: cloudflare-yaml +runtime: yaml +resources: + worker: + type: cloudflare:WorkersScript + properties: + accountId: "${accountId}" + name: "hello-world-worker-yaml" + content: | + export default { + async fetch(request) { + const options = { headers: { 'content-type': 'text/plain' } }; + return new Response("Hello World!", options); + }, + }; + module: true ``` - - + + +### b. Add a Worker route + +You will now add a Worker Route to the Pulumi stack, `dev` so the script can have an endpoint. This will ensure the Worker is active, you’ll also need to setup a [cloudflare.WorkerRoute](). -## 3. Add a Worker route -You will now add a Worker Route to the Pulumi stack, `dev` so the script can have an endpoint. Append the following code to your entrypoint file: @@ -364,7 +518,7 @@ export const route = new cloudflare.WorkerRoute("hello-world-route", { -## 4. Add a DNS record +### c. Add a DNS record You will now add a DNS record so the previously configured route can be accessed via a URL. @@ -418,7 +572,7 @@ export const url = route.pattern; -## 5. Deploy the changes +## 5. Deploy your application Now that you have defined the resources, you can deploy the changes to your Cloudflare account using the Pulumi CLI. From 9d6733a63f4d660c4b40ca891228f37ec25db983 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Thu, 12 Sep 2024 17:06:46 -0500 Subject: [PATCH 07/17] updated route code --- .../docs/pulumi/tutorial/hello-world.mdx | 156 +++++++++++++----- 1 file changed, 118 insertions(+), 38 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index c453f3b4653579..133c03fafb9927 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -38,7 +38,7 @@ Ensure you have: - A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) -- A domain name. You may use `example.com` to complete the tutorial. +- A Cloudflare-managed domain. Complete the [Add a site tutorial](pulumi/tutorial/add-site/) to bring your existing domain under Cloudflare. ## 1. Initialize your project @@ -159,8 +159,7 @@ 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 -# TODO CHECK IF THIS IS NEEDED? -# Replace example.com with your registered domain, or leave as is +# Replace example.com with your domain pulumi env set $E --plaintext pulumiConfig.domain example.com ``` @@ -259,9 +258,9 @@ There are no dependencies to download for YAML. Skip ahead. With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. You'll define a Worker script and a Worker route to serve requests. -### a. Add a Workers Script +### a. Add a Workers script -The [Workers Script resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersscript/) represents a Cloudflare Worker that can be deployed to the Cloudflare network. +The [Workers Script resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersscript/) represents a Cloudflare Worker that can be deployed to the Cloudflare network. Replace the contents of your entrypoint file with the following: @@ -274,6 +273,7 @@ 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) { @@ -298,6 +298,7 @@ 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) { @@ -323,6 +324,7 @@ import pulumi_cloudflare as cloudflare CONFIG = pulumi.Config() ACCOUNT_ID = CONFIG.get("accountId") +DOMAIN = CONFIG.require("domain") CONTENT = """ export default { async fetch(request) { @@ -334,7 +336,7 @@ export default { worker = cloudflare.WorkersScript("hello-world-worker", account_id=ACCOUNT_ID, - name="hello-world-worker-py", + name="hello-world-worker", content=CONTENT, module=True # ES6 module ) @@ -354,7 +356,8 @@ import ( func main() { pulumi.Run(func(ctx *pulumi.Context) error { conf := config.New(ctx, "") - accountId := conf.Get("accountId") + accountID := conf.Get("accountId") + domain := conf.Get("domain") content := ` export default { async fetch(request) { @@ -364,8 +367,8 @@ func main() { }; ` _, err := cloudflare.NewWorkersScript(ctx, "hello-world-worker", &cloudflare.WorkersScriptArgs{ - AccountId: pulumi.String(accountId), - Name: pulumi.String("hello-world-worker-go"), + AccountId: pulumi.String(accountID), + Name: pulumi.String("hello-world-worker"), Content: pulumi.String(content), Module: pulumi.Bool(true), // ES6 module }) @@ -392,19 +395,19 @@ 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); - }, - }; - """; + 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 helloWorldWorker = new WorkersScript("hello-world-worker", WorkersScriptArgs.builder() + var domain = ctx.config().require("domain"); + var worker = new WorkersScript("hello-world-worker", WorkersScriptArgs.builder() .accountId(accountId) - .name("hello-world-worker-java") + .name("hello-world-worker") .content(content) .module(true) .build()); @@ -425,6 +428,7 @@ 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) { @@ -437,7 +441,7 @@ return await Deployment.RunAsync(() => var worker = new Cloudflare.WorkersScript("hello-world-worker", new() { AccountId = accountId, - Name = "hello-world-worker-cs", + Name = "hello-world-worker", Content = content, Module = true }); @@ -448,14 +452,14 @@ return await Deployment.RunAsync(() => ```yaml -name: cloudflare-yaml +name: serverless-cloudflare runtime: yaml resources: worker: type: cloudflare:WorkersScript properties: accountId: "${accountId}" - name: "hello-world-worker-yaml" + name: "hello-world-worker" content: | export default { async fetch(request) { @@ -468,62 +472,139 @@ resources: -### b. Add a Worker route - -You will now add a Worker Route to the Pulumi stack, `dev` so the script can have an endpoint. This will ensure the Worker is active, you’ll also need to setup a [cloudflare.WorkerRoute](). +### b. Add a Route +You will now add a [Workers Route resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersroute/) to your Pulumi program so the Workers script can have an endpoint and be active. To properly configure the Route, you will also look up the zone ID for your domain. - -Append the following code to your entrypoint file: +Append the following code to your entrypoint file after the Worker script resource: ```javascript +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, +}); ``` ```typescript -// A Worker route to serve requests and the Worker script -export const route = new cloudflare.WorkerRoute("hello-world-route", { - zoneId: zoneId, - pattern: "hello-world." + domain, - scriptName: script.name, +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, }); ``` ```python +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 +) ``` ```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 +} ``` ```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()); ``` ```csharp +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, +}); ``` +Below the `runtime` key, add the following code: ```yaml +# new top-level section +variables: + zone: + fn::invoke: + function: cloudflare:getZone + arguments: + accountId: ${accountId} + name: ${domain} ``` - +Below the `worker` resource, add the following code: +```yaml + route: + type: cloudflare:WorkersRoute + properties: + zoneId: ${zone.id} + pattern: "hello-world.${domain}" + scriptName: ${worker.name} +``` -### c. Add a DNS record + -You will now add a DNS record so the previously configured route can be accessed via a URL. +### c. Add a Record -Append the following code to your entrypoint file: +You will now add a [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Route can be resolved. You'll also export the URL of your Route so it can be easily found. +Append the following code to your entrypoint file after the Route resource: @@ -533,8 +614,7 @@ Append the following code to your entrypoint file: ```typescript -// A DNS record to access the route from the domain -export const record = new cloudflare.Record("hello-world-record", { +const record = new cloudflare.Record("hello-world-record", { zoneId: zoneId, name: script.name, value: "192.0.2.1", From 50da0dc7322c42f91659dfa17aa8542657152542 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 10:52:48 -0500 Subject: [PATCH 08/17] updated code --- src/content/docs/pulumi/tutorial/add-site.mdx | 1 - .../docs/pulumi/tutorial/hello-world.mdx | 561 +++++++++++++++++- 2 files changed, 537 insertions(+), 25 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index 0f0087ecc68f9d..ad2adffd78b274 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -23,7 +23,6 @@ import { TabItem, Tabs } from "~/components"; In this tutorial, you will go through step-by-step instructions to bring an existing site to Cloudflare using Pulumi Infrastructure as Code (IaC) so that you can become familiar 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](/fundamentals/setup/manage-domains/add-site/). :::note - You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. ::: diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 133c03fafb9927..3c094b79050c7c 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -35,10 +35,11 @@ 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must have: - `Account-Workers Scripts-Edit` permission - `Zone-Workers Route-Edit` permission + - `Zone-DNS-Edit` permission - A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) -- A Cloudflare-managed domain. Complete the [Add a site tutorial](pulumi/tutorial/add-site/) to bring your existing domain under Cloudflare. +- A Cloudflare-managed domain. Complete the [Add a site tutorial](/pulumi/tutorial/add-site/) to bring your existing domain under Cloudflare. ## 1. Initialize your project @@ -134,7 +135,7 @@ At this point, you have not defined any resources so you'll have an empty stack. ### e. Save your application settings -In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is 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 save the following: +In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is 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](/fundamentals/setup/find-account-and-zone-ids/). - A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). @@ -256,7 +257,7 @@ There are no dependencies to download for YAML. Skip ahead. ## 3. Define Cloudflare resources in code -With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. You'll define a Worker script and a Worker route to serve requests. +With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. You'll define a Worker, a Route, and a DNS Record next. ### a. Add a Workers script @@ -266,6 +267,8 @@ Replace the contents of your entrypoint file with the following: +**Filename: `index.js`** + ```javascript "use strict"; const pulumi = require("@pulumi/pulumi"); @@ -292,6 +295,8 @@ const worker = new cloudflare.WorkersScript("hello-world-worker", { +**Filename: `index.ts`** + ```typescript import * as pulumi from "@pulumi/pulumi"; import * as cloudflare from "@pulumi/cloudflare"; @@ -317,6 +322,8 @@ const worker = new cloudflare.WorkersScript("hello-world-worker", { +**Filename: `__main__.py`** + ```python """Pulumi program """ import pulumi @@ -344,6 +351,8 @@ worker = cloudflare.WorkersScript("hello-world-worker", +**Filename: `main.go`** + ```go package main @@ -366,7 +375,7 @@ func main() { }, }; ` - _, err := cloudflare.NewWorkersScript(ctx, "hello-world-worker", &cloudflare.WorkersScriptArgs{ + worker, err := cloudflare.NewWorkersScript(ctx, "hello-world-worker", &cloudflare.WorkersScriptArgs{ AccountId: pulumi.String(accountID), Name: pulumi.String("hello-world-worker"), Content: pulumi.String(content), @@ -383,6 +392,8 @@ func main() { +**Filename: `src/main/java/myproject/App.java`** + ```java package myproject; @@ -420,6 +431,8 @@ public class App { +**Filename: `Program.cs`** + ```csharp using Pulumi; using Cloudflare = Pulumi.Cloudflare; @@ -451,6 +464,8 @@ return await Deployment.RunAsync(() => +**Filename: `Pulumi.yaml`** + ```yaml name: serverless-cloudflare runtime: yaml @@ -476,15 +491,17 @@ resources: You will now add a [Workers Route resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersroute/) to your Pulumi program so the Workers script can have an endpoint and be active. To properly configure the Route, you will also look up the zone ID for your domain. -Append the following code to your entrypoint file after the Worker script resource: +Add the following code snippet to your entrypoint file **after** the Worker script resource: +**Filename: `index.js`** + ```javascript const zone = cloudflare.getZone({ accountId: accountId, name: domain -}) +}); const zoneId = zone.then(z => z.zoneId); @@ -497,6 +514,8 @@ const route = new cloudflare.WorkersRoute("hello-world-route", { +**Filename: `index.ts`** + ```typescript const zone = cloudflare.getZone({ accountId: accountId, @@ -513,6 +532,8 @@ const route = new cloudflare.WorkersRoute("hello-world-route", { ``` +**Filename: `__main__.py`** + ```python zone = cloudflare.get_zone(account_id=ACCOUNT_ID, name=DOMAIN) zone_id = zone.zone_id @@ -525,6 +546,8 @@ route = cloudflare.WorkersRoute("hello-world-route", +**Filename: `main.go`** + ```go zone, err := cloudflare.LookupZone(ctx, &cloudflare.LookupZoneArgs{ AccountId: &accountID, @@ -534,7 +557,7 @@ if err != nil { return err } -route, err = cloudflare.NewWorkersRoute(ctx, "hello-world-route", &cloudflare.WorkersRouteArgs{ +route, err := cloudflare.NewWorkersRoute(ctx, "hello-world-route", &cloudflare.WorkersRouteArgs{ ZoneId: pulumi.String(zone.Id), Pattern: pulumi.String("hello-world." + domain), ScriptName: worker.Name, @@ -546,6 +569,8 @@ if err != nil { +**Filename: `src/main/java/myproject/App.java`** + ```java final var zone = CloudflareFunctions.getZone(GetZoneArgs.builder() .accountId(accountId) @@ -560,6 +585,8 @@ var route = new WorkersRoute("hello-world-route", WorkersRouteArgs.builder() +**Filename: `Program.cs`** + ```csharp var zone = Output.Create(Cloudflare.GetZone.InvokeAsync(new() { @@ -576,6 +603,8 @@ var route = new Cloudflare.WorkersRoute("hello-world-route", new() +**Filename: `Pulumi.yaml`** + Below the `runtime` key, add the following code: ```yaml # new top-level section @@ -600,61 +629,550 @@ Below the `worker` resource, add the following code: -### c. Add a Record +### c. Add a DNS Record -You will now add a [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Route can be resolved. You'll also export the URL of your Route so it can be easily found. +You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Route can be resolved. You'll also output the Route URL so it can be easily accessed in the next step. -Append the following code to your entrypoint file after the Route resource: +Add the following code snippet to your entrypoint file **after** the Route resource: +**Filename: `index.js`** + ```javascript +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`** + ```typescript const record = new cloudflare.Record("hello-world-record", { - zoneId: zoneId, - name: script.name, - value: "192.0.2.1", - type: "A", - proxied: true, + name: route.pattern, + type: "A", + content: "192.0.2.1", + zoneId: zoneId, + proxied: true, }); -export const url = route.pattern; +export const url = pulumi.interpolate`https://${record.hostname}`; ``` +**Filename: `__main__.py`** + ```python +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`** + ```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`** + ```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`** + +Because you're now exporting a value, notice the updated `return` statement. Ensure to also include `using System.Collections.Generic;` in your imports. + ```csharp +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 +{ + ["url"] = Output.Format($"https://{record.Hostname}") +}; ``` +Notice the new top-level `outputs` section. + ```yaml + 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 + +Depending on your domain settings, you may need to use `http` instead. + +::: + +### d. (Optional) Verify your code + +Confirm all your changes match the full solution below: + + + + +**Filename: `index.js`** + +```javascript +"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`** + +```typescript +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`** + +```python +"""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`** + +```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`** + +```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`** + +```csharp +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 + { + ["url"] = Output.Format($"https://{record.Hostname}") + }; +}); + +``` + + + +**Filename: `Pulumi.yaml`** + +```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}" +``` + + + ## 5. Deploy your application -Now that you have defined the resources, you can deploy the changes to your Cloudflare account using the Pulumi CLI. +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: @@ -663,7 +1181,7 @@ pulumi up --yes ``` ```sh output -wait for stack to become ready +wait for the dev stack to become ready ``` ## 6. Test the Worker @@ -671,18 +1189,13 @@ wait for stack to become ready 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. ```sh -curl "https://$(pulumi stack output url)" +curl $(pulumi stack output url) ``` ```sh output Hello, World! ``` -:::note - -Depending on your domain settings, you may need to use `http` in the curl command instead. - -::: ## 7. Clean up From 1c37cc5bcdb3b4abea35a38f3bcadb03b2d25727 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 12:09:20 -0500 Subject: [PATCH 09/17] update tutorial flow --- src/content/docs/pulumi/tutorial/add-site.mdx | 554 ++++++------------ .../docs/pulumi/tutorial/hello-world.mdx | 10 +- 2 files changed, 169 insertions(+), 395 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index ad2adffd78b274..0f8fd4a50e0be8 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -9,7 +9,7 @@ languages: - Java - .NET - YAML -updated: 2024-08-02 +updated: 2024-09-13 difficulty: Beginner sidebar: order: 1 @@ -20,7 +20,7 @@ head: import { TabItem, Tabs } from "~/components"; -In this tutorial, you will go through step-by-step instructions to bring an existing site to Cloudflare using Pulumi Infrastructure as Code (IaC) so that you can become familiar 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](/fundamentals/setup/manage-domains/add-site/). +In this tutorial, you will go through step-by-step instructions to bring an existing site to Cloudflare using Pulumi infrastructure as code (IaC) so that you can become familiar 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](/fundamentals/setup/manage-domains/add-site/). :::note You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. @@ -39,7 +39,10 @@ Ensure you have: - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) 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 Pulumi +## 1. Initialize your project + +A Pulumi project is a collection of files in a dedicated folder that describe the infrastructure you want to create. The Pulumi project folder is identified by the presenece of the required `Pulumi.yaml` file. You will use the Pulumi CLI to create a new project and configure it. + ### a. Create a directory @@ -50,7 +53,9 @@ mkdir addsite-cloudflare cd addsite-cloudflare ``` -### b. Login +### b. Login to Pulumi Cloud + +[Pulumi Cloud](https://www.pulumi.com/product/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](https://www.pulumi.com/docs/pulumi-cloud/access-management/access-tokens/). @@ -58,12 +63,9 @@ At the prompt, press Enter to log into your Pulumi Cloud account via the browser pulumi login ``` -### c. Create a program - -:::note +### c. Create a new program A Pulumi program is code written in a [supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) that defines infrastructure resources. -::: To create a program, select your language of choice and run the `pulumi` command: @@ -117,19 +119,27 @@ pulumi new yaml --name addsite-cloudflare --yes -### d. Save your settings +### d. Create a stack + +A Pulumi [stack](https://www.pulumi.com/docs/concepts/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: + +```sh +pulumi up --yes +# wait a few seconds for the stack to be instantiated. +``` + +At this point, you have not defined any resources so you'll have an empty stack. + +### e. Save your settings -You will need: +In this step, you will store your settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is 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](/fundamentals/setup/find-account-and-zone-ids/). - A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). - A domain. For instance, `example.com`. -:::note - -A Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/) is a YAML file containing configurations and secrets that pertain to your application and infrastructure. These can be accessed in several ways, including a Pulumi program. All ESC Environments reside in your Pulumi Cloud account. -::: - ```sh # Define an ESC Environment name E=my-dev-env @@ -151,47 +161,13 @@ 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 - -# Review your ESC Environment -pulumi env open $E ``` -```sh output -{ - "pulumiConfig": { - "accountId": "111222333", - "cloudflare:apiToken": "abc123abc123", - "domain": "example.com" - } -} -``` - -### e. Create a stack - -:::note - -A Pulumi [stack](https://www.pulumi.com/docs/concepts/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: - -```sh -pulumi up --yes -# wait a few seconds for the stack to be instantiated. -``` - -At this point, you have not defined any resources so you'll have an empty stack. - -## 2. Add a Zone - -:::note - -A domain, or site, is known as a Zone in Cloudflare. -::: +### f. Install the Cloudflare package -You will now add the Pulumi Cloudflare package and a Cloudflare Zone resource to your Pulumi program. +In order to define Cloudflare resources in your Pulumi program, you need to install the Cloudflare package for your language of choice. -### a. Install dependencies +Install the Cloudflare package by running the following command: @@ -222,9 +198,7 @@ pip install -r requirements.txt ``` ```sh output -... -Collecting pulumi-cloudflare -... +...Collecting pulumi-cloudflare... ``` @@ -252,16 +226,14 @@ Below are Apache Maven instructions. For other Java project managers such as Gra ``` -1. Run: +3. Run: ```sh mvn clean install ``` ```sh output -... -[INFO] BUILD SUCCESS -... +...[INFO] BUILD SUCCESS... ``` @@ -282,12 +254,20 @@ There are no dependencies to download for YAML. Skip ahead. -### b. Modify the program +## 2. Define Cloudflare resources in code + +With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) 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](https://www.pulumi.com/registry/packages/cloudflare/api-docs/zone/) represents a Cloudflare Zone. Replace the contents of your entrypoint file with the following: +**Filename: `index.js`** + ```js "use strict"; const pulumi = require("@pulumi/pulumi"); @@ -305,12 +285,15 @@ const zone = new cloudflare.Zone("my-zone", { jumpStart: true, }); -// Export the zone ID exports.zoneId = zone.id; +exports.nameservers = zone.nameServers; +exports.status = zone.status; ``` +**Filename: `index.ts`** + ```typescript import * as pulumi from "@pulumi/pulumi"; import * as cloudflare from "@pulumi/cloudflare"; @@ -327,12 +310,15 @@ const zone = new cloudflare.Zone("my-zone", { jumpStart: true, }); -// Export the zone ID export const zoneId = zone.id; +export const nameservers = zone.nameServers; +export const status = zone.status; ``` +**Filename: `__main__.py`** + ```py import pulumi import pulumi_cloudflare as cloudflare @@ -347,12 +333,15 @@ zone = cloudflare.Zone("my-zone", plan="free", jump_start=True) -# Export the zone ID pulumi.export("zoneId", zone.id) +pulumi.export('nameservers', zone.name_servers) +pulumi.export('status', zone.status) ``` +**Filename: `main.go`** + ```go package main @@ -375,8 +364,9 @@ func main() { return err } - // Export the zone ID ctx.Export("zoneId", zone.ID()) + ctx.Export("nameservers", zone.NameServers) + ctx.Export("status", zone.Status) return nil }) } @@ -384,7 +374,7 @@ func main() { -The entrypoint file is under the `src/main/java/myproject` directory. +**Filename: `src/main/java/myproject/App.java`** ```java package myproject; @@ -411,6 +401,8 @@ public class App { .build()); ctx.export("zoneId", zone.id()); + ctx.export("nameservers", zone.nameServers()); + ctx.export("status", zone.status()); }); } } @@ -418,8 +410,11 @@ public class App { +**Filename: `Program.cs`** + ```csharp using System.Threading.Tasks; +using System.Collections.Immutable; using Pulumi; using Pulumi.Cloudflare; @@ -444,20 +439,25 @@ class Program }); this.ZoneId = zone.Id; + this.Nameservers = zone.NameServers; + this.Status = zone.Status; } [Output] public Output ZoneId { get; set; } + public Output> Nameservers { get; set; } + public Output Status { get; set; } } } ``` -```yaml -environment: - - my-dev-env +**Filename: `Pulumi.yaml`** +```yaml +name: addsite-cloudflare +runtime: yaml resources: myZone: type: cloudflare:Zone @@ -469,166 +469,29 @@ resources: outputs: zoneId: ${myZone.id} + nameservers: ${exampleZone.nameServers} + status: ${exampleZone.status} ``` -### c. Apply the changes - -```sh -pulumi up --yes -# wait a few seconds while the changes take effect -``` +Notice the code also outputs a number of properties from the Zone resource, such as the `zoneId`, `nameservers`, and `status` so that these can easily be accessed in subsequent steps. -## 3. Update your nameservers +### b. Add a DNS Record -Once you have added a domain to Cloudflare, that domain will receive two assigned authoritative nameservers. +You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Zone can be tested. -:::note - -This process makes Cloudflare your authoritative DNS provider, allowing your DNS queries and web traffic to be served from and protected by the Cloudflare network. - -[Learn more about pending domains](/dns/zone-setups/reference/domain-status/) -::: - -### a. Update the program - -Towards the end of your entrypoint file, below the `zoneId` variable, add the following: +Add the following code snippet to your entrypoint file **after** the Zone resource definition: -```js -exports.nameservers = zone.nameServers; -exports.status = zone.status; -``` - - - -```typescript -export const nameservers = zone.nameServers; -export const status = zone.status; -``` - - - -```py -pulumi.export('nameservers', zone.name_servers) -pulumi.export('status', zone.status) -``` - - - -```go -ctx.Export("nameservers", zone.NameServers) -ctx.Export("status", zone.Status) -``` - - - -```java -ctx.export("nameservers", zone.nameServers()); -ctx.export("status", zone.status()); -``` - - - -1. Add `using System.Collections.Immutable;` at the top of your `Program.cs` file. -2. Below `this.ZoneId = zone.Id;`, add: - -```csharp -this.Nameservers = zone.NameServers; -this.Status = zone.Status; -``` - -3. Below `public Output ZoneId { get; set; }`, add: - -```csharp -public Output> Nameservers { get; set; } -public Output Status { get; set; } -``` - - - -```yaml -nameservers: ${exampleZone.nameServers} -status: ${exampleZone.status} -``` - - - -### b. Apply the changes - -```sh -pulumi up --yes -``` - -### c. Obtain the nameservers - -Review the value of `nameservers` to retrieve the assigned nameservers: - -```sh -pulumi stack output -``` - -### d. Update your registrar - -:::note - -If you use `example.com` as your site, skip ahead to [Add a DNS record](#add-a-dns-record). -::: - -Update the nameservers at your registrar to activate Cloudflare services for your domain. Instructions are registrar-specific. You may be able to find guidance under [this consolidated list of common registrars](/dns/zone-setups/full-setup/setup/#update-your-registrar). - -:::caution - -Registrars take up to 24 hours to process nameserver changes. -::: - -### e. Check your domain status - -Once successfully registered, your domain `status` will change to `active`. - -```sh -pulumi stack output -``` - -## 4. Add a DNS record - -You will now add a DNS record to your domain. - -### a. Modify your program - -Below is the final version of how your Pulumi program entrypoint file should look. -Replace the contents of your entrypoint file with the following: - - +**Filename: `index.js`** ```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, -}); - -// Export the zone ID -exports.zoneId = zone.id; -exports.nameservers = zone.nameServers; -exports.status = zone.status; - const record = new cloudflare.Record("my-record", { zoneId: zone.id, name: domain, - value: "192.0.2.1", + content: "192.0.2.1", type: "A", proxied: true, }); @@ -636,36 +499,13 @@ const record = new cloudflare.Record("my-record", { -```typescript -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", // Choose the desired plan, e.g., "free", "pro", "business", etc. - jumpStart: true, -}); - -// Export the zone ID -export const zoneId = zone.id; - -// Export the Cloudflare-assigned nameservers. -export const nameservers = zone.nameServers; - -// Export the status -export const status = zone.status; +**Filename: `index.ts`** -// Set up a Record for your site +```typescript const record = new cloudflare.Record("my-record", { - zoneId: zoneId, + zoneId: zone.id, name: domain, - value: "192.0.2.1", + content: "192.0.2.1", type: "A", proxied: true, }); @@ -673,29 +513,13 @@ const record = new cloudflare.Record("my-record", { -```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) - -# Export the zone ID -pulumi.export("zoneId", zone.id) -pulumi.export('nameservers', zone.name_servers) -pulumi.export('status', zone.status) +**Filename: `__main__.py`** +```py record = cloudflare.Record("my-record", zone_id=zone.id, name=domain, - value="192.0.2.1", + content="192.0.2.1", type="A", proxied=True ) @@ -704,37 +528,14 @@ record = cloudflare.Record("my-record", -```go -package main +**Filename: `main.go`** -import ( - cloudflare "github.com/pulumi/pulumi-cloudflare/sdk/v3/go/cloudflare" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" -) - -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 - } - - // Export the zone ID - ctx.Export("zoneId", zone.ID()) - ctx.Export("nameservers", zone.NameServers) - ctx.Export("status", zone.Status) +```go _, err = cloudflare.NewRecord(ctx, "my-record", &cloudflare.RecordArgs{ ZoneId: zone.ID(), Name: pulumi.String(domain), - Value: pulumi.String("192.0.2.1"), + Content: pulumi.String("192.0.2.1"), Type: pulumi.String("A"), Proxied: pulumi.Bool(true), }) @@ -742,145 +543,114 @@ func main() { return err } - return nil - }) -} - ``` +**Filename: `src/main/java/myproject/App.java`** + ```java -package myproject; -import com.pulumi.Pulumi; -import com.pulumi.Context; -import com.pulumi.cloudflare.ZoneArgs; -import com.pulumi.cloudflare.Zone; +// Add imports import com.pulumi.cloudflare.Record; import com.pulumi.cloudflare.RecordArgs; - -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()); - - new Record("my-record", RecordArgs.builder() - .zoneId(zone.id()) - .name(domain) - .value("192.0.2.1") - .type("A") - .proxied(true) - .build()); - }); - } -} +// 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()); ``` -```csharp -using System.Collections.Immutable; -using System.Threading.Tasks; -using Pulumi; -using Pulumi.Cloudflare; +**Filename: `Program.cs`** -class Program +```csharp +new Record("my-record", new RecordArgs { - static Task Main() => Deployment.RunAsync(); - - 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; - - new Record("my-record", new RecordArgs - { - ZoneId = zone.Id, - Name = domain, - Value = "192.0.2.1", - Type = "A", - Proxied = true - }); - - } - - [Output] - public Output ZoneId { get; set; } - public Output> Nameservers { get; set; } - public Output Status { get; set; } - } -} + ZoneId = zone.Id, + Name = domain, + Content = "192.0.2.1", + Type = "A", + Proxied = true +}); ``` -```yaml -environment: - - my-dev-env - -resources: - myZone: - type: cloudflare:Zone - properties: - zone: ${domain} - accountId: ${accountId} - plan: "free" - jumpStart: true +**Filename: `Pulumi.yaml`** +```yaml myRecord: type: cloudflare:Record properties: zoneId: ${myZone.id} name: ${domain} - value: 192.0.2.1 + content: 192.0.2.1 type: A proxied: true -outputs: - zoneId: ${myZone.id} - nameservers: ${exampleZone.nameServers} - status: ${exampleZone.status} ``` -### b. Apply the changes +## 3. Deploy your changes + +Now that you have defined your resources, you can deploy the changes so these are reflected in your Cloudflare account using the Pulumi CLI. + +To deploy the changes, run: ```sh pulumi up --yes ``` -## 5. Verify your setup +```sh output +wait for the dev stack to become ready +``` + +## 4. Configure your DNS provider + +:::note + +This process makes Cloudflare your authoritative DNS provider, allowing your DNS queries and web traffic to be served from and protected by the Cloudflare network. + +[Learn more about pending domains](/dns/zone-setups/reference/domain-status/) +::: + +:::note +If you use `example.com` as your site, skip ahead to [Test your site](#5-test-your-site). +::: + +### a. Obtain your nameservers + +Once you have added a domain to Cloudflare, that domain will receive two assigned authoritative nameservers. + +To retrieve the assigned `nameservers`, run: + +```sh +pulumi stack output +``` + +### b. Update your registrar + +Update the nameservers at your registrar to activate Cloudflare services for your domain. Instructions are registrar-specific. You may be able to find guidance under [this consolidated list of common registrars](/dns/zone-setups/full-setup/setup/#update-your-registrar). + +:::caution +Registrars take up to 24 hours to process nameserver changes. +::: + +### c. Check your domain status + +Once successfully registered, your domain `status` will change to `active`. + +```sh +pulumi stack output +``` + +## 5. Test your site You will run two `nslookup` commands against the Cloudflare-assigned nameservers. @@ -898,6 +668,10 @@ For .NET use `Nameservers` as the Output. Confirm your response returns the IP address(es) for your site. +:::note +If you use `example.com` as your site, you will not receive a valid response. +::: + ## 6. Clean up In this last step, you will remove the resources and stack used throughout the tutorial. @@ -914,8 +688,8 @@ pulumi destroy --yes pulumi stack rm dev ``` -You have incrementally defined Cloudflare resources needed to add a site to Cloudflare. After each new resource, you apply the changes to your `dev` stack via the `pulumi up` command. You declare the resources in your programming language of choice and let Pulumi handle the rest. - ## Next steps +You have incrementally defined Cloudflare resources needed to add a site to Cloudflare. You declare the resources in your programming language of choice and let Pulumi handle the rest. + Follow the [Deploy a Worker tutorial](/pulumi/tutorial/hello-world/) to deploy a serverless app with Pulumi. diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 3c094b79050c7c..a6e0d66b9bc15f 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -3,7 +3,7 @@ title: Deploy a Worker pcx_content_type: tutorial products: - Workers -updated: 2024-09-12 +updated: 2024-09-13 difficulty: Beginner languages: - JavaScript @@ -255,7 +255,7 @@ There are no dependencies to download for YAML. Skip ahead. -## 3. Define Cloudflare resources in code +## 2. Define Cloudflare resources in code With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. You'll define a Worker, a Route, and a DNS Record next. @@ -1170,7 +1170,7 @@ outputs: -## 5. Deploy your application +## 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. @@ -1184,7 +1184,7 @@ pulumi up --yes wait for the dev stack to become ready ``` -## 6. Test the Worker +## 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. @@ -1197,7 +1197,7 @@ Hello, World! ``` -## 7. Clean up +## 5. Clean up In this last step, you will clean up the resources and stack used throughout the tutorial. From 42f4bbbbd79f9cc308189080a6cbc3edb5cb2bfe Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 12:15:48 -0500 Subject: [PATCH 10/17] lint check --- .vscode/settings.json | 13 ++++++++++++- src/content/docs/pulumi/tutorial/add-site.mdx | 5 ++--- .../docs/pulumi/tutorial/hello-world.mdx | 19 +++++++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f50be09c286fb..22690264528bd7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,16 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "typescript.tsdk": "node_modules/typescript/lib", - "cSpell.enableFiletypes": ["mdx"] + "cSpell.enableFiletypes": [ + "mdx" + ], + "grammarly.selectors": [ + { + "language": "mdx", + "scheme": "file" + } + ], + "[mdx]": { + "editor.defaultFormatter": "unifiedjs.vscode-mdx" + } } diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index 0f8fd4a50e0be8..aba563cf62796a 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -43,7 +43,6 @@ Ensure you have: A Pulumi project is a collection of files in a dedicated folder that describe the infrastructure you want to create. The Pulumi project folder is identified by the presenece of the required `Pulumi.yaml` file. You will use the Pulumi CLI to create a new project and configure it. - ### a. Create a directory Use a new and empty directory for this tutorial. @@ -260,7 +259,7 @@ With the Cloudflare package installed, you can now define any [supported Cloudfl ### a. Add a Zone -A domain, or site, is known as a Zone in Cloudflare. In Pulumi, the [Zone resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/zone/) represents a Cloudflare Zone. +A domain, or site, is known as a Zone in Cloudflare. In Pulumi, the [Zone resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/zone/) represents a Cloudflare Zone. Replace the contents of your entrypoint file with the following: @@ -481,7 +480,7 @@ Notice the code also outputs a number of properties from the Zone resource, such You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Zone can be tested. -Add the following code snippet to your entrypoint file **after** the Zone resource definition: +Add the following code snippet to your entrypoint file **after** the Zone resource definition: diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index a6e0d66b9bc15f..39020c6bf50d20 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -261,7 +261,7 @@ With the Cloudflare package installed, you can now define any [supported Cloudfl ### a. Add a Workers script -The [Workers Script resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersscript/) represents a Cloudflare Worker that can be deployed to the Cloudflare network. +The [Workers Script resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersscript/) represents a Cloudflare Worker that can be deployed to the Cloudflare network. Replace the contents of your entrypoint file with the following: @@ -491,7 +491,7 @@ resources: You will now add a [Workers Route resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/workersroute/) to your Pulumi program so the Workers script can have an endpoint and be active. To properly configure the Route, you will also look up the zone ID for your domain. -Add the following code snippet to your entrypoint file **after** the Worker script resource: +Add the following code snippet to your entrypoint file **after** the Worker script resource: @@ -530,6 +530,7 @@ const route = new cloudflare.WorkersRoute("hello-world-route", { scriptName: worker.name, }); ``` + **Filename: `__main__.py`** @@ -606,6 +607,7 @@ var route = new Cloudflare.WorkersRoute("hello-world-route", new() **Filename: `Pulumi.yaml`** Below the `runtime` key, add the following code: + ```yaml # new top-level section variables: @@ -618,6 +620,7 @@ variables: ``` Below the `worker` resource, add the following code: + ```yaml route: type: cloudflare:WorkersRoute @@ -633,7 +636,7 @@ Below the `worker` resource, add the following code: You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Route can be resolved. You'll also output the Route URL so it can be easily accessed in the next step. -Add the following code snippet to your entrypoint file **after** the Route resource: +Add the following code snippet to your entrypoint file **after** the Route resource: @@ -875,6 +878,7 @@ const record = new cloudflare.Record("hello-world-record", { export const url = pulumi.interpolate`https://${record.hostname}`; ``` + @@ -996,6 +1000,7 @@ func main() { } ``` + @@ -1027,7 +1032,7 @@ public class App { }; """; - var accountId = ctx.config().require("accountId"); + var accountId = ctx.config().require("accountId"); var domain = ctx.config().require("domain"); var worker = new WorkersScript("hello-world-worker", WorkersScriptArgs.builder() @@ -1052,7 +1057,7 @@ public class App { .zoneId(zone.applyValue(getZoneResult -> getZoneResult.id())) .proxied(true) .build()); - + ctx.export("url", Output.format("https://%s", record.hostname())); return; }); @@ -1060,6 +1065,7 @@ public class App { } ``` + @@ -1119,6 +1125,7 @@ return await Deployment.RunAsync(() => }); ``` + @@ -1167,6 +1174,7 @@ resources: outputs: url: "https://${record.hostname}" ``` + @@ -1196,7 +1204,6 @@ 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. From 4afa2a228be3934eb654ab51ca5c93e01e5d3247 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 12:30:17 -0500 Subject: [PATCH 11/17] grammar --- .../docs/pulumi/tutorial/hello-world.mdx | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 39020c6bf50d20..8c706285bb11cb 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -22,7 +22,7 @@ head: import { TabItem, Tabs } from "~/components"; -In this tutorial, you will go through step-by-step instructions to deploy a Hello World application using Cloudflare Workers and Pulumi infrastructure as code (IaC) so that you can become familiar with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. +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) to familiarize yourself with the resource management lifecycle. In particular, you will create a Worker, a Route, and a DNS Record to access the application before cleaning up all the resources. :::note You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. @@ -31,19 +31,19 @@ You will provision resources that qualify under free tier offerings for both Pul ## 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must have: - - `Account-Workers Scripts-Edit` permission - - `Zone-Workers Route-Edit` permission - - `Zone-DNS-Edit` permission -- A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). + +- 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must have the following: + - `Account-Workers Scripts-Edit` permission + - `Zone-Workers Route-Edit` permission + - `Zone-DNS-Edit` permission +- A Pulumi Cloud account. You can sign up for an [always-free individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) - A Cloudflare-managed domain. Complete the [Add a site tutorial](/pulumi/tutorial/add-site/) to bring your existing domain under Cloudflare. ## 1. Initialize your project -A Pulumi project is a collection of files in a dedicated folder that describe the infrastructure you want to create. The Pulumi project folder is identified by the presenece of the required `Pulumi.yaml` file. You will use the Pulumi CLI to create a new project and configure it. +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 @@ -131,11 +131,11 @@ pulumi up --yes # wait a few seconds for the stack to be instantiated. ``` -At this point, you have not defined any resources so you'll have an empty stack. +You have not defined any resources at this point, so you'll have an empty stack. ### e. Save your application settings -In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/). This is 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: +In this step, you will store your application settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/), 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](/fundamentals/setup/find-account-and-zone-ids/). - A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). @@ -166,7 +166,7 @@ pulumi env set $E --plaintext pulumiConfig.domain example.com ### f. Install the Cloudflare package -In order to define Cloudflare resources in your Pulumi program, you need to install the Cloudflare package for your language of choice. +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: @@ -257,7 +257,7 @@ 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](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. You'll define a Worker, a Route, and a DNS Record next. +With the Cloudflare package installed, you can now define any [supported Cloudflare resource](https://www.pulumi.com/registry/packages/cloudflare/) in your Pulumi program. Next, define a Worker, a Route, and a DNS Record. ### a. Add a Workers script @@ -634,7 +634,7 @@ Below the `worker` resource, add the following code: ### c. Add a DNS Record -You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Route can be resolved. You'll also output the Route URL so it can be easily accessed in the next step. +You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) to resolve the previously configured Route. In the next step, you'll also output the Route URL so it can be easily accessed. Add the following code snippet to your entrypoint file **after** the Route resource: @@ -726,7 +726,7 @@ ctx.export("url", Output.format("https://%s", record.hostname())); **Filename: `Program.cs`** -Because you're now exporting a value, notice the updated `return` statement. Ensure to also include `using System.Collections.Generic;` in your imports. +Notice the updated ' return ' statement because you're now exporting a value. Ensure that you also include `using System.Collections.Generic;` in your imports. ```csharp var record = new Cloudflare.Record("hello-world-record", new() @@ -766,7 +766,7 @@ outputs: :::note -Depending on your domain settings, you may need to use `http` instead. +You may need to use `http` instead depending on your domain settings. ::: @@ -1222,4 +1222,4 @@ pulumi stack rm dev ## Next steps -Explore other resources you can define with Pulumi and Cloudflare by visiting the [Cloudflare package documentation](https://www.pulumi.com/docs/reference/pkg/cloudflare/). +Visit the [Cloudflare package documentation] (https://www.pulumi.com/docs/reference/pkg/cloudflare/) to explore other resources you can define with Pulumi and Cloudflare. From a30f6e3daf7db3af8d1f86baff3be43a6d6cfd22 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 12:50:52 -0500 Subject: [PATCH 12/17] grammar --- src/content/docs/pulumi/tutorial/add-site.mdx | 28 +++++++++---------- .../docs/pulumi/tutorial/hello-world.mdx | 8 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index aba563cf62796a..a4dcee0b5b66ad 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -20,7 +20,7 @@ head: import { TabItem, Tabs } from "~/components"; -In this tutorial, you will go through step-by-step instructions to bring an existing site to Cloudflare using Pulumi infrastructure as code (IaC) so that you can become familiar 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](/fundamentals/setup/manage-domains/add-site/). +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](/fundamentals/setup/manage-domains/add-site/). :::note You will provision resources that qualify under free tier offerings for both Pulumi Cloud and Cloudflare. @@ -34,14 +34,14 @@ Ensure you have: - `Zone-Zone-Edit` permission - `Zone-DNS-Edit` permission - `include-All zones from an account-` zone resource -- A Pulumi Cloud account. You can sign up for an [always-free, individual tier](https://app.pulumi.com/signup). +- A Pulumi Cloud account. You can sign up for an [always-free individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) 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 describe the infrastructure you want to create. The Pulumi project folder is identified by the presenece of the required `Pulumi.yaml` file. You will use the Pulumi CLI to create a new project and configure it. +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 @@ -129,11 +129,11 @@ pulumi up --yes # wait a few seconds for the stack to be instantiated. ``` -At this point, you have not defined any resources so you'll have an empty stack. +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](https://www.pulumi.com/docs/esc/environments/). This is 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: +In this step, you will store your settings in a Pulumi [ESC Environment](https://www.pulumi.com/docs/esc/environments/), 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](/fundamentals/setup/find-account-and-zone-ids/). - A valid Cloudflare API [token](/fundamentals/api/get-started/create-token/). @@ -164,7 +164,7 @@ pulumi env set $E --plaintext pulumiConfig.domain example.com ### f. Install the Cloudflare package -In order to define Cloudflare resources in your Pulumi program, you need to install the Cloudflare package for your language of choice. +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: @@ -474,11 +474,11 @@ outputs: -Notice the code also outputs a number of properties from the Zone resource, such as the `zoneId`, `nameservers`, and `status` so that these can easily be accessed in subsequent steps. +Notice that the code also outputs several properties from the Zone resource, such as the `zoneId`, `nameservers`, and `status`, so that they can easily be accessed in subsequent steps. ### b. Add a DNS Record -You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) so the previously configured Zone can be tested. +You will now add a DNS [Record resource](https://www.pulumi.com/registry/packages/cloudflare/api-docs/record/) to test previously configured Zone. Add the following code snippet to your entrypoint file **after** the Zone resource definition: @@ -598,7 +598,7 @@ new Record("my-record", new RecordArgs ## 3. Deploy your changes -Now that you have defined your resources, you can deploy the changes so these are reflected in your Cloudflare account using the Pulumi CLI. +Now that you have defined your resources, you can deploy the changes using the Pulumi CLI so that they are reflected in your Cloudflare account. To deploy the changes, run: @@ -620,7 +620,7 @@ This process makes Cloudflare your authoritative DNS provider, allowing your DNS ::: :::note -If you use `example.com` as your site, skip ahead to [Test your site](#5-test-your-site). +If your site is `example.com`, skip ahead to [Test your site](#5-test-your-site). ::: ### a. Obtain your nameservers @@ -635,7 +635,7 @@ pulumi stack output ### b. Update your registrar -Update the nameservers at your registrar to activate Cloudflare services for your domain. Instructions are registrar-specific. You may be able to find guidance under [this consolidated list of common registrars](/dns/zone-setups/full-setup/setup/#update-your-registrar). +Update the nameservers at your registrar to activate Cloudflare services for your domain. The instructions are registrar-specific. You may be able to find guidance under [this consolidated list of common registrars](/dns/zone-setups/full-setup/setup/#update-your-registrar). :::caution Registrars take up to 24 hours to process nameserver changes. @@ -663,12 +663,12 @@ nslookup $DOMAIN $NS1 nslookup $DOMAIN $NS2 ``` -For .NET use `Nameservers` as the Output. +For .NET, use `Nameservers` as the Output. Confirm your response returns the IP address(es) for your site. :::note -If you use `example.com` as your site, you will not receive a valid response. +You will not receive a valid response if you use `example.com` as your site. ::: ## 6. Clean up @@ -691,4 +691,4 @@ pulumi stack rm dev You have incrementally defined Cloudflare resources needed to add a site to Cloudflare. You declare the resources in your programming language of choice and let Pulumi handle the rest. -Follow the [Deploy a Worker tutorial](/pulumi/tutorial/hello-world/) to deploy a serverless app with Pulumi. +To deploy a serverless app with Pulumi, follow the [Deploy a Worker tutorial](/pulumi/tutorial/hello-world/). \ No newline at end of file diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 8c706285bb11cb..8c1aedc5195f5e 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -33,9 +33,9 @@ You will provision resources that qualify under free tier offerings for both Pul 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must have the following: - - `Account-Workers Scripts-Edit` permission - - `Zone-Workers Route-Edit` permission - - `Zone-DNS-Edit` permission + - `Account-Workers Scripts-Edit` permission + - `Zone-Workers Route-Edit` permission + - `Zone-DNS-Edit` permission - A Pulumi Cloud account. You can sign up for an [always-free individual tier](https://app.pulumi.com/signup). - The [Pulumi CLI](/pulumi/installing/) is installed on your machine. - A [Pulumi-supported programming language](https://github.com/pulumi/pulumi?tab=readme-ov-file#languages) configured. (TypeScript, JavaScript, Python, Go, .NET, Java, or use YAML) @@ -1222,4 +1222,4 @@ pulumi stack rm dev ## Next steps -Visit the [Cloudflare package documentation] (https://www.pulumi.com/docs/reference/pkg/cloudflare/) to explore other resources you can define with Pulumi and Cloudflare. +Visit the [Cloudflare package documentation](https://www.pulumi.com/docs/reference/pkg/cloudflare/) to explore other resources you can define with Pulumi and Cloudflare. From 9bf4da62a57cbf94c6b918317d03e4379020acc6 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 12:58:32 -0500 Subject: [PATCH 13/17] undo settings file change --- .vscode/settings.json | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 22690264528bd7..2f50be09c286fb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,16 +3,5 @@ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "typescript.tsdk": "node_modules/typescript/lib", - "cSpell.enableFiletypes": [ - "mdx" - ], - "grammarly.selectors": [ - { - "language": "mdx", - "scheme": "file" - } - ], - "[mdx]": { - "editor.defaultFormatter": "unifiedjs.vscode-mdx" - } + "cSpell.enableFiletypes": ["mdx"] } From 5ed3c2b5daf95f183b5c35b4a697876a7f9b737b Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 13 Sep 2024 13:17:46 -0500 Subject: [PATCH 14/17] cf signup link --- src/content/docs/pulumi/tutorial/add-site.mdx | 2 +- src/content/docs/pulumi/tutorial/hello-world.mdx | 2 +- src/content/docs/pulumi/tutorial/manage-secrets.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index a4dcee0b5b66ad..ecd1b55f60a407 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -30,7 +30,7 @@ You will provision resources that qualify under free tier offerings for both Pul 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must 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](https://www.cloudflare.com/sign-up) before continuing. Your token must have: - `Zone-Zone-Edit` permission - `Zone-DNS-Edit` permission - `include-All zones from an account-` zone resource diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 8c1aedc5195f5e..8b1628d2b95890 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -32,7 +32,7 @@ You will provision resources that qualify under free tier offerings for both Pul 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](https://dash.cloudflare.com/sign-up/workers-and-pages) before continuing. Your token must have the following: +- 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](https://www.cloudflare.com/sign-up) before continuing. Your token must have the following: - `Account-Workers Scripts-Edit` permission - `Zone-Workers Route-Edit` permission - `Zone-DNS-Edit` permission diff --git a/src/content/docs/pulumi/tutorial/manage-secrets.mdx b/src/content/docs/pulumi/tutorial/manage-secrets.mdx index 3c2ebceceb061d..6a3aa3cb96917f 100644 --- a/src/content/docs/pulumi/tutorial/manage-secrets.mdx +++ b/src/content/docs/pulumi/tutorial/manage-secrets.mdx @@ -22,7 +22,7 @@ You will provision resources that qualify under free tier offerings for both Pul Ensure you have: -- A Cloudflare account. [Sign up for a Cloudflare account](https://dash.cloudflare.com/sign-up/workers-and-pages). +- A Cloudflare account. [Sign up for a Cloudflare account](https://www.cloudflare.com/sign-up). - A Pulumi Cloud account. [Sign up for a Pulumi Cloud](https://app.pulumi.com/signup). - The [Pulumi ESC CLI](https://www.pulumi.com/docs/install/esc/) installed. - A Wrangler project. To create one, follow the [Create a New Worker project step](/workers/get-started/guide/#1-create-a-new-worker-project). From 7c46d4afaeb3c973b586adb3486b655f3a1d1e96 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Wed, 18 Sep 2024 14:50:18 -0500 Subject: [PATCH 15/17] update code to use esc projects --- src/content/docs/pulumi/tutorial/add-site.mdx | 4 ++-- src/content/docs/pulumi/tutorial/hello-world.mdx | 4 ++-- src/content/docs/pulumi/tutorial/manage-secrets.mdx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/content/docs/pulumi/tutorial/add-site.mdx b/src/content/docs/pulumi/tutorial/add-site.mdx index ecd1b55f60a407..a9321ed6bae090 100644 --- a/src/content/docs/pulumi/tutorial/add-site.mdx +++ b/src/content/docs/pulumi/tutorial/add-site.mdx @@ -141,14 +141,14 @@ In this step, you will store your settings in a Pulumi [ESC Environment](https:/ ```sh # Define an ESC Environment name -E=my-dev-env +E=clouflare/my-dev-env # Create a new Pulumi ESC Environment pulumi config env init --env $E --yes ``` ```sh output -Creating environment my-dev-env for stack dev... +Creating environment clouflare/my-dev-env for stack dev... ``` ```sh diff --git a/src/content/docs/pulumi/tutorial/hello-world.mdx b/src/content/docs/pulumi/tutorial/hello-world.mdx index 8b1628d2b95890..7ec579c436dd69 100644 --- a/src/content/docs/pulumi/tutorial/hello-world.mdx +++ b/src/content/docs/pulumi/tutorial/hello-world.mdx @@ -143,14 +143,14 @@ In this step, you will store your application settings in a Pulumi [ESC Environm ```sh # Give your new ESC Environment a name -E=hello-world-dev-env +E=hello-world/dev-env # Initialize the new ESC Environment pulumi config env init --env $E --yes ``` ```sh output -Creating environment hello-world-dev-env for stack dev... +Creating environment hello-world/dev-env for stack dev... ``` ```sh diff --git a/src/content/docs/pulumi/tutorial/manage-secrets.mdx b/src/content/docs/pulumi/tutorial/manage-secrets.mdx index 6a3aa3cb96917f..9b8000f43bc130 100644 --- a/src/content/docs/pulumi/tutorial/manage-secrets.mdx +++ b/src/content/docs/pulumi/tutorial/manage-secrets.mdx @@ -50,7 +50,7 @@ Environment names must be unique within a Pulumi organization and may only conta ::: ```sh -ESC_ENV=my-dev-environment +ESC_ENV=wrangler/my-dev-environment esc env init $ESC_ENV ``` @@ -138,7 +138,7 @@ With a dedicated ESC Environment to store all the `.dev.vars` secrets, you can u ### a. Create an Environment ```sh -E=my-devvars +E=wrangler/my-devvars esc env init $E ``` From 4072dbb441d3b4dfe35ea4fff8ee69c811c49fc4 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 20 Sep 2024 16:21:46 -0500 Subject: [PATCH 16/17] Update src/content/docs/pulumi/tutorial/manage-secrets.mdx Co-authored-by: Claire W <78226508+crwaters16@users.noreply.github.com> --- src/content/docs/pulumi/tutorial/manage-secrets.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/pulumi/tutorial/manage-secrets.mdx b/src/content/docs/pulumi/tutorial/manage-secrets.mdx index 9b8000f43bc130..9081672f11bc63 100644 --- a/src/content/docs/pulumi/tutorial/manage-secrets.mdx +++ b/src/content/docs/pulumi/tutorial/manage-secrets.mdx @@ -107,7 +107,7 @@ Getting User settings... When you use the `esc run` command, it opens the Environment and sets the specified Environment variables into a temporary environment. After that, it uses those variables in the context of the `wrangler` command. This is especially helpful when running `wrangler` commands in a CI/CD environment but wanting to avoid storing credentials directly in your pipeline. -## 3, Add Worker secrets +## 3. Add Worker secrets Pulumi ESC centralizes secrets, and Wrangler can be used to pass them on to Workers and other Cloudflare resources. You will use the `wrangler secret put` command for this purpose. From 415a9bcba6f2a0120725d42b4f1f6d38602b4e05 Mon Sep 17 00:00:00 2001 From: diana esteves Date: Fri, 20 Sep 2024 16:21:55 -0500 Subject: [PATCH 17/17] Update src/content/docs/pulumi/tutorial/manage-secrets.mdx Co-authored-by: Claire W <78226508+crwaters16@users.noreply.github.com> --- src/content/docs/pulumi/tutorial/manage-secrets.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/pulumi/tutorial/manage-secrets.mdx b/src/content/docs/pulumi/tutorial/manage-secrets.mdx index 9081672f11bc63..b0f4758d35b276 100644 --- a/src/content/docs/pulumi/tutorial/manage-secrets.mdx +++ b/src/content/docs/pulumi/tutorial/manage-secrets.mdx @@ -125,7 +125,7 @@ esc run -i ${ESC_ENV} -- sh -c 'echo "$TOP_SECRET" | npx wrangler secret put TOP By using an external secrets management solution, commonly used Worker secrets can be stored in a single shared Environment that is accessed by the relevant Workers. You can use shell commands with `esc` to incorporate scripting and integrate them into deployment pipelines or `make` commands. Use `esc [command] --help` for more information about the various commands available in the CLI. -## 4, Load `.dev.vars` +## 4. Load `.dev.vars` In this step, you will configure an Environment to load your `.dev.vars` file programmatically.