跳转到内容
搜索文档

添加网站

最后更新 查看 MarkdownAgent 设置

在本教程中,你将按照分步说明,使用 Pulumi 基础设施即代码(IaC)将现有网站接入 Cloudflare,以熟悉资源管理生命周期。具体而言,你将创建一个 Zone 和一个 DNS 记录来解析新添加的网站。本教程采用 IaC 原则来完成添加网站教程中列出的步骤。

开始之前

确保你拥有:

  • 一个 Cloudflare 账户和 API 令牌,具有在本教程中编辑资源的权限。如有需要,请在继续之前注册 Cloudflare 账户 ↗。你的令牌必须具有:
    • Zone-Zone-Edit 权限
    • Zone-DNS-Edit 权限
    • include-All zones from an account-<your account> Zone 资源
  • 一个 Pulumi Cloud 账户。你可以注册永久免费的个人版 ↗。
  • 在你的机器上安装了 Pulumi CLI。
  • 配置了一种 Pulumi 支持的编程语言 ↗。(TypeScript、JavaScript、Python、Go、.NET、Java 或使用 YAML)
  • 一个域名。你可以使用 example.com 来完成本教程。

1. 初始化你的项目

Pulumi 项目是专用文件夹中的一组文件,描述了你想要创建的基础设施。Pulumi 项目文件夹通过必需的 Pulumi.yaml 文件来标识。你将使用 Pulumi CLI 创建和配置新项目。

a. 创建目录

为本教程使用一个新的空目录。

mkdir addsite-cloudflare
cd addsite-cloudflare

b. 登录 Pulumi Cloud

Pulumi Cloud ↗ 是一种托管服务,为管理基础设施即代码提供安全且可扩展的平台。你将使用它来存储 Pulumi 后端配置。

在提示符处,按 Enter 通过浏览器登录你的 Pulumi Cloud 账户。或者,你也可以提供 Pulumi Cloud 访问令牌 ↗。

pulumi login

c. 创建新程序

Pulumi 程序是用支持的编程语言 ↗编写的代码,用于定义基础设施资源。

要创建程序,请选择你喜欢的语言并运行 pulumi 命令:

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

d. 创建 Stack

Pulumi Stack ↗ 是 Pulumi 程序的实例。Stack 可以独立配置,可以代表不同的环境(开发、暂存、生产)或功能分支。在本教程中,你将使用 dev Stack。

要实例化你的 dev Stack,请运行:

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

此时你尚未定义任何资源,因此你将拥有一个空的 Stack。

e. 保存你的设置

在此步骤中,你将把设置存储在 Pulumi ESC Environment ↗ 中,这是一个包含配置和密钥的 YAML 文件。这些可以通过多种方式访问,包括 Pulumi 程序。所有 ESC Environment 都安全地存储在你的 Pulumi Cloud 账户中,可以通过 Pulumi CLI 完全管理。在本教程中,你将存储以下值:

  • 你的 Cloudflare 账户 ID。
  • 有效的 Cloudflare API 令牌。
  • 一个域名。例如,example.com。
# Define an ESC Environment name
E=cloudflare/my-dev-env

# Create a new Pulumi ESC Environment
pulumi config env init --env $E --yes
Creating environment cloudflare/my-dev-env for stack dev...
# Replace abc123 with your Cloudflare Account ID
pulumi env set $E --plaintext pulumiConfig.accountId abc123

# Replace API_TOKEN with your Cloudflare API Token
pulumi env set $E --secret  pulumiConfig.cloudflare:apiToken API_TOKEN

# Replace example.com with your registered domain, or leave as is
pulumi env set $E --plaintext pulumiConfig.domain example.com

f. 安装 Cloudflare 包

你需要为所选语言安装 Cloudflare 包,以便在 Pulumi 程序中定义 Cloudflare 资源。

通过运行以下命令安装 Cloudflare 包:

npm install @pulumi/cloudflare
added 1 package ...
npm install @pulumi/cloudflare
added 1 package ...
echo "pulumi_cloudflare>=5.38,<6.0.0" >> requirements.txt
source venv/bin/activate
pip install -r requirements.txt
...Collecting pulumi-cloudflare...
go get github.com/pulumi/pulumi-cloudflare/sdk/v3/go/cloudflare
go: downloading github.com/pulumi/pulumi-cloudflare ...

