跳转到内容
搜索文档

添加网站

最后更新 查看 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 资源输出了多个属性,例如 zoneIdnameserversstatus,以便在后续步骤中轻松访问。

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 教程

这篇文档对您有帮助吗?