开源的自动化配置工具 —— Terraform 实践分享

百家 作者:QingCloud 2018-02-23 09:47:31



Terraform 是一个安全、高效地部署、更改、版本化基础设施和应用程序的工具,可以用来管理多层次的资源。从上层的软件配置到底层的网络、系统配置都可以使用 Terraform 统一进行管理。


关于 Terraform 的特性、配置、及应用场景,年前青小云已经和大家分享过了,这里就不再赘述。今天青小云整理了一些与大家沟通过程中遇到的疑问以及 Terraform 在生产、研发环境中的一些经验总结,希望对大家有所帮助。


 问:什么是 IaC(Infrastructure as Code),与 DevOps 之间的关系是什么?


:IaC 是通过机器可读的定义文件而不是物理硬件配置或交互式配置工具来管理和配置计算机数据中心的过程。这些配置可以放在版本控制系统当中,它既可以使用脚本也可以使用声明式定义,不过现在比较推荐的是声明式的定义。


IaC 是实现 DevOps 最佳实践的关键属性——开发人员更多地参与定义配置,并在开发过程中更早涉足 Ops 团队。


利用 IaC 的工具可以看到服务器的状态和配置,并最终为企业内部的用户提供可视性,旨在将团队聚合在一起,以最大限度地发挥他们的努力。自动化旨在消除手动过程中的混乱和容易出错的方面,并使其更加高效,允许更灵活地创建更好的软件和应用程序,减少停机时间,并为公司提供总体成本效益的方法。基础设施自动化工具通常包含在 DevOps 工具链的组件中。


 问:如果一个公司采用基础设施即代码的方式的话,他有没有碰到什么陷阱的风险?


: 很多基础设施团队都使用了云和自动化技术,却没有使用自动化测试和发布流程,而仅仅是把这种自动化技术当做一种脚本语言来使用。他们同样也会对每次改动编写手册、配置文件和脚本,再针对一部分服务器手工运行他们,也就是说每次改动还是需要大量的人为干预。


这种工作方式意味着基础设施团队还是没有把自己从重复性的劳动中解放出来,他们需要做变更时也没有减少破坏系统的风险,也没能对他们的用户产生帮助。所以还是需要自动化能自动化的一切,并且使用完整的上线流程保证脚本的正确性。


比较推荐的方法是,在脚本使用之前使用 Terraform plan 进行执行情况的预览,但是有些情况下虽然 plan 是正常的,但是还是没有办法正常的执行,所以在实际应用当中应该先进行测试。


一般来讲基础设施产生错误造成的损失往往是巨大的。在上线之前也需要进行 code review,在完成了这些步骤之后可以说这些代码基本是 100% 可靠的。并且尽量要保证每一步只做一小部分修改,这样比较方便找到脚本的问题,也方便同事进行 review.


 问:Terraform 是如何存储状态的,在我的团队当中应该如何去管理这些状态?


: 此状态默认存储在名为“Terraform.tfstate”的本地文件中,但也可以远程存储,远程存储可能会更利于团队协作。Terraform 存储的状态文件是 JSON 格式的,但不鼓励对其进行文本编辑。Terraform 提供了 Terraform state 命令对其状态的修改,不过大部分情况下是使用不到的。


对于单个脚本进行管理多个环境的情况 Terraform 提供了 workspace 功能。使用 workspace 可以利用简单的判断语句来修改部分变量的值:

如果只是小型可以利用版本管理工具来进行状态的存储,不过使用这种方法有一定的缺点,例如状态文件中可能包含一些账号密码等信息,有人同时对基础设施进行操作时会造成一定的冲突。


更推荐的方法是使用 remote state 进行状态的管理,Terraform 的状态管理支持多种存储形式如 S3、Consul 等,部分的存储可以支持状态锁以保证只有一个人在执行 Terraform apply.


 问:如何将 Terraform 集成到我的项目当中?Terraform 有没有提供相关的 API?


: 为了方便从代码中调用 Terraform,可以使用 JSON 形式的配置文件,这样可以简化生成配置文件的步骤。


当然也可以使用 Terraform 作为库进行编程,Terraform 是一个遵循 MPL2.0 的开源软件,所以不用对版权问题担心。不过使用 Terraform 作为库进行开发,官方并不保证他的稳定性。并且 Terraform 的初始化过程相对来说也较为复杂。


 问:在使用 Terraform 的情况下,如何在不停机的情况下进行服务的升级?


答: 在 Terraform 的资源配置当中包含几个字段可以帮助实现这个功能例如 lifecycle 当中的 create_before_destory,该标志可以保证在原实例销毁之前就创建资源进行替换。例如在删除旧负载均衡器后端的时候可以使用他来创建好后端。


对于有状态的服务,我们通常使用挂载的硬盘进行状态的存储,可以使用 lifecycle 当中的 prevent_destroy 保证 volume 不会被操作失误删除,然后将硬盘挂载到新启动的实例上。


 :如何对生产、开发等环境的Terraform脚本进行管理 ?


: Terraform 提供了 workspace 功能可以让用户对单个配置目录生成多个不同的基础架构资源。默认情况下我们使用的都是名为 default 的工作区,使用 Terraform workspace 子命令可以进行 workspace 的相关操作。


在具体的配置文件当中我们可以使用 ${Terraform.workspace} 取出变量的值,然后进行简单的判断来修改部分变量的值。

workspace 是用来管理开发生产之间微小差异的方法,但并不是唯一的隔离机制。


随着 Terraform 配置文件的增大,使用 remote_state 进行状态的管理是一个比较推荐的方法。 Terraform 同样也支持 workspace 机制可以视情况使用。


在 Terraform 的开源社区当中已经明确提出在后续版本当中会加强 workspace 相关的功能,可以将 workspace 与版本管理工具的分支进行关联。


 问:Terraform 如何和配置管理工具比如 Ansible, Puppet 集成?


: Terraform 本身支持 output 变量,可以把创建基础设施后想要保存的变量进行 output, 再进行适当的处理输出到配置管理工具当中。


不过更推荐的方法是使用 Terraform-inventory 将 Terraform 的 state 文件直接转换为 ansible 的 Inventory 文件,然后利用 Inventory 进行 ansible 脚本的使用。


下面是一个开源的项目可以非常方便的 Terraform 的 state 文件转换为 Inventory 文件,


https://github.com/adammck/Terraform-inventory


同样 Terraform 有使用 Provisioners 进行帮助初始化机器,其中支持了多种 Provisioners,如 chef、remote_exec 等也可以帮助用户进行配置管理。


 问:如何将多个 Terraform 项目进行关联?


: 随着 Terraform 的配置变大,将一个大型的配置文件拆分为多个配置可能会更安全更易用。可以利用 Terraform 的 data resource 读取其他项目当中的配置。

并且利用 remote_state 可以将状态设置为 read-only 可以保证最为基础的设施不会被各个团队都能进行修改。


- FIN -


关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接