Infrastructure as Code 一个看似很悬乎的单词,从去年开始接触云「用云真的蛮好的,IDC谁爱折腾谁折腾吧」,到今年慢慢的熟悉了世界两大云厂商,发起其实用云了对于运维、基础设施工程师要求更高了,我们不在是一个安装服务的人、我们不在是一个做完监控到此为止的人、我们不在是你用就好了的人,我们需要去理解为什么云要这样做,为什么业务会这个德行,为什么其实没有我们这帮人也是可以的,不就点点点么开个虚机、开个数据库、来个EMR集群、k8s集群不是玩一样的吗,甚至于CICD云都可以帮你干了,还要我们干啥「其实我现在依然觉得迟早会给淘汰」。
好了好了,有危机感就行了,做正确的事情,尽量多学、多看点就好了,不争不抢,保持同理心,保持克制「我是一个脾气不好人,很羡慕佛系的人」,勤能补拙,还有一定要保持一颗好奇心,这个真的很重要。
回归正题 Infrastructure as Code & Programmable Infrastructure 是啥,其实可以通俗的理解成,云上各种资源从网络到机器均是一段代码,这边又不得不提到 HashiCorp 这家牛到不行的公司「有种都是他们在定规则的感觉」,引入两个工具,Packer 管理云上虚机镜像的,右边 Terraform 管理所有资源的。
自动化不是什么新鲜的东西,开始上班就是天天想着一条命令甚至于自动触发,躺着喝咖啡,Ansiable PlayBook 其实也也是一种基础设施及代码只是它其实是没有状态的,但是 HashiCorp 这家公司的东西其实均是有状态的物件,我们所有的操作最终 push 到生产均是会产生变更的,所有 Review 变更相当重要,这边自认而然的引入 Git 是不是就很完美了,是不是有种 Git Ops的感觉,如果有就对了,万物皆代码统统进 Git 「版本管理、操作 Review」。
好处是啥
除了让配置管理高效可复用之外,基础设施即代码还带来了其他好处。首先,脚本本质上都可以作为应用基础设施的文档。这个附带的好处很有用。因为你已经投入时间和精力把脚本写好了,那么把它当成基础设施的网络关系图来看其实也挺好。有人可能并不满足于此,还会基于脚本生成外行都能看懂的内容、图表和文档。其次,因为一切肇始于脚本,那么所有部署都将源于同一个文件。自然地,每个部署都将具备相同的基础设施特性。这只是理论上,实践中我发现很多机构会在已有基础设施上运行脚本,或者在脚本自动运行后再手工修改配置文件,导致脚本丧失了作为追溯依据的价值。另外,脚本还是基础设施中立的。只要把脚本写好,就可以在任何云上运行,公有、私有、混合,都没问题。等到软件定义网络即SDN统治了全世界的路由器,现在90%的中立就会变成100%中立。这种中立性对云用户至关重要,可以避免被某家供应商锁定,也可以在多个云中运行以增加冗余。不仅如此,不同的用例还可以运行在特定的云上。比如,有一个用于集成测试的云,还有一个产品开发云,还有一个beta版本云,它们都相对独立。但由于脚本可复用,部署就不仅仅是复制资源和可运行代码了。部署还包含了基础设施。这样每一次部署,都会有一套新的基础设施和一套代码。这样就避免了交叉污染。QA就不必再回答“在我的电脑上可以运行”之类的问题了。增加了新功能的测试套件可以在全新的基础设施中运行。而在出现问题时,也能够取得部署、代码和基础设施的完整快照。与以往模糊的快照和对错误的文字描述相比,简单天壤之别。更吸引人的是,大多数公有云都提供有限或全功能的REST API,支持用户对自己的云进行编程。这样在把代码从Github下载到前端和数据库服务器之前,我只要向自己的产品云发送一个REST请求就可以启动它们。
面临的挑战
尽可能控制在 Infrastructure Engineer 手上,并非面向所有研发,如果面向所有必将带来混乱的目录结构,混乱的变量定义,轮乱的。。。
目录结构、资源引用如要做好是要花费大量的精力和毅力下去的,这件事情我的理解是如果认定的就需要持续坚持的一件事情,也很有意义的一件事情「难是不难,就是很烦躁在初期的时候,学习曲线很陡峭」。
各种 Providers 的熟悉,引用下官方介绍
Terraform is used to create, manage, and update infrastructure resources such as physical machines, VMs, network switches, containers, and more. Almost any infrastructure type can be represented as a resource in Terraform.
A provider is responsible for understanding API interactions and exposing resources. Providers generally are an IaaS (e.g. AWS, GCP, Microsoft Azure, OpenStack), PaaS (e.g. Heroku), or SaaS services (e.g. Terraform Enterprise, DNSimple, CloudFlare).
优势明显
- 容易重现的系统。能够毫不费力且可靠地重建基础设施中的任何元素。
- 可任意处理系统。可以轻松创建、销毁、替换、更改以及移动资源。
- 一致的系统。假设两个基础设施元素提供相似的服务,比如同一个集群中有
- 两个应用程序服务器。这些服务器应该几乎完全相同。它们的系统软件和配
- 置应该是一样的,除了一丁点配置(比如IP地址)用于区分彼此。
- 可重复的过程。基于可再生原则,对基础设施执行的任何行为都是可以重复的。也就是说Duang了之后,对于所有人的效果应该是一样的。
变化的设计。确保系统能够安全地改变,迅速的频繁做出变化。
最后贴上一段漂亮的代码,这个就是数据库,受得了吗 。。。
# Aws
resource "aws_db_instance" "default" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "foo"
password = "foobarbaz"
parameter_group_name = "default.mysql5.7"
}
# alicloud
variable "name" {
default = "dbInstanceconfig"
}
variable "creation" {
default = "Rds"
}
data "alicloud_zones" "default" {
available_resource_creation = "${var.creation}"
}
resource "alicloud_vpc" "default" {
name = "${var.name}"
cidr_block = "172.16.0.0/16"
}
resource "alicloud_vswitch" "default" {
vpc_id = "${alicloud_vpc.default.id}"
cidr_block = "172.16.0.0/24"
availability_zone = "${data.alicloud_zones.default.zones.0.id}"
name = "${var.name}"
}
resource "alicloud_db_instance" "default" {
engine = "MySQL"
engine_version = "5.6"
instance_type = "rds.mysql.s2.large"
instance_storage = "30"
instance_charge_type = "Postpaid"
instance_name = "${var.name}"
vswitch_id = "${alicloud_vswitch.default.id}"
monitoring_period = "60"
}