基础设施代码化（IaC）的自动化配置与编排
本文将基于基础设施即代码 IaC 理念，分享如何借助自动化编排工具实现自动化部署，使得运上运维工作更为高效。
IaC
本文将基于基础设施即代码 IaC 理念，分享如何借助自动化编排工具实现自动化部署，使得运上运维工作更为高效。
![](/data/attachment/album/202103/04/154721w8ziqi8ztsiuyv8t.jpg)


云上运维，那就是和云上资源和产品打交道，无疑会涉及到一系列的资源部署。比如简单地使用一台云服务器，就需要运维人员依次创建 VPC、VSwitch、安全组和云服务器实例，如果想创建一个集群，那还要进一步创建负载均衡、数据库和多个云服务器实例。


随着业务规模的不断扩大，IT系统和环境日益复杂，人工一个一个创建资源的方式显然不可取，许多人正在转向自动化资源部署和配置的工具。


本文将基于基础设施即代码 IaC 理念，分享如何借助自动化编排工具实现自动化部署，使得运上运维工作更为高效。


### 手动/半手动云上运维的五大痛点


对于云上资源的部署，如果你的云上运维还处于手动或是半手动运维阶段，那么大部分工作是通过控制台选择特定资源规格参数进行创建，还有一部分是使用 CLI（如 aliyun-cli）或者 SDK 直接调用接口来创建资源。但随着企业的云上业务规模不断扩大，不论是哪种方式，或多或少都会遇到下述五个问题：


* **部署效率低。**手动创建对于创建少量种类的资源来说倒是种很直观的方式，但一旦涉及到大量不同资源时，尤其是资源之间还有依赖关系，这时候会发现需要在不同的产品控制台之间来回切换，还要时刻关注创建进度，才能再去创建下一个依赖它的资源，整个过程所耗费的时间和精力可想而知，相信不少人有深有体会。
* **可复制性差。**当手动创建好了一系列的资源后，如果需要针对不同的环境（如预发、测试和生产）或不同的地域（如北京和上海）创建完全相同的资源，则又需要花费很多时间一步步地进行操作，无法直接复制、做到一键部署。
* **一致性差。**手动创建还有一个非常大的问题，那就是非常容易出现配置错误，很难保证两套环境中各个资源配置是完全相同的。
* **管理困难。**资源的创建只是开始，可能还需要针对这批资源做扩缩容、更新特定资源的规格等操作。但手动运维的方式就导致没有统一管理这批资源的入口，仍需要分别到各产品控制台上操作。随着资源数越来越多，资源管理就愈发难以维护。
* **难以 DevOps。**每次开发、测试或部署软件应用程序时都可能需要手动部署基础设施，既无法对基础设施进行版本控制，也无法对其变动进行评审，更无法做到敏捷部署。


其实，我们都知道这些问题的背后是因为资源的部署还未做到自动化。但这些问题也不断促使着我们思考应该通过什么样的方式来解决这些痛点，才能让整个资源部署过程自动化。


### 引入基础设施即代码 IaC 理念，实现云上资源自动化部署


在真正做到自动化部署之前，不妨回头看看所需要创建的云服务资源（如 VPC、VSwitch、ECS 实例等），它们相对于Web服务等应用程序来说都是云上的基础设施，如果把这些基础设施想象成一段“代码”，在“代码”中定义产品、规格、数量等信息，那么是不是就可以通过这段“代码”来管理整个基础设施了呢？


**这就是<ruby> 基础设施即代码 <rp>  （ </rp> <rt>  Infrastructure as Code </rt> <rp>  ） </rp></ruby>（IaC）的理念，将基础设施配置视为软件编程。**Kief Morris 在《Infarftruce as Code》一书中对基础设施即代码是这么定义的：



> 
> “基础设施即代码是一种使用新的技术来构建和管理动态基础设施的方式。它把基础设施、工具和服务以及对基础设施的管理本身作为一个软件系统，采纳软件工程实践以结构化的安全的方式来管理对系统的变更。”
> 
> 
> 


引入 IaC 的理念，运维人员可以将基础设施的部署和管理过程变得敏捷：


* 在模板（宽泛意义上的代码）中定义基础设施，即各类云资源及其规格、数量等属性、云资源之间的依赖；
* 使用版本控制（如 Git）管理模板，并提交评审；
* 通过评审后由自动化部署工具使用模板来创建/更新基础设施；


