Day 17-实务上如何写出 terraform module,以 AKS 为例

本章介绍实务上如何写出自己的 terraform module

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

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

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

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


NOTE

  • 课程范例会超出永久免费额度,会消耗 azure credit,用完请 destroy
  • 范例会产出 kubeconfig 档案,内含可以存取 cluster control panel 的 private key,请妥善保存
  • 范例 AKS 是功能完整的 AKS,但不适合直接做 production 环境使用
    • 需要 补齐 security hardening

Prerequisite & Steps

  • infrastructure 本身的知识
    • 了解 subnet
    • 了解 AKS
    • 理解 infrastructure 的参数。terraform 的文件并不会说明 resource 参数的细节,还是要对照 cloud provider 的文件。
  • terraform 官方文件,查询module 的使用方法,参数格式
    • 理解 AKS module 的 inputs, outputs
  • 根据需求调整 module 参数
    • 使用 meta-argument, built-in functions 协助管理 module
  • plan & apply 完整的 module

Requirements & spec

今天的范例内容在此 azure/dev/southeastasia/chechia_net/kubernetes

  • 假设需求是「为 https://chechia.net 的後端架设 AKS 集群」
  • 测试用的 dev 环境
  • 网站的主要用户在东南亚,所以 location 放在 southeastasia
  • 路径上放上 chechia_net 路径,把相关的 resource root module 放进来

Content

养成好习惯:使用任何 terraform module 时都务必检查一下内容物

# azure/dev/southeastasia/chechia_net/kubernetes/terragrunt.hcl

terraform {
  source = "../../../../..//azure/modules/kubernetes_cluster"
}

dependency "network"{
  config_path = find_in_parent_folders("azure/foundation/compute_network")
}

inputs = {
  ...
  kubernetes_cluster_name = "terraform-30-days"
  default_node_pool_vm_size = "Standard_D2_v2" # This is beyond 12 months free quota
  default_node_pool_count = 1

  network = dependency.network.outputs.vnet_name # acctvnet
  subnet  = dependency.network.outputs.vnet_subnets[2] # dev-3

  kubeconfig_output_path = pathexpand("~/.kube/azure-aks-terraform-30-days")

  spot_node_pools = {
    spot = {
      vm_size    = "Standard_D2_v2"
      node_count = 1
      ...
    }
  }

}

terragrunt.hcl

  • 定义 source 到本地的 module,稍後要来看 module 内容
  • 定义 dependency,说明这个 aks 依赖 network
  • 定义 kubeconfig output path,这个是 apply 之後的输出产物
    • aks 建立後,会产出 kubeconfig,包含 cluster 资讯与 credential
    • 使用 kubeconfig 可以存取 aks,是敏感资料,所以要放到本地安全的地方
  • inputs
    • aks 本身的 input 参数
      • 使用 vm size 是超出 12 个月免费额度的,会扣 credit
      • network, subnet, ...
    • aks 的下一层 node pool 的 input 参数
      • 使用 vm size 是超出 12 个月免费额度的,会扣 credit
      • node pool 的 vm size, node count, ...等

把不同层的参数放在最上层传入,方便使用,但会降低可读性(不同 resource 的参数混杂)

  • 以程序语言类比,相当於上层 function 调用其他 function,把 variable 透过 function argument 送到最上层传入
  • coding style 可以团队讨论是否要这样写

module content

看一下 modules

tree -L 1 azure/modules/kubernetes_cluster

azure/modules/kubernetes_cluster
├── README.md
├── client_config.tf
├── kubeconfig.tf
├── kubernetes_cluster.tf
├── node_pool.tf
├── output.tf
└── variables.tf

0 directories, 7 files

透过client_config.tf 取得 terraform 呼叫时的 provider 中的 config

# client_config.tf
 data "azurerm_client_config" "current" {}

kubeconfig.tf 是透过 local_file resource,将建立 cluster 後的 cluster config 与 credential 存入本地档案

kubernetes_cluster.tf 描述 azurerm_kubernetes_cluster resource,以及 aks 本身依赖的其他 resource

how to create module

azure/modules/kubernetes_cluster 是如何写出来的?其实就是围绕需求,慢慢补齐 module 的功能

  • 查找 terraform aks resource 的文件,参考范例先出 kubernetes_cluster.tf
  • azure/dev/southeastasia/chechia_net/kubernetes 尝试 plan 与 apply
    • 检查结果,做功能性测试,这个 module 是否能用,有无缺什麽设定与参数?...
  • 继续修改,例如
  • 过程中有需要传入的参数,就写在 variables.tf 让最上层呼叫的时候传入

由於我们的设计是会有 dev-aks, stag-aks, prod-aks 使用相同的 module 产生,所以要把不同环境下的不同参数,传到最上层的 terragunt.hcl

  • 实际上线,可能会有底下几个环境,透过不同路径的 terragrunt.hcl 产生
    • azure/dev/southeastasia/chechia_net/kubernetes/terragrunt.hcl
    • azure/stag/southeastasia/chechia_net/kubernetes/terragrunt.hcl
    • azure/prod/southeastasia/chechia_net/kubernetes/terragrunt.hcl
  • 不同环境使用相同 module 产生,可以掺生多个环境的 infrastructure
    • 有测试的 dev, stag 之後才会上到 prod
    • 降低多环境维运的常见问题:dev 会动但是 prod 不会动
    • 将低不同环境的维护成本

