维护页面是通知您的用户存在需要停机的操作更改的一种简洁方式。 Cloudflare Workers 允许您执行 Javascript 并在您的用户附近提供 HTML 服务,当 Cloudflare 管理您的 DNS 时,它可以轻松创建一个 Worker 并让它在维护期间管理所有流量。这对于不想花时间创建和显示维护页面的小型团队/应用程序来说是一个很好的解决方案。 Terraform 是一种工具,可以通过代码配置基础设施,它与 Cloudflare API 集成得很好。

最终实现的预览可以在这里找到,我已经创建了一个 Terraform 模块,用于创建维护页面。

Cloudflare Worker

Worker 的 javascript 很简单,可以在这篇博客文章中找到并深入解释它。如果连接 IP 被列入白名单,该片段会将请求转发到 Web 服务器,否则它会返回您定义的 html 响应,在我们的例子中是维护页面。

async function fetchAndReplace(request) {

  let modifiedHeaders = new Headers()

  modifiedHeaders.set('Content-Type', 'text/html')
  modifiedHeaders.append('Pragma', 'no-cache')


  //Allow users from trusted into site
  if (white_list.indexOf(request.headers.get("cf-connecting-ip")) > -1)
  {
    //Fire all other requests directly to our WebServers
    return fetch(request)
  }
  else //Return maint page if you're not calling from a trusted IP
  {
    // Return modified response.
    return new Response(maintenancePage, {
      status: 503,
      headers: modifiedHeaders
    })
  }
}

let maintenancePage = `
<!doctype html>
<title>Site Maintenance</title>
<div class="content">
    <h1>We&rsquo;ll be back soon!</h1>
    <p>We&rsquo;re very sorry for the inconvenience but we&rsquo;re performing maintenance. Please check back soon...</p>
    <p>&mdash; Awesome Team</p>
</div>
`

地形

我们现在将使用 Terraform 创建脚本并创建工作路由。可以使用cloud_worker_script资源使用 Terraform 创建工作脚本:

resource "cloudflare_worker_script" "this" {
  name    = "maintenance"
  content = file("/maintenance.js")
}

这将创建一个 Cloudflare worker 脚本,我们可以使用cloudflare_worker_route引用它。路由资源将在具有指定 url 模式的区域中部署 worker:

data "cloudflare_zones" "this" {
  filter {
    name = "hodovic.cc/*"
  }
}

resource "cloudflare_worker_route" "this" {
  zone_id     = lookup(data.cloudflare_zones.this.zones[0], "id")
  pattern     = "hodovi.cc/maintenance/*"
  script_name = cloudflare_worker_script.this.name
}

所有访问/maintenance/路径的用户都将显示维护页面,但列入白名单的 IP 除外。

地形模块

上面介绍的解决方案很简洁,尽管我们想要一个可重复使用的模块。因此,我创建了一个Terraform 模块来创建和部署 Cloudflare Worker。但是,为了使模块可重用,我们需要动态 html 内容:

  • 标志

  • 字体

  • 公司/团队名称

  • 网站图标

  • 用于支持的电子邮件地址

Cloudflare 支持我们可以在 Terraform 模块中定义的键/值存储。我们将调整之前的cloudflare_worker_script以添加键/值存储:

resource "cloudflare_worker_script" "this" {
  name    = "maintenance"
  content = file(format("%s/maintenance.js", path.module))

  plain_text_binding {
    name = "COMPANY_NAME"
    text = var.company_name
  }

  plain_text_binding {
    name = "WHITELIST_IPS"
    text = var.whitelist_ips
  }

  plain_text_binding {
    name = "LOGO_URL"
    text = var.logo_url
  }

  plain_text_binding {
    name = "FAVICON_URL"
    text = var.favicon_url
  }

  plain_text_binding {
    name = "FONT"
    text = var.font
  }

  plain_text_binding {
    name = "EMAIL"
    text = var.email
  }
}

我们可以创建一个 HTML 片段并传递环境变量:

let maintPage = (company_name, logo_url) => `
<body>
    <div class="content">
        <img class="logo" src="${logo_url}" alt="${company_name}">
        <div class="info">
            <h1>Our site is currently down for maintanence</h1>
            <p>We apologize for any inconveniences caused and we will be online as soon as possible. Please check again in a little while. Thank you!</p>
            <p>&mdash; ${company_name}</p>
        </div>
        <img class="image-main" src="https://i.imgur.com/0uJkCM8.png" alt="Maintenance image">
        <hr />
        <a href="mailto:${email}?subject=Maintenance">You can reach us at: ${email}</a>
    </div>
</body>
`;

我们还将为字体创建动态 CSS:

body {
    text-align: center;
    font-family: "${font}", sans-serif;
    color: #0C1231;
}

html/css 片段更加复杂和动态,完整的源代码可以在Github上找到。

该模块支持几个变量:

  • 标志

  • 字体(谷歌字体)

  • 邮箱

  • 团队名称

  • 白名单IP

您可以使用 Terraform 的module创建它:

module "hodovi_cc_maintenance" {
  source          = "git::git@github.com:adinhodovic/terraform-cloudflare-maintenance.git?ref=v0.1.3"
  enabled         = false
  cloudflare_zone = "hodovi.cc"
  pattern         = "hodovi.cc/maintenance/*"
  company_name    = "HoneyLogic"
  email           = "support@honeylogic.io"
  font            = "Poppins"
  logo_url        = "https://s3.eu-west-1.amazonaws.com/honeylogic.io/media/images/Honeylogic-blue.original.png"
  favicon_url     = "https://s3.eu-west-1.amazonaws.com/honeylogic.io/media/images/Honeylogic_-_icon.original.height-80.png"
}

维护页面的预览可以在这里找到,完全可以根据您的团队需求进行调整!

Logo

CI/CD社区为您提供最前沿的新闻资讯和知识内容

更多推荐