基础设施的部署和管理变得便捷后，上述提到的手动运维/半手动运维的痛点问题就可以得到很好的解决：


* **提升部署效率。**使用自动化部署工具进行部署，相对于人工部署的效率将大大提升。
* **标准化和一致性。**将基础设施的内容通过模板的形式保存，对基础设施的变更由对模板的变更来实现，实现了基础设施管理的标准化。此外，使用相同的模板在不同地域部署，也能够保证资源的一致性。
* **易于管理。**对基础设施的管理不再分散于各个产品控制台，而统一到单个模板，使得管理成本大大降低。
* **敏捷化工作流程。**通过基础设施管理流程的规范化和标准化，资源部署的整个过程就变得敏捷。
* **审计和回滚。**对模板进行版本管理，使得对基础设施变动的审计和回退到某个特定版本成为了可能。


### 四个常见的 IaC 自动化配置与编排工具


当前，有很多 IaC 自动化部署工具，有第三方资源编排工具，也有云服务商提供的云原生的资源编排工具，这里介绍四个自动化配置与编排工具：


1. **阿里云资源编排服务 ROS**（Resource Orchestration Service），这是云原生编排工具，通过编写 JSON/YAML 格式的模板，在模板中定义所需的ECS实例、数据库实例等云服务资源以及资源依赖关系等，然后再根据模板在 ROS 中创建资源栈，ROS 服务端将根据模板自动完成所有资源的创建和配置，实现自动化部署及运维。而资源栈则管理着模板中定义的所有资源，并可通过新模板来更新资源栈，包括资源的新增、更新或删除等操作。
2. **AWS CloudFormation**，也是云原生的编排工具，运维人员也是通过 JSON/YAML 格式的模板定义云服务资源，通过资源栈管理这些资源。
3. **HashiCorp Terraform**，这是一个开源的自动化编排工具。以配置文件为驱动，可以在文件中定义所要管理的组件，即基础设施资源，以此生成一个可执行的计划，通过执行这个计划来完成所定义组件的创建，增量式的变更和持续的管理。如果不可执行，会提示报错。Terraform 不仅可以管理 IaaS 层的资源，如计算实例、网络实例和存储实例等，也可以管理更上层的服务，如DNS 域名和解析记录、SaaS 应用的功能等。
4. **Pulumi**，与 Terraform 一样也是开源项目，但它与 Terraform 的重要区别在于：可以用熟悉的编程语言来编写声明式配置，而不需要额外学习云服务商特定的模板语言来写配置。


对于自动化配置与编排工具的选择，笔者的建议是：


1. **如果你的业务部署在单一云平台，就选择云平台提供的资源编排工具，在阿里云平台就用 ROS、在 AWS 平台就用 CloudFormation，原因很简单：云平台提供的工具是云原生，是免费的托管服务，在服务端就可以执行自动化部署；同时，它还实现了云原生的访问控制、编排资源与实际资源差异检测等功能，用起来比较省心。**
2. **如果你的业务是部署在多个云平台，建议使用第三方的 Terraform 和 Pulumi，因为它不仅可以进行多云资源的部署和管理，还能管理除云以外的其他资源，如 Kubernetes。**


### 如何利用编排工具进行自动化部署和管理？


对于运维人员来说，使用 IaC 理念的自动化部署工具的门槛其实不高，使用步骤也非常简单，主要来说就是编写模板和使用模板。这里谈谈编写模板和使用模板有哪些注意事项，如何才能更好地利用工具、更好地提升运维效率。 


#### 1、编写模板的三个注意事项


确认好自动化部署工具，就可以根据不同工具的模板语言来编写对应的模板文件。如果你选择云服务商提供的云原生的编排工具， 编写模板这里，有三点注意事项想重点提醒一下：


1. **注意资源的依赖关系。**不恰当的依赖或少了依赖都会导致资源创建出错。
2. **注意使用通用属性作为参数。**比如实例规格等就是比较通用的属性，建议使用同一份模板，指定不同的参数来达到部署不同规格实例的目的。
3. **使用有价值的属性作为输出。**比如实例 ID、连接地址等内容就是有价值的属性，它们都是在资源创建完成后才能获取到，把这些属性作为整个模板的输出，可以方便后续的查看和管理。


#### 2、自动解析依赖关系，自动化部署基础设施