自干的 AKS module

  • 一组 vpn subnets,将 node group 放在 vpn subnet 上
    • foundation/compute_network 已经把 vpn subnets 产生出来了
      • 使用 terragrunt dependency 来产生两个 root module 的依赖
      • 将 network 中的 output 作为 kubernetes cluster 的 input 传入
  • 一个 aks cluster
    • AKS cluster 是代管的 control panel,费用为 $0.1 / hr
    • 一个 default on-demand node group,创建时必须产生
    • (Optional) 一个 on-demand node group
    • (Optional) 一个 spot node group

Init, Plan & Apply

看过内容,变来实际跑看看

  • 好习惯不怕提醒:apply 前仔细看,apply 下去就都要收费了XD
cd  azure/dev/southeastasia/chechia_net/kubernetes

terragrunt init

terragrunt plan

terragrunt apply

apply 时间较长

  • aks kubernetes control panel 的创建时间约为 2-3 mins
  • aks node group 的创建时间约为 2-3 mins
  • 由於 node group depends on control panel,所以无法平行创造,整体花费时间会拉长

access ake with kubectl

不熟悉 AKS / Kubernetes 的朋友可以搭配azure official doc: Create a Kubernetes cluster with Azure Kubernetes Service using Terraform

安装 kubectl

  • terraform module apply 同时已经将 aks kubeconfig 写在 ~/.kube/azure-aks 路径
  • 设定 kubeconfig 路径~/.kube/azure-aks
  • 检查一下 kubeconfig 内容
  • 使用 kubectl access k8s
cat ~/.kube/azure-aks

KUBECONFIG_OUTPUT_PATH="/Users/che-chia/.kube/azure-aks"

kubectl --kubeconfig ${KUBECONFIG_OUTPUT_PATH} cluster-info

kubectl --kubeconfig ${KUBECONFIG_OUTPUT_PATH} get node

NAME                              STATUS   ROLES   AGE    VERSION
aks-default-44401806-vmss000000   Ready    agent   9m4s   v1.20.7

可以使用 kubectl 控制 cluster 就成功了

Module Known Issues

这个自干的 AKS module 有着以下问题

  • variable type(any) 这个蛮糟的XD
  • tfsec security issues

自干的 module 通常会有比较多问题,所以安全性的扫描工具(ex. tfsec)是十分必要的

或是就不要自干,使用社群维护的 module 版本

Alternative: AKS Example

实务上,除了自己写 module 外使用,也可以直接使用开源的 module

以上面的 AKS 范例,可以使用 azurerm AKS module

使用开源的 module,有几个条件

  • 作者/团队是有名的,或是在 terraform registry 官方认证的
    • module 更安全,更新更稳定,bug 少
  • 务必挑选经常更新的 module 使用
    • 如果是没在维护的 module ,使用後才会发现没有更新,最後还是要自己刻一版
  • 仍然需要看完完整 module 内容
    • 没看懂内容就 apply 到云端上蛮危险的。除了恶意的 module 内容,也有可能搞错原本设计的用途,导致误用

建议常见的 resource 与泛用性高的基本架构可以使用社群

专门为公司服务打造的上层 infrastructure,可以自干,放在私有 repository,并自己维护

  • 例如我的 https://chechia.net
    • 可能有 network Vnet,後端 AKS,资料库 DB,前端 VM scaleSets (Scaling Group),firewall rules,....
    • 将这些东西打包成上层 terraform module,方便管理,传递 module 间的参数,也建立彼此的依赖关系
    • 底下则是调用社群维护的 module,只要固定维护升级 module 就好

Open Source modules

合适的开源 module,除了 google terraform module aks 以外,可以到以下地方寻找

public cloud provider 都有出自家的 module,方便用户使用

Cleanup

destroy 整座 cluster

Homework

  • 继续尝试 azure/modules/kubernetes_cluster
    • 新增 spot node group
  • 使用 azurerm AKS module 部署 AKS
    • 阅读 README.md 以及范例
    • 调整 inputs
    • plan, apply 创建 AKS
    • 比较使用 azurerm 维护的 module,与讲者随手做的 module
  • 增加 firewall rule
    • 限制可以存取 master 的 CIDR

Summary

本章节主要是代大家走过一次实务的开发流程

  • 查 cloud provider 文件
  • 查 terraform resource 文件
  • init, plan, apply, test, fix 然後不断迭代改进
  • 可以善用社群维护的 module
  • 务必使用安全性扫描工具

<<:  第 2 集:认识 Bootstrap 5 世界

>>:  单位的责任分级

全端入门Day23_後端程序撰写之多一点的Node.js

昨天写了写了基本的Node.js,但还没有介绍程序码,今天就来介绍昨天的程序码。 Node.js入门...

设定档格式 YAML

YAML YAML的诞生不算太晚, 1.0在2004就出了, 虽然晚了JSON 5年(1999年),...

Day 22 - Spring Boot & Interceptor

Interceptor 拦截器 在许多的Java Web 框架都有实现Interceptor 的方法...

[常见的自然语言处理技术] 文本相似度(II): Cosine Similarity

前言 昨天我们使用了 Python 自然语言处理套件 spaCy 预训练好的 word embedd...

VPC(二)

VPC使用 昨天提到了关於VPC是什麽?以及如何简单的建立VPC XPN等的内容,那今天就来说说关於...