Day 08-Code 要 Review,Infrastrcture 岂不 Review?吾未见其明也

Code 要 Review,Infrastrcture 岂不 Review?吾未见其明也

CI/CD 系列

  • day 08-Code 要 Review,Infrastrcture 岂不 Review?吾未见其明也
  • day 09-(暂定:dedicated service principal for terraform)
  • day 10-(暂定:github action CI/CD automation)
  • day 11-(暂定:atlantis plan apply automation)
  • day 12-(暂定:tfsec automatic security check)

课程内容与代码会放在 Github 上: https://github.com/chechiachang/terraform-30-days

赛後文章会整理放到个人的部落格上 http://chechia.net/

追踪粉专可以收到文章的主动推播

https://ithelp.ithome.com.tw/upload/images/20210901/20120327NvpHVr2QC0.jpg


软件开发中,我们要求严谨的 Code workflow,有 Review 还有 release 流程

但 infra 却没有这些步骤:只是上去 console 点一点,把 infra 开起来,把很稳的 code,透过很稳的 CI/CD 放到没有 review 流程的 infrastructure 上运行,然後祈祷他会很稳。结果就是

  • code 好,却跑不好
  • infra 鬼故事多
    • 不改就不会坏
    • 新功能,稳定性,二选一,或是两个都没有

Terraform workflow

导入 terraform 後,团队成员都可以各自撰写 terraform 来描述 infrastructure,然後各自 plan 各自 apply,这样个工作流程在小规模的 infrastructure 中是可以运作的。然而随着团队规模增加,infra 越来越复杂,这样协作性低的工作流程,便会面离许多挑战。

Terraform 官方文件也针对团队导入的阶段做说明,也描述实务上 infra 管理的困难,这边只简述摘要 infrastructure 管理的两大困难:

  • 技术 infra 越来越复杂
    • 实务上会累积许多不一致(ex. infra 团队常见:我以为是这样,但怎麽实际 cloud 上是长这样勒?)
    • Terraform 是简化的工作流程抽象框架(workflow-level abstraction),固定工作流程(init,plan,apply...)
  • 团队组织越来越复杂
    • 分工,各个团队各自负责,但又要沟通协作
    • 平行开发,注重效率,但整合又要要避免冲突与错误

这些问题是所有 IaC 工具都试图解决与优化的部分。Infrastructure as Code 不只是将 web console 上的手动点击操作,替换成程序码操作而已,使用 IaC 来管理 infrastructure,除了更改使用方式,还有许多延伸的优势,例如搭配使用程序码的管理工具,进一步提升 IaC 程序码的整体效率,达成 infrastructure 管理的元件化,标准化与自动化。

这边要先说明,不是自动化就是好

  • 步骤标准化可以降低错误机率
  • 自动化可以达到更高效率
  • 然而,技术栈的选择应该以团队为本

底下我们会介绍 IaC 高效开发的范例,导入 gitflowd 开发流程,来管理 IaC,使用到的工具有:

Core workflow

  • Github flow
  • Terraform Team Workflow
    • Terraform 推荐自家的 Terraform Cloud 作为范例介绍
    • 我们底下会使用 Github,事实上任何模式的 git-flow 都能套用

回顾一下 Github 具体的开发流程

  • create branch
    • Write:编辑.tf 档案
    • Plan:本地 validate, plan,检查结果
      • pre-commit:terraform fmt
    • (Optional) Apply:最好有 dev 环境可以让 infra 自由测试
  • add commits
  • Create Pull Request & Review
  • Apply to stag / prod

local branch

本地开发

  • 取得新的 feature request 後,进行 .tf 档案的更改
  • 更改完後执行 terraform plan,确定 plan 与预期相同
  • commit
  • 推上 remote branch

在 commit 之前,还有一些事情可以透过 pre-commit hook 处理,例如:

  • 确认 .tf 都是有效的,不会有错误的程序码,因为人为疏失被 push 到远端
  • 希望在 remote branch 上的 .tf coding-style 与格式都相同

上面这两件事,terraform cli 都已内建 (都内建了,不做真的说不过去)

  • terraform validate
  • terraform fmt

Pre-commit

使用 ㄠpre-commit 工具,每个开发人原本机都需要 安装 pre-commit,然後依据 .pre-commit-config.yaml 的设定,自动安装 pre-commit 中指定的 script

$ sudo port install pre-commit
# brew install pre-commit

$ pre-commit --version
pre-commit 2.13.0

然後使用 gruntwork 准备的 pre-commit script,进行以下几个 pre-commit script

repos:
  - repo: https://github.com/gruntwork-io/pre-commit
    rev: v0.1.12 # Get the latest from: https://github.com/gruntwork-io/pre-commit/releases
    hooks:
      - id: terraform-fmt
      - id: terraform-validate
      - id: tflint
      - id: shellcheck
      - id: gofmt
      - id: golint

执行 pre-commmit install 来安装 script 到本地

$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

手动驱动执行 pre-commit run,来检查新增的 git changes
或是执行 pre-commit run --all-files,来检查所有档案

git add .
pre-commit run
pre-commit run terraform-fmt
pre-commit run --all-files

Terraform fmt............................................................Passed
Terraform validate.......................................................Passed
tflint...................................................................Passed
Shellcheck Bash Linter...................................................Passed
gofmt....................................................................Passed
golint...................................................................Passed