编写完模板后，就可以通过对应的自动化部署工具将模板转化为真正的资源。上述提到的编排工具都能解析资源的依赖关系，并能先后创建这些资源。同时，对于互不依赖的资源也能够并行创建。


* 对于阿里云 ROS 和 AWS CloudFormation 来说，可使用模板来创建一个资源栈。一个资源栈即一组云上资源，也就是在模板中定义的基础设施。后续当需要增/删/改一些资源时，也是通过使用模板来更新资源栈来达到目的。
* 对于 Terraform 来说，可使用配置文件生成一个可执行的计划，通过执行这个计划来完成所定义资源/组件的创建，增量式的变更和持续的管理。
* 对于 Pulumi 来说，则是直接执行代码来进行部署。


这样的部署方式既能使得资源能按照合理的顺序创建出来，又能够提升部署效率，在遇到异常情况时也会进行一定程度的重试，真正让整个自动化部署过程变得稳定和高效。


### 以基础设施代码化为基础，进一步高效运维


当运维工作完成整个基础设施模板化后，DevOps 就变得更加容易。我们可以使用版本管理工具（如 Git）管理描述当前基础设施的模板，使用阿里云云效/AWS CodePipline/Jenkins 创建一个从代码提交触发到人工卡点再到资源栈部署的流水线，这样整个基础设施的管理就会变得更加敏捷和自动化。


![](/data/attachment/album/202103/04/155137crx7xzls7nsnwrlr.png)


*图1： 基础设施变更的流程图*


1. 在每次变更模板后，将本地仓库的分支内容推送到远程仓库，并发起评审；
2. 若评审不通过，则修改模板后重新发起评审；若评审通过，则自动触发流水线；
3. 流水线触发人工卡点，通知上级管理员检查此次变更。若不同意，则终止；若同意，则进入下一个步骤；
4. 若是首次提交模板，则创建资源栈（即创建基础设施）；反之，则更新资源栈（即更新基础设施）。


#### 基础设施变更及预览


IT 基础设施并非一成不变，随着业务的变化，我们可能面临扩缩容场景，也可能面临整个架构的变化。好在基于 IaC 的理念，我们只需要描述基础设施最新配置，而不用担心如何进行变更。但即使如此，我们需要在变更前知道究竟会发生哪些变化。阿里云ROS 和 AWS CloudFormation 的更改集功能，Terraform 的执行计划均能让我们提前了解到变更内容。


例如，由于业务变化，在基于图1的架构基础上，在阿里云平台上新增一台 ECS 实例，并使用 SLB 实例为两台 ECS 实例做负载均衡。在编写好新的模板后，就可以使用更改集功能来感知变化，下图是 阿里云ROS 的一个变更示例：


![](/data/attachment/album/202103/04/155206l6mj4z7cli68qliz.png)


在确认无误后，便可以执行变更。随后，自动化编排工具便会对整个基础设施进行更新，根据模板发生的变化来决定新增、更改或删除哪些资源。


#### 基础设施偏差检测和纠正


尽管使用了自动化编排工具部署资源，仍可能有部分人员会通过非标准化的方式（比如通过控制台或 API）修改了基础设施中部分资源的属性，使得资源实际情况和模板中定义的资源产生了差异。好的自动化编排工具不仅具备检测基础设施实际属性和模板中定义的属性之间差异的能力；还能基于差异结果纠正模板或实际资源，使得模板和基础设施保持一致。


当前，通过 阿里云 ROS 和 AWS CloudFormation 的偏差检测能力，就可以轻松地发现实际资源和模板中定义的资源之间的差异，并可通过偏差纠正功能使模板内容和实际资源保持一致。


### 总结


在 IT 基础设施全面上云的趋势下，云上手工运维的方式已难以为继，出现了部署效率低、可复制性差、一致性差、管理困难、难以 DevOps 等痛点。阿里云 ROS/AWS CloudFormation/Terraform/Pulumi 等自动化编排工具都是基于基础设施即代码（IaC）的理念，可以通过模板来定义基础设施，同时标准化和自动化整个部署过程，配合更改集、偏差检测等能力，再结合流水线，真正实现了 IT 基础设施管理的 DevOps。建议运维人员可以重点关注和巧用工具，将帮助你更好的提升运维效率，解放生产力。




---


作者介绍：


王斌鑫，从事阿里云弹性计算资源编排工具的研发工作，热爱开源和写作。阿里云凌云时刻出品人、PyCon China出品人。 


 

