试着构建数据利用基础设施-第12部分(使用Terraform的技巧)
首先
你好,我是NTT数据先进技术的白木。
本文是关于创建数据利用基础设施的系列文章的第12篇(Terraform的技巧)。
关于本系列的工作内容,请参阅第1篇(配置场景)。
之前的文章,请参阅创建数据利用基础设施第11篇(建设和数据利用 – Athena)。
这次,我将描述关于使用Terraform进行AWS构建的技巧等。
目录
-
- 前段
-
- Tips
-
- 詰まった点
- 最後に
前段时间

-
- 環境
Terraform: v1.5.2
aws provider: v5.5.0
TerraformによるAWSのインフラ構築
バックエンドはリモートステート先としてS3バケット、排他制御としてDynamoDBを東京リージョンに作成済み
Remote Backendや環境構築については、前章の~~で記載。
提示
我将通过这个项目介绍一些使用Terraform的技巧。
关于目录结构的问题
参考了这篇文章,初始实现的目录结构方案如下:
最顶级的是按服务配置的模块 (modules),以及按每个环境配置的环境文件 (environments) 分别进行管理,这是一种常见的结构划分。
-- TechLearning/
-- environments/
-- prd/
-- main.tf
-- backend.tf
-- variables.tf
-- provider.tf
-- README.md
-- outputs.tf
-- modules/
-- iam-admin/
-- main.tf
-- variables.tf
-- outputs.tf
-- README.md
-- iam-analytics/
-- main.tf
-- variables.tf
-- outputs.tf
-- README.md
-- ....
然而,在推进实施的过程中,上述的结构方案考虑了可扩展性,对于Terraform初学者来说难度较高。另外,由于工作量无法承担,我们选择了下述结构方案,而牺牲了扩展性。
-- TechLearning/
-- backend.tf
-- iam-admin.tf
-- iam-analyst.tf
-- iam-securityservice.tf
-- iam-service-role.tf
-- jobs.tf
-- provider.tf
-- README.md
-- security.tf
-- storage.tf
由于没有考虑到可重用性和可扩展性,我们能够以更快的速度进行开发。 然而,对于那些没有参与这个项目的人来说,阅读代码并理解其结构变得困难。 对此我深感反省。 如果有下一次,我希望能够添加更多功能,并对代码进行重构,恢复最初的目录结构。
计划执行后,申请出现问题。
我经常遇到这样的情况:即使执行了terraform plan并且计划执行结果为success,但apply却不能成功。实际上,什么是terraform plan呢?
在执行terraform时,可以使用模拟资源的命令来模拟实际在云上构建的资源。根据.tf文件中的信息,可以参考哪些资源将被创建/修改/删除。
https://blog.mmmcorp.co.jp/2022/10/31/terraform-apply-safely/
根据情况我得知,因此在执行terraform apply之前确认terraform plan的结果是有效的。然而,这是一个陷阱。虽然我曾以为如果plan成功,则apply一定成功,但事实并非如此,apply常常会失败。
这也是情理之中,因为terraform plan本来就是用来展示变更的预测,无法保证这些变更能够成功执行。
terraform plan命令仅仅是根据编写的代码预测将要进行的变更,并不保证最终这些变更会成功执行。
因为误以为这是错误的,所以一开始花了很多时间解决错误,尽管Terraform的语法实际上是正确的。这可能是初学者容易陷入的陷阱。
这次在解决这个错误时,我们已经通过自己的力量进行了确认,但是如果使用tflint,似乎可以在执行plan后解决一定程度上的”apply失败”的情况。
下次我想尝试使用tflint。
计划、申请无法执行。
以一种简单的方式执行Terrafom plan/apply会导致错误。
错误内容显示为状态锁定。
╷
│ Error: Error acquiring the state lock
│
│ Error message: resource temporarily unavailable
│ Lock Info:
│ ID:
│ ...
看起来在访问state文件时被锁定,并且出现错误。
原因可能是在执行命令之前中断了先前执行的apply命令。(在检查代码时发现了需要进行其他修正,因此停止了执行。)
在执行apply或plan时会锁定state,并在执行完成后解锁,但由于中断导致它处于锁定状态。
解决方法很简单,只需解锁即可执行命令。{LOCK_ID}是出现在错误消息中的ID值。
$ terraform force-unlock {LOCK_ID}
如果执行这条命令,成功解锁并且可以执行命令了。
虽然无意间中断了一下,但除非有不得已的情况,最好不要中断。
关于Terraform Cloud
尽管在前一章中已经提到过,但这次我们选择了使用Remote Backend而不是Terrafom Cloud来管理Terrafom的状态。我们选择不使用Terrafom Cloud的原因是,首先作为一个SaaS服务,使用该服务需要耗费大量时间来获得内部批准。其次,考虑到只有Terrafom的初学者在团队中,使用新的服务会增加难度。为了下次的准备,我们计划在事前学习中介绍Terrafom Cloud的优势以及它能够做什么。
Terraform Cloud是什么?
Terraform Cloud是一个为团队共同使用Terraform而提供访问控制和模块共享的私有存储库的服务。
-
- 機能
Stateファイルの管理
デプロイパイプライン
ガバナンス機能
アクセスコントロール・ポリシー設定・監査ログ等
Private Registry
moduleやproviderを組織内に公開
参考)可以查看以下链接以了解有关Terraform tfstate管理以及TFC的更多信息:https://dev.classmethod.jp/articles/terraform_tfstate_management_tfc/
Terraform Cloud的优点
如上所述,首先是能够进行状态管理。在这个项目中,我们使用S3和DynamoDB进行状态管理。但是如果使用Terrafom Cloud,您不需要额外准备云资源,即可进行管理。
下一个要说的是可以在 GUI 上查看 State 文件的更改历史。可以类比为 Git 的提交历史,可以轻松地查看谁在什么时候做了什么样的更改。
此外,我认为还有一个很好的地方是可以创建部署流程。如果在GitHub上管理着Terraform的代码,当将代码合并到主分支等操作时,它会作为事件在Terrafom Cloud上自动执行terrafom plan和apply操作。即使不使用GitHub Actions等方式编写yaml文件,只需在Terraform Cloud上设置相关分支参数,它也会自动执行。参考)https://qiita.com/boccham/items/190f04bfbc9ffc0b5baf
我认为除了这些之外,还有很多其他优点,但我只介绍了代表性的一些。
下次我一定要尝试使用Terraform Cloud来管理Terraform。
与CloudFormation进行比较
在我们的团队中有一个成员曾经在以前的项目中使用CloudFormation,所以我考虑了一下Terraform和CloudFormation之间的差异。
多云支持
我认为Terraform的一个很大的优点是它支持多云平台。
CloudFormation是一个AWS服务,因此创建的资源会限定在AWS上。
而Terraform则通过切换Provider,可以适用于AWS、Azure、GCP以及OCI等多个主流云平台。
参考链接:Terraform 提供者列表
https://registry.terraform.io/browse/providers
然而,为AWS创建的Terraform代码(即将提供程序设置为AWS的代码)将成为AWS特定的资产,不能简单地在其他云服务上重用。
通过编写代码实际进行验证很明显,例如,在为AWS创建EC2实例时,资源名称为”aws_instance”;而在为OCI创建Compute实例时,资源名称为”oci_core_instance”,且所需参数也不同。
因此,基本上很难在多云环境下重新利用资产,相比而言,共享Terraform的语法、命令、各种技巧等知识才是更有优势的选择。
直到利用为止的步骤
CloudFormation是AWS的一项服务,只需访问管理控制台即可轻松使用。
此外,辅助服务如CloudFormation Designer等每天都在进行更新,因此对于初次接触基础架构即代码(IaC)来说,门槛相对较低。
然而,在使用Terraform之前,需要进行一些步骤,如设置本地环境和构建用于后端的S3存储桶。
※请参阅本系列文章的构建部分以获取详细信息。
因此,从初学者开始使用的角度来看,目前来说,CloudFormation似乎更具优势。
然而,由于本次项目的原因,我们没有使用Terraform Cloud。如果使用基于SaaS的Terraform Cloud,则可能有不同的评估。
多人共同使用时需注意事项
在CloudFormation中,有一个叫做“stack(堆栈)”的概念,基本上可以通过一个(甚至可以通过嵌套功能和模块功能使用多个)模板来创建的资源进行堆栈单位的管理。
如果团队使用CloudFormation进行构建,那么在管理控制台上管理堆栈会给人一种非常灵活的印象。
特别是在模板和堆栈有不同责任人的情况下,这将发挥其效果。
例如,在NW负责人修改NW相关模板时,只需更新与NW相关的堆栈,而无需考虑其他模板或堆栈,并且该负责人在操作时无需意识到其他模板或堆栈。(当然,前提是没有与其他堆栈存在依赖关系。)
相比之下,在Terraform中,使用相同后端的tf文件都被包含在管理范围内,因此即使只想更新其中一个tf文件,也需要准备所有tf文件的最新版本进行操作。
也就是说,当存在多个责任人进行分工的情况下,由于需要其他责任人的最新资源,因此防止更新时出现降级情况变得重要起来。
这对于通常管理代码的人可能是理所当然的,但是对于主要使用AWS管理控制台手动构建基础架构的人来说,需要注意工作分工和代码管理机制。
※为了避免上述问题,我们曾经考虑将后端根据责任人分开,但是由于没有找到使用这种方法进行开发的案例,所以没有采用。如果有相关经验的人,请留下评论,谢谢。
关于语法
CloudFormation是使用json/yaml编写,而Terraform使用一种名为HCL(Hashicorp Configuration Language)的类似于Json语法的自定义语言进行编写。
我认为哪一个更难/更易读完全是个人差异的问题,所以避免给出优劣评价。
如果项目成员在其中一种语言中有很强的熟悉度,那么将其作为评估的标准是好的,但如果没有的话,我认为对于初学者来说学习的难度没有太大差异。
最后
這是本系列的最後一篇文章。非常感謝您的閱讀,直到最後!我整理了初學者在使用Terraform建立基礎架構時的一些技巧。如果本文能對您有所幫助,我將非常高興。如果有任何錯誤,請隨意留言~~