设定完成後,以後每次 commit 前就会自动执行,不用担心忘记 fmt 就 commit 歪七扭八的 code

pre-commit 还可以额外增加许多功能,这些功能我们在之後会介绍,例如

  • terragrunt test:使用 golang 来执行 infra 的测试
  • infracost:使用 tool 来计算新的 plan 在公有云上的费用

Remote Branch & Pull Request

在本地执行过基本 fmt,validate,lint 与 local test 後,我们把相对稳定的 branch 推到 Github 上。这已确定远端的 code 有一定品质。

CI 可以接收 Branch Push event

CI 可以接收 Pull Request event,只要有 Pull Request 产生:

  • 针对 git diff 部分进行验证,ex. terraform fmt -recursive,或是更完整的测试
  • 显示新的 plan
  • 直接将 Pull Request 的 infrastructure 使用 test framework 产生到公有云上,测试
    • CI 最後再 destroy 所有测试用 resource

Pull Request 除了自动化测试以外,当然还有人工 Review

  • 当然需要 Review .tf 程序码本身
  • bot / github action 可以执行 plan 结果,然後备注在 Pull Request 中,辅助 Review
  • 其他如 lint,效能与执行时间,都可以显示在 Pull Request 中

Review 是 Github flow 的核心

  • IaC 的 infra 才容易做完整的 Review
  • Review 的延伸意涵,是在整合团队的程序码,并传递团队文化
    • coding style,如何提升品质,什麽品质是可以接受的...等等
  • 经过完整测试 + 人工 Review 的档案才会 merge 到 master 中

Master Branch

所有 master 的 .tf code 都

  • 经过 apply 测试(到test framework)
  • 经过人工 Review

都是稳定的程序码,可以自动 apply 到 stag 环境,stag 上有相对稳定的 infrastructure 搭载稳定的 app code,这时让 QA team 进驻做更详细的测试,可以发现更细部的错误

  • infrastructure 的变更造成错误
  • 新 infrastructure 跟 app 版本不匹配,例如:app 需要下一版的 infrastructure 的新元件
  • 效能 performance 测试,效能比起上一版本 infrastructure 是否提升
  • 搭配 app 做压力测试,app 端压力升高时,infrastructure 是否称得住
  • 服务的可用性测试,infrastructure 是否能支撑
  • ...无尽的测试

Release

依照产品时程准备 release candidate

  • 根据 product release 的时程,cherry-pick master 的功能到 release branch
  • 打上当前 release candidate tag,例如:v1.0.0-rc
  • 与 app 版本搭配,进入 pre-prod 环境发布与测试
  • 如果有抓出错误,打上 hotfit commit 修复

确定 release 版本,打上 release tag,例如:v1.0.1

  • 准备 changelog
  • 准备 infrastructure changelog,本次 apply 是否会影响正在线上运作的服务
  • app 与 infrastructure 配合 release

CI: Github Action

Github Action 是 Github 支援的 CI 工具,十分方便,而且是免费使用。我们这边直接使用 Github Action 来做,目的在教学单纯化,以及可以节省成本。drlook/terraform-github-action 有非常多开源范例,这边实际套用

tree .github
.github
└── workflows
    ├── lint.yaml
    ├── fmt.yaml
    └── plan.yaml

workflow 有

  • lint: 在所有 push branch 上坐 validate 与 fmt
  • fmt: 在 master branch 上执行 fmt,然後自动发 PR 校正回归到 master(可被 pre-commit fmt 取代)
  • plan: 在 PR 的内容

CD: deploy to azure

https://thomasthornton.cloud/2021/03/19/deploy-terraform-using-github-actions-into-azure/

  • create ad service principal for terraform
    • test terraform run with service principal
  • Config Github Aciont

CI: Terraform Cloud

Terraform 官方提供的 Github Action 整合说明,需要依赖 Terraform Cloud。放在这边让大家参考

Github action Alternatives

  • 各种 CI 工具皆可,例如:
    • circleCI, DroneCI, travisCI

考量

  • 安全性
    • Sass platform
    • on-premises / self-hosted
      • Self-hosted Github Enterprise
  • 各家的功能支援程度
  • 团队熟悉程度

References


<<:  从精准回馈来看成长重要性

>>:  Day8 - 程序设计报价 (三) - 常见问题

Day13 - 使用 Kamigo 取得事件资讯

GitHub 网址:https://github.com/ Kamigo 说明文件:https:/...

[Day 4] 使用 Gradle Multi-Project Builds X Shadow Plugin X Docker Compose 建置、打包、部署

以往 Gradle 只能使用 Groovy 语言撰写 Script,因为我对 Groovy 不熟,所...

除了刷题之外的事 - Software Engineering

除了刷题之外的事 「程序设计」的练习是一种从「写得出」程序到「写得好」持续迭代的优化过程,在 Le...

Android Studio初学笔记-Day26-ExpandableListVIew(2)

接续昨天,今天要讲的是ExpandableListView的主体拉,首先创一个java档,我命名为M...

ES2021(ES12) - Intl、WeakRef

本系列文章经过重新编排和扩充,已出书为ECMAScript关键30天。原始文章因当时准备时程紧迫,...