• 云原生之旅 - 7)部署Terrform基础设施代码的自动化利器 Atlantis


    前言

    前面有几篇文章讲述了如何使用Terraform创建资源 (基础设施即代码 Terraform 快速入门使用 Terraform 创建 Kubernetes) 以及 Kubernetes时代的包管理工具 Helm 里也讲述了如何用Terraform 安装 Helm Charts,但我们都是在local 执行Terrafrom的,那么有什么办法自动化整个流程呢?并且让这些基础设施的代码也需要走Pull Request Review 评审。

    这时候推荐一款利器:开源工具 Atlantis,在代码提交时自动运行terraform plan命令,并将 plan命令的输出添加到pull request的注释中,经过团队伙伴Approve之后,才能执行terraform apply 变更资源,资源apply 成功之后,代码合并到master分支,整个流程遵循GitOps的最佳实践。换句话说就是我们使用了 Atlantis 为 Terraform 实现 GitOps。

    Atlantis 在国内的文章很少,本篇文章就给大家详细的介绍下如何使用这款利器。

    关键词:Terraform自动化,Atlantis入门,Atlantis示例,Terraform Pull Request Automation, Terraform基础设施自动化

     

    安装

    前提条件

    * Kubernetes 我用的GKE 1.22 

    * 准备一个common github user, 也可以用自己的账号

    * 准备 Personal Access Token

    * 随机生成一个 Webhook Secret

    * kubectl 建一个 generic secret 供Atlantis使用

    echo -n "xxx" > ghUser
    echo -n "xxx" > ghToken
    echo -n "xxx" > ghWebhookSecret
    
    kubectl create secret generic atlantis --from-file=ghUser --from-file=ghToken --from-file=ghWebhookSecret

     

    安装

    有多种方式,这里使用Kustomize 作为例子,k8s manifests 参考 my repo

    修改 statefulset-patch.yaml 环境变量为自己的。

    kustomize build sre-mgmt-dev > deploy.yaml  
    
    kubectl apply -f deploy.yaml 

     

    配置网关

    需要一个Gateway,配置一个 URL 指向 atlantis ClusterIP svc ,我的 Ingress-nginx 配置参考。(Optional) Ingress-Nginx入门参考我下一篇文章 云原生之旅 - 8)云原生时代的网关 Ingress Nginx

    也可以把atlantis 置成 LB类型或者NodePort本地测试。

     

    配置Github webhook

    很简单,参考文档 https://www.runatlantis.io/docs/configuring-webhooks.html#github-github-enterprise

     

    使用

    权限

    确保Running 在 Kubernetes 的 Atlantis service account 对所操作的资源有权限,能Terraform init/plan/apply 云端资源。

    我这里是GCP Project作为例子。

    * GKE default service account use node service account.
    * (Optional) for GKE Workload Identity: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity
     

    配置 Atlantis.yaml

    简单例子如下

    假设Terraform 代码结构如下

    复制代码
    Terraform
    ├── quick_demo1
    │   ├── xxx.tf
    │   └── xxx.tf
    ├── quick_demo2
        ├── xxx.tf
        └── xxx.tf
    复制代码

    Atlantis yaml 配置

    复制代码
    ---
    version: 3
    automerge: true
    delete_source_branch_on_merge: true
    
    projects:
    - name: project-1
      dir: Terraform/quick_demo1
      terraform_version: 1.2.9
      autoplan:
        when_modified:
        - '**/*.tf'
    
    - name: project-2
      dir: Terraform/quick_demo2
      terraform_version: 1.2.9
      autoplan:
        when_modified:
        - '**/*.tf'
    复制代码

    当你修改TF文件 提交PR的时候,Atlantis 会自动使用default workflow 执行 Terraform Plan, plan result 会 comment到 PR里面。

    注意: 需要配置 Github -> Settings -> Branches-> Branch protection rule -> Protect matching branches 需要Approve才能merge。

    然后有队友Approve了PR, 你才可以执行 Atlantis Apply, 最终资源会被Terraform apply,PR 自动 merged to master。

     

    Workflow breakdown

    •  Step 1: Open a Pull Request
    •  Step 2: Atlantis automatically run `terraform plan` and comments back on PR
    •  Step 3: Someone reviews and approves PR
    •  Step 4: Comment `atlantis apply`
    •  Step 5: Atlantis run `terraform apply` and comments back on PR about result
    •  Step 6: PR merged automatically.

     

    自定义 Workflow

    加个Terraform format check, 代码如下:

    复制代码
    workflows:
      test:
        plan:
          steps:
          - env:
              name: ENV_NAME
              command: 'echo "dynamic-value-$(date)"'
          - run: terraform${ATLANTIS_TERRAFORM_VERSION} fmt -check=true -write=false -diff=true
          - init
          - plan
        apply:
          steps:
          - apply
    复制代码

     需显示申明使用此workflow 如 "workflow: test", 完整 Atlantis yaml 参考 

    ---
    version: 3
    automerge: true
    delete_source_branch_on_merge: true
    
    projects:
    - name: project-demo
      dir: Terraform/quick_demo
      terraform_version: 1.2.9
      autoplan:
        when_modified:
        - '**/*.tf'
    
    - name: project-module-demo
      dir: Terraform/module_demo/project_1
      terraform_version: 1.2.9
      workflow: test
      autoplan:
        when_modified:
        - '**/*.tf'
    
    # (Optional) custom workflows
    workflows:
      test:
        plan:
          steps:
          - env:
              name: ENV_NAME
              command: 'echo "dynamic-value-$(date)"'
          - run: terraform${ATLANTIS_TERRAFORM_VERSION} fmt -check=true -write=false -diff=true
          - init
          - plan
        apply:
          steps:
          - apply
    atlantis.yaml

     

    测试 

     

    总结

    我们的Terraform 代码结构是按环境分成不同的folder,这样做的好处是可以通过github CODEOWNERS文件来针对不同的文件夹(环境)给不同的组权限。比如以下例子给予group-dev权限审批这个folder project-xx/dev下面的Terraform代码变化。

    * @sre
    Terraform/project-xx/dev/** @group-dev
    Terraform/project-xx/prod/** @sre

    我们也试过同一套代码利用Terraform的工作区workspace 来区分环境,实践下来不如上面的结构灵活,维护性差。

     

    感谢阅读,如果您觉得本文的内容对您的学习有所帮助,您可以打赏和推荐,您的鼓励是我创作的动力。 

     

  • 相关阅读:
    springboot mybatis多数据源配置
    Undefined和Null的区别
    PHP保存时自动删除末尾的空格,phpstorm自动删除空白字符串
    IEEE COMMUNICATIONS LETTERS (ICL) 投稿状态记录
    2023系统架构设计师备考攻略!附完整备考资料!
    【光伏场地建设规划】python实现-附ChatGPT解析
    云原生时代开发提效神器-Nocalhost
    一文带你学会 consul 基本使用和 Docker 部署
    全新代购商城源码,迅速实现财富梦想!
    火狐浏览器翻译页面功能如何设置
  • 原文地址:https://www.cnblogs.com/wade-xu/p/16839827.html