试着构建数据利用基础设施-第12部分(使用Terraform的技巧)

首先

你好,我是NTT数据先进技术的白木。
本文是关于创建数据利用基础设施的系列文章的第12篇(Terraform的技巧)。
关于本系列的工作内容,请参阅第1篇(配置场景)。
之前的文章,请参阅创建数据利用基础设施第11篇(建设和数据利用 – Athena)。
这次,我将描述关于使用Terraform进行AWS构建的技巧等。

目录

    • 前段

 

    • Tips

 

    • 詰まった点

 

    最後に

前段时间

image.png
    • 環境

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管理控制台手动构建基础架构的人来说,需要注意工作分工和代码管理机制。
※为了避免上述问题,我们曾经考虑将后端根据责任人分开,但是由于没有找到使用这种方法进行开发的案例,所以没有采用。如果有相关经验的人,请留下评论,谢谢。

另外,如果进一步发展并实现了git和CI/CD,无论是使用CloudFormation还是Terraform,在这些方面的差异都将减少。由于本次没有准备这样的开发环境,所以在此基础上进行了描述。

关于语法

CloudFormation是使用json/yaml编写,而Terraform使用一种名为HCL(Hashicorp Configuration Language)的类似于Json语法的自定义语言进行编写。
我认为哪一个更难/更易读完全是个人差异的问题,所以避免给出优劣评价。
如果项目成员在其中一种语言中有很强的熟悉度,那么将其作为评估的标准是好的,但如果没有的话,我认为对于初学者来说学习的难度没有太大差异。

最后

這是本系列的最後一篇文章。非常感謝您的閱讀,直到最後!我整理了初學者在使用Terraform建立基礎架構時的一些技巧。如果本文能對您有所幫助,我將非常高興。如果有任何錯誤,請隨意留言~~

广告
将在 10 秒后关闭
bannerAds