以下是 Apache Maven 的说明。对于其他 Java 项目管理器(如 Gradle),请参阅官方 Maven repository ↗

  1. 打开你的 pom.xml 文件。
  2. 在 <dependencies> 部分内添加 Pulumi Cloudflare 依赖项。
<dependency>
    <groupId>com.pulumi</groupId>
    <artifactId>cloudflare</artifactId>
    <version>5.38.0</version>
</dependency>
  1. Run:
mvn clean install
...[INFO] BUILD SUCCESS...
dotnet add package Pulumi.Cloudflare
...
info : Adding PackageReference for package 'Pulumi.Cloudflare' into project
...

YAML 没有需要下载的依赖项。请跳过此步骤。

2. 在代码中定义 Cloudflare 资源

安装 Cloudflare 包后,你现在可以在 Pulumi 程序中定义任何支持的 Cloudflare 资源 ↗。接下来你将定义一个 Zone 和一个 DNS 记录。

a. 添加 Zone

域名(或网站)在 Cloudflare 中称为 Zone。在 Pulumi 中,Zone 资源 ↗表示一个 Cloudflare Zone。

将你的入口文件内容替换为以下内容:

Filename: index.js

"use strict";
const pulumi = require("@pulumi/pulumi");
const cloudflare = require("@pulumi/cloudflare");

const config = new pulumi.Config();
const accountId = config.require("accountId");
const domain = config.require("domain");

// Create a Cloudflare resource (Zone)
const zone = new cloudflare.Zone("my-zone", {
	zone: domain,
	accountId: accountId,
	plan: "free",
	jumpStart: true,
});

exports.zoneId = zone.id;
exports.nameservers = zone.nameServers;
exports.status = zone.status;

Filename: index.ts

import * as pulumi from "@pulumi/pulumi";
import * as cloudflare from "@pulumi/cloudflare";

const config = new pulumi.Config();
const accountId = config.require("accountId");
const domain = config.require("domain");

// Create a Cloudflare resource (Zone)
const zone = new cloudflare.Zone("my-zone", {
	zone: domain,
	accountId: accountId,
	plan: "free",
	jumpStart: true,
});

export const zoneId = zone.id;
export const nameservers = zone.nameServers;
export const status = zone.status;

Filename: __main__.py

import pulumi
import pulumi_cloudflare as cloudflare

account_id = pulumi.Config().require("accountId")
domain = pulumi.Config().require("domain")

# Create a Cloudflare resource (Zone)
zone = cloudflare.Zone("my-zone",
    zone=domain,
    account_id=account_id,
    plan="free",
    jump_start=True)

pulumi.export("zoneId", zone.id)
pulumi.export('nameservers', zone.name_servers)
pulumi.export('status', zone.status)

Filename: main.go

package main

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

func main() {
    pulumi.Run(func(ctx *pulumi.Context) error {
        domain, _ := ctx.GetConfig("domain")

        // Create a Cloudflare resource (Zone)
        zone, err := cloudflare.NewZone(ctx, "my-zone", &cloudflare.ZoneArgs{
            Zone:      pulumi.String(domain),
            Plan:      pulumi.String("free"),
            JumpStart: pulumi.Bool(true),
        })
        if err != nil {
            return err
        }

        ctx.Export("zoneId", zone.ID())
        ctx.Export("nameservers", zone.NameServers)
        ctx.Export("status", zone.Status)
        return nil
    })
}

Filename: src/main/java/myproject/App.java

package myproject;

import com.pulumi.Pulumi;
import com.pulumi.Context;
import com.pulumi.cloudflare.ZoneArgs;
import com.pulumi.cloudflare.Zone;


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

Filename: Program.cs

using System.Threading.Tasks;
using System.Collections.Immutable;
using Pulumi;
using Pulumi.Cloudflare;

class Program
{
    static Task<int> Main() => Deployment.RunAsync<MyStack>();

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

