我们对于云上资源的部署,部分工作是通过控制台选择特定资源规格参数进行创建,还有一部分是使用 CLI或者 SDK 直接调用接口封装成定制化的平台来创建资源。但是随着企业数字化转型的加速,公司业务上云规模的持续增长和云资源的不断更新,同时又为了满足跨云基建的快速交付和容灾能力建设需求。我们也不可避免遇到行业内频繁提出的以下问题:
总之在业务多云环境成为常态的当下,为了能更好地享受云计算带来的弹性扩展、按需付费、高可用性等优势,实现跨云跨地域基础设施的一键交付,加强云上容灾能力,寻求更为合理的基础设施交付手段成为我们迫切需要解决的问题。
IaC
Terraform
Terraform的优势
Git模版管理: 开发者将模版代码推送到代码仓库,形成tag或者commit版本控制。
BPM审批流: 完成对于审批后,由bpm调用回调接口触发资源交付任务。
Terraform封装: 交付异步任务触发调用Terraform,执行基础设施的创建或更新操作。
消息通知: 企微机器人通知。
基础设施交付主要分为5个部分组成:
1. 技术选型
在平台建设的调研期间,我们也考虑使用社区目前普遍推荐的与gitlab结合来触发terraform的编排任务,并且在demo中也是以这种方式作为测试基础。但是因为以下的几点考虑,我们并没有结合gitlab或者Jenkins,而是自建了一个更加轻量化和定制化的任务执行流水线。
2. 模版存储
实际开发中,我们并没有完全舍弃gitlab,仍然还是将terraform模版代码文件存放在gitlab中,让gitlab帮我们管理模版版本的追踪进行模版存储。在模版存储上,我们使用master分支作为可使用模版文件分支,而其他的分支作为模版开发和测试分支,仓库中以云商code(如aliyun、huaweicloud等)作为云商模版的集合,当我们在平台选用模版文件时,结合gitlab api来调用master分支下aliyun的子文件夹名称来进行模版的选择。
实际代码仓库代码文件结构如下:
在平台上我们可以动态选择到需要的模版文件:
3. 执行流程
资源编排是作为某个业务项目下具体环境分组的资源交付任务执行的集合,也是我们对terraform进行封装集成的关键,在执行一次资源编排任务之前,我们需要先在项目环境分组下创建一个资源编排。
在资源编排创建之后,根据terraform采用声明式配置方式,我们针对资源编排,根据实际业务的需要,进行参数的填充和更新。下面是一个新建虚拟交换机的场景tf模版代码,其中availability_zone
作为交换机的可用区参数。
// variable声明的是参数类型声明
// availability_zone是参数名称
variable "availability_zone" {
description = "虚拟交换机的可用区参数."
type = list(string)
default = []
}
// resource描述的是我们想要得到的基础资源声明
// alicloud_vswitch是具体的资源类型
// vswitches是资源的描述
// zone_id是指创建的虚拟交换机所在的可用区
// var.availability_zone 我们可以通过这种方式使用上面定义好的参数`availability_zone`
resource "alicloud_vswitch" "vswitches" {
for_each = toset([for idx in range(length(var.vswitch_cidrs)) : tostring(idx)])
vpc_id = alicloud_vpc.vpc.id
cidr_block = element(var.vswitch_cidrs, tonumber(each.key))
zone_id = var.availability_zone[tonumber(each.key) % length(var.availability_zone)]
vswitch_name = format("%s%02d", var.vswitch_name_prefix, tonumber(each.key) + 1)
tags = var.tags
}
在平台上可以修改任务的availability_zone
参数来控制最终交换机所处的可用区信息。
最终平台会将参数组合形成一个标准json。
{
"availability_zone": [
"cn-hongkong-b",
"cn-hongkong-c",
"cn-hongkong-d"
]
}
在命令组合的类方法里,组合好的标准参数json会被拼接到terraform的执行命令中,供后续任务触发后进行调用。
class TerraformCommandManager(object):
def __init__(self, terraform_bin=None):
self.terraform_bin = terraform_bin or '/usr/local/bin/terraform'
def init(self, *args):
return [self.terraform_bin, 'init', '-no-color', '-reconfigure'] + list(args)
def plan(self, *args):
return [self.terraform_bin, 'plan', '-no-color'] + list(args)
def apply(self, *args):
return [self.terraform_bin, 'apply', '-auto-approve', '-no-color'] + list(args)
资源编排任务的流程如下:
4. 页面展示
4.1 任务详情页面
展示资源编排任务的各节点执行详情及耗时,并且展示本次任务变更涉及的资源数量。
4.2资源详情页面
当任务执行成功后,点击资源管理,跳转到资源详情页面,可查看本次变更在云上产生的资源详情列表,并展示了各类型数量,方便校验云上资源的数量。
安全配置: 使用合适的方法来管理密码和密钥保护敏感信息。
测试和验证: 所有的资源都会以最终的参数作为目标,在正式部署之前,要进行充分的测试和验证,确保参数的准确性,同时模版在正式使用之前也要做相应的测试和验证。
当我们对云上资源制定了较为完整的标准,结合terraform的编排能力,可以轻松做到在10几分钟内,跨多个云和可用区部署完全相同的海量基础设施服务,会对我们的云上容灾能力建设有很大帮助。
Nanliao,现任后端研发专家
青州,现任前端研发专家