manage cloudflare with terraform without breaking existing settings

# devops

最近隨著browser頁面越開越多,畫面一直要切來切去的,加上每次登入 cloudflare 都要拿起手機輸入二階段驗證,感覺有點煩 lol

所以實在是有點懶得手動進入 cloudflare 頁面了,就打算開始來用工具管理 cloudflare 的設定,其實在以前工作上有稍微用terraform 來管理VM,不過是直接一開始就用 terraform 管理了,所以不會遇到上面設定跟你的 terraform 不一致的狀況! (除非有人頁面進入自己改啦。。) 不過這次狀況是我一開始就已經在 cloudflare 做了一些操作,像是域名管理 ~ 所以需要想個方法來 sync 上面的值。

爲何要自動化跟透過 terraform 管理

確實今天如果只有單純管理 cloudflare 而已,而且如果設定不多不複雜,個人簡單開發而已,沒啥需求需要用到沒錯,不過今天我這邊還想要多加管理 github action 的 secrets 和 environment variables,或許有人會覺得兩個網站而已,也還好吧? 或許是吧? 不過這要管理的事物只會越來越多,所以儘早自動化跟有地方統一管理會比較好! 要不然四散各地,沒有良好的文檔支持會很難過的~

好啦,既然決定了就來研究看看要怎麼把 cloudflare 的設定給 sync 下來,讓我沒想到的是,竟然官網就有文章是關於這樣的議題 https://developers.cloudflare.com/terraform/advanced-topics/import-cloudflare-resources/

來嘗試一下

其實基本上按照官方文章教學跟著做,就差不多了,沒有特別的地方需要注意。 算是滿方便的,它有提供 cf-terraforming 這個 cli(command line interface) 工具,來幫你抓取你目前 cloudflare 上面的設定,使用方法文章也寫的滿清楚的,事前準備就是需要 cloudflare 的 token,然後用 cf-terraforming generate terraform 檔案。

到這邊爲止,你只有完成同步設定到 terraform 的 file, 但是你還需要做 terraform state 的設定,滿貼心的 cf-terraforming 也是有做該功能 cf-terraforming import 基本上無腦跟著文章做,你應該就順順利利完成了!

唯一你可能會遇到的問題是~

如果你用 terraform 的 cloudflare plugin 版本是4.5以上,如下面這樣是用版本5

像下面這樣指定版本

terraform {
  required_providers {
    cloudflare = {
      source = "cloudflare/cloudflare"
      version = "5.0.0-rc1"
    }
  }
}

你會發現 cf-terraforming 執行 command 有機會報錯 (看你使用到cloudflare什麼資源)~ 因爲版本5還不太穩定,這邊建議是用4.5比較安全。到這邊爲止,cloudflare很順利,接著來研究看看 terraform 有沒有 github action plugin , 沒意外應該是有啦,畢竟 community 這麼大,多少都會有人寫

terraform manages github action secrets

我這邊需求其實很簡單,只需要管理 github action 上面的 secrets 而已,原因也是我想要有地方統一管理secrets加上有terraform管理,我會比較知道那些secrets是什麼~ 要不然我單純在網頁編輯後,搞不好日子久了會忘記 lol

果不其然有相關的plugin https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret , 文檔說明也夠清楚了

resource "github_actions_secret" "example_secret" {
  repository       = "example_repository"
  secret_name      = "example_secret_name"
  encrypted_value  = var.some_encrypted_secret_string
}

這樣就可以建立名字 “examplesecret” 的 secret 到 github action ci secrets 上面了! 但是呢~ 關於sync github secrets的值是做不到的,github action 似乎不提供方法讓你知道他的值,所以在你還知道那些secret的值是什麼的時候趕緊把他們換成 terraform 管理(如果你想用 terraform 管理的話啦)。

關於把值丟進secrets的方式,我目前是用 locals 來讀取檔案的方式把值丟進去 github secrets, 如下面的方式

locals {
  provision_profile = filebase64("./files/xxx")
  cert = filebase64("./files/xxx")
  songa = yamldecode(file("./files/xxx.yaml"))
}

data "github_repository" "repo" {
  full_name = "xxx"
}

resource "github_actions_secret" "MACOS_PROVISIONING_PROFILE" {
  repository      = data.github_repository.repo.name
  secret_name     = "MACOS_PROVISIONING_PROFILE"
  plaintext_value = local.provision_profile
}

當然這些檔案會加在 .gitignore 裡面,不要不小心把他們加進版控裡面~ 不過如果你想要用 git 管理這些敏感資料怎辦? 畢竟你總不可能一直都在同臺電腦吧? 會有需求需要把他們放到 remote storage,之後其他電腦也可以載下來,要不然你永遠都被迫只能在同個環境做這些 devops 的事情! 這邊我爲了方便我是使用 git secret 來管理啦。

另外其實terraform github action這個套件還有很多功能啦~ 只是我暫時用不到其他的。

如何用 git secret 來隱藏敏感資料

其實git secret背後原理也是加密、解密,它是用到 gpg (hybrid symmetric and asymmetric)來實現的,這邊就不詳述其原理。

使用它來把你想要加密的檔案加密後,你應該會看到 .gitsecret 資料夾被產生出來,裡面其中 .gitsecret/paths/mapping.cfg 可以看到你加密了哪些檔案,再接著執行 git secret hide , 就會跑出一些 xx.secret 檔案,這就是被加密過的檔案,其他人沒有金鑰還有你一開始訂的密碼是無法解密檔案的~ 原則上這樣你就可以快快樂樂的把東西推上去了。

總結

目前只是一個基本雛形,等到我用到的服務越來越多,我想納入terraform來管理的東西也會跟著變多,現在裡面結構也沒特別多項目,不過怎樣個人需求用的應該都不會比在公司用的複雜啦,如下圖

至少目前這樣,舒服了不少lol~ 等到之後用得更多有其他心得再來記錄。

If you like my content,

feel free to buy me a coffee

Enjoy crafting new things

Never stop learning.

Life is the sum of your daily habits.

Find things that you enjoy and please

Doit.

Feel free to connect with me.

Created by potrace 1.16, written by Peter Selinger 2001-2019

© Jing 2024. All rights reserved.