        [Output]
        public Output<string> ZoneId { get; set; }
        public Output<ImmutableArray<string>> Nameservers { get; set; }
        public Output<string> Status { get; set; }
    }
}

Filename: Pulumi.yaml

name: addsite-cloudflare
runtime: yaml
resources:
  myZone:
    type: cloudflare:Zone
    properties:
      zone: ${domain}
      accountId: ${accountId}
      plan: "free"
      jumpStart: true

outputs:
  zoneId: ${myZone.id}
  nameservers: ${exampleZone.nameServers}
  status: ${exampleZone.status}

请注意,代码还从 Zone 资源输出了多个属性,例如 zoneId、nameservers 和 status,以便在后续步骤中轻松访问。

b. 添加 DNS 记录

你现在将添加一个 DNS Record 资源 ↗来测试之前配置的 Zone。

在 Zone 资源定义之后,将以下代码片段添加到你的入口文件中:

Filename: index.js

const record = new cloudflare.Record("my-record", {
	zoneId: zone.id,
	name: domain,
	content: "192.0.2.1",
	type: "A",
	proxied: true,
});

Filename: index.ts

const record = new cloudflare.Record("my-record", {
	zoneId: zone.id,
	name: domain,
	content: "192.0.2.1",
	type: "A",
	proxied: true,
});

Filename: __main__.py

record = cloudflare.Record("my-record",
    zone_id=zone.id,
    name=domain,
    content="192.0.2.1",
    type="A",
    proxied=True
)

Filename: main.go


    _, err = cloudflare.NewRecord(ctx, "my-record", &cloudflare.RecordArgs{
      ZoneId:  zone.ID(),
      Name:    pulumi.String(domain),
      Content:   pulumi.String("192.0.2.1"),
      Type:    pulumi.String("A"),
      Proxied: pulumi.Bool(true),
    })
    if err != nil {
      return err
    }

Filename: src/main/java/myproject/App.java


// Add imports
import com.pulumi.cloudflare.Record;
import com.pulumi.cloudflare.RecordArgs;

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

Filename: Program.cs

new Record("my-record", new RecordArgs
{
    ZoneId = zone.Id,
    Name = domain,
    Content = "192.0.2.1",
    Type = "A",
    Proxied = true
});

Filename: Pulumi.yaml

myRecord:
  type: cloudflare:Record
  properties:
    zoneId: ${myZone.id}
    name: ${domain}
    content: 192.0.2.1
    type: A
    proxied: true

3. 部署你的更改

现在你已经定义了资源,可以使用 Pulumi CLI 部署更改,以便它们在你的 Cloudflare 账户中生效。

要部署更改,请运行:

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

4. 配置你的 DNS 提供商

a. 获取你的名称服务器

将域名添加到 Cloudflare 后,该域名将获得两个分配的权威名称服务器。

要检索分配的 nameservers,请运行:

pulumi stack output

b. 更新你的注册商

在你的注册商处更新名称服务器以为你的域名激活 Cloudflare 服务。说明因注册商而异。你可以在常用注册商的综合列表下找到指导。

c. 检查你的域名状态

成功注册后,你的域名 status 将变为 active。

pulumi stack output

5. 测试你的网站

你将对 Cloudflare 分配的名称服务器运行两个 nslookup 命令。

要测试你的网站,请运行:

DOMAIN=$(pulumi config get domain)
NS1=$(pulumi stack output nameservers | jq '.[0]' -r)
NS2=$(pulumi stack output nameservers | jq '.[1]' -r)
nslookup $DOMAIN $NS1
nslookup $DOMAIN $NS2

对于 .NET,请使用 Nameservers 作为 Output。

确认你的响应返回了你网站的 IP 地址。

6. 清理

在最后一步,你将删除本教程中使用的资源和 Stack。

a. 删除资源

pulumi destroy --yes

b. 删除 Stack

pulumi stack rm dev

后续步骤

你已逐步定义了将网站添加到 Cloudflare 所需的 Cloudflare 资源。你用所选的编程语言声明资源,由 Pulumi 处理其余事项。

要使用 Pulumi 部署无服务器应用程序,请参照部署 Worker 教程。

这篇文档对您有帮助吗?