我自己制作了一个用于Terraform Provider的GitHub Actions,并尝试发布了出来
首先
自 2018 年开始似乎已经有针对 Terraform 的 GitHub Actions,但思考一下,我自己制作的适用于企业云的 Terraform Provider 是否可用呢……经过一番验证,很快就发现不行。
如果是社区提供者的原因,那是因为没有插入该二进制文件的方式。
基本上,GitHub Actions 在 Docker 映像上運行,但是沒有一種方法可以將該二進制文件傳送到 entrypoint.sh(它是由該 Docker 映像中的某個插件路徑呼叫的)。看這些內容就能明白這種情況。
我无奈之下决定自己动手并以此为学习机会。
尝试过的事情 (Shiyan guo de shiqing)
我决定用以下的想法来准备适用于自制提供者的GitHub Actions。
-
- GitHub Actionsから呼び出されるイメージは、基本hashicorp/terraformベースのものにする
-
- イメージビルド時は、Dockerfile内で、コンパイル済みの自作プロバイダのバイナリを / においておくように処理をしておく
GitHub Actions経由で上記イメージがrunされる際、どうやら /github が -v 経由でマウントされている。かつ、ここが $HOME 相当になってしまうため、イメージビルドの段階で ~/.terraform.d/ 配下にプロバイダのバイナリをおいておく意味がないように見える(実際の挙動はコードレベルでちゃんと確認しておきたいが・・・)
GitHub Actionsの各サブコマンド(plan , validate …)毎にentrypoint.shを作っておき、その中で、事前に / においておいたバイナリをプラグインの所定のディレクトリである、 ~/.terraform.d/plugins/linux_amd64 に コピーする という処理を毎回入れる
その後に terraform init や terraform apply 等が動くようにすることで、プロバイダが見つからない問題を回避する
虽然有许多改进点,但我想先试着用这个来实现一下。
准备用于生成基础映像的Dockerfile。
首先,在这里创建一个用于基础镜像的Dockerfile和entrypoint.sh文件。
现在使用的是 hashicorp/terraform:0.12.3 版本。
实际上,在GitHub Actions方面进行调整的想法是通过继承进一步完善它。
通过给予这些图标相应的标签,使其具有适合的形象,从而使工作流的图标看起来更接近所需的形象。
所以,再重申一遍,这是用于基础的。
与Docker Hub集成
请将这个仓库与Docker Hub进行连接,并自动化构建。
首先连接GitHub账号,然后创建一个代码库。
这次我们选择了keiichihikita/terraform-ecl这个形式。
下一步是向该存储库添加构建设置。
我暂时采取了类似以上的方式。
我将它保存下来并手动触发一下。
看起来成功地完成了。状态显示为成功。
准备一个GitHub Actions的代码库
GitHub Actions的每个操作实质上是一个仓库。
我试着用这种感觉来制作。
几乎完全抄袭自原作。
改变的是两个重要的点。
-
- ベースのイメージを変えてます。例えば こんな 感じです。
- 最初に書いた、プロバイダのバイナリを $HOME/.terraform.d/plugins/linux_amd64 配下に持ってくる処理を追記しています。こんな 感じです。
我试着用这个动作。
特别是针对没有webhook的仓库,另外创建一个仓库,将PR提交到该仓库进行操作确认。
(由于这是一个私有仓库,所以您可以从以下大致推测其结构…)
准备main.workflow
为了运行GitHub Actions,我们需要放置 .github/main.workflow 文件。
这可以通过浏览器的图形界面(GUI)创建,也可以通过使用HCL语言直接创建文件,两种方式都可以。
(意外之处在于它是使用HCL语言编写的。)
以下是基本流程的概述,我会在下面写出一些需要考虑的要点。
从https://github.com/hashicorp/terraform-github-actions/releases获取最新版本,并替换所有的@v实例。例如:uses = “hashicorp/terraform-github-actions/plan@v3.0″。
我在我的情况下将GitHub Actions的主要master更改为查看我自己准备好的版本。
目录 – 如果您的Terraform配置不在仓库的根目录中,请替换所有实例
因为我个人情况下(也就是说,我应用了GitHub Actions的存储库),我的tf文件组是放在顶层的,所以不需要特别考虑。
实际上,形式如下:
% tree . .
├── main.tf
├── provider.tf
└── terraform.tf
工作空间 – 如果您的Terraform在不同于默认的Terraform工作空间中运行,请在terraform-plan动作中更改TF_ACTION_WORKSPACE环境变量。
如果使用Terraform Cloud Free Tier,工作区将无法使用,因此我将其保持为默认状态。
因此,最终的 main.workflow 如下所示。
workflow "Terraform" {
resolves = "terraform-plan"
on = "pull_request"
}
action "filter-to-pr-open-synced" {
uses = "actions/bin/filter@master"
args = "action 'opened|synchronize'"
}
action "terraform-fmt" {
uses = "keiichi-hikita/terraform-ecl-github-actions/fmt@master"
needs = "filter-to-pr-open-synced"
secrets = ["GITHUB_TOKEN"]
env = {
TF_ACTION_WORKING_DIR = "."
}
}
action "terraform-init" {
uses = "keiichi-hikita/terraform-ecl-github-actions/init@master"
needs = "terraform-fmt"
secrets = ["GITHUB_TOKEN", "TF_ACTION_TFE_TOKEN"]
env = {
TF_ACTION_WORKING_DIR = "."
}
}
action "terraform-validate" {
uses = "keiichi-hikita/terraform-ecl-github-actions/validate@master"
needs = "terraform-init"
secrets = ["GITHUB_TOKEN", "TF_ACTION_TFE_TOKEN"]
env = {
TF_ACTION_WORKING_DIR = "."
}
}
action "terraform-plan" {
uses = "keiichi-hikita/terraform-ecl-github-actions/plan@master"
needs = "terraform-validate"
secrets = ["GITHUB_TOKEN", "TF_ACTION_TFE_TOKEN"]
env = {
TF_ACTION_WORKING_DIR = "."
# If you're using Terraform workspaces, set this to the workspace name.
TF_ACTION_WORKSPACE = "default"
}
}
在图上看,它呈现出这样的形状。(只能看到一部分)
我把图标变成了蓝色(原版是紫色),但这是通过每个动作的Dockerfile的LABEL来改变的。
试着提交一个Pull Request 的时候,亲自实践一下。
我会对 main.tf 进行以下更改并提交 PR。
resource "ecl_compute_keypair_v2" "kp1" {
name = "kp1"
}
如果顺利的话,处理将按以下方式按顺序进行流动。
所以最终评论区会变成这样。
是的,我成功地到达了计划中的目的地。
思考或者感受到的意见或体验。
我想要阅读更多关于GitHub Actions开发者的文档。
我个人认为,如果能够有一种方式将提供者的二进制文件直接注入到原始操作中,那就好了。但是,如果每次在entrypoint.sh中执行wget等操作,将会非常慢,而且很难将其集成到主体镜像中。不知道什么方法是最好的……我觉得那些拥有非官方提供者的人可能也有同样的困扰。
根据此感觉,我先前所写的是,相比较而言,Atlantis更容易准备环境,而且使用起来也更方便。
嗯,很快应该就能在 Terraform Cloud 免费层面上实现,如果能这样的话,我觉得可能会是最强的选择。
所以,我认为这是相当罕见的。
-
- Enterprise CloudをTerraformで構築したい
- そのCIをGitHubだけで完結させたい
如果您是這種人,請務必使用它。
我想一想,我只在 Terraform Cloud 环境下进行了测试,但应该没问题!