在使用Terraform之前需要考虑的事项

这是《未来Advent Calender 2021》的第10天文章。
昨天是@iwaaya先生分享的《SwiftUI实例教程(MVVM模式,CoreData,API执行+异步处理)》。

首先

我觉得在建立新的云环境时,很多人会选择使用Terraform(对于使用Cloud Formation等的人,我很抱歉)。
而且,我认为也有一些人会立刻编写代码并执行terraform apply。

请稍等一下。
当项目变大时,可能会承担较大的债务。
事后想着应该怎样做可能为时已晚(也许不算晚,但会付出相当大的代价)。
因此,在这篇文章中,我会简单地写下在个人编写代码之前需要考虑的事情。

    • Terraform の実行環境をどうするか

 

    ディレクトリ構成

还有其他的选择,但我列举这两个是因为它们非常重要。

怎样设置 Terraform 的执行环境?

对于Terraform的执行环境,最好提前确定并整理好环境。如果是个人规模的项目,我认为使用本地环境作为执行环境也是不错的选择。然而,如果是多人共同运营的情况,这样做就不太可行了。因此,接下来我想介绍一下以下示例作为执行环境的大致推荐方案。

    1. 本地环境

 

    1. 服务器环境,如EC2等

 

    1. 基于浏览器的CLI环境,如CloudShell

 

    1. CI/CD环境

 

    Terraform云环境

1. 本地执行环境

在一個熟悉的編輯器中編碼並且能夠立即在終端機上執行的環境非常具有吸引力。
但是,如果在本地環境中執行,就必須發行具有相當權限的金鑰,這在安全方面非常危險。
另外,雖然有時候計劃在發布之前在本地環境中執行,然後在發布之後轉移到非本地環境,但通常情況下仍然保持在本地。
如果有考慮在某個時候將執行環境轉移,最好在發布之前進行。

顺便提一句,由于TFenv非常方便,我推荐你安装它。

tfenv – tfenv 是一个用于管理和安装 Terraform 版本的工具。

tfenv是一个用于简化Terraform版本管理的工具。安装了tfenv后,您可以使用以下命令安装和切换到想要使用的版本。

$ tfenv install 1.1.0
$ tfenv use 1.1.0

2. 例如 EC2 的服务器环境

作为手动执行环境,与本地环境相比,执行环境显然更好。
通过设置服务器本身的审计日志等措施以及进行认证,也能够在审计方面进行了解。
然而,建立这些环境会带来成本和运营成本。
此外,由于手动执行不变,会出现错误和执行成本的问题。
结果是,虽然比本地环境好,但并不是特别推荐。

3. 像CloudShell这样基于浏览器的CLI环境

云服务提供商提供基于浏览器的CLI环境。通过使用该环境,可以轻松获取Terraform的执行环境。另外,由于可以更改CloudShell的容器映像,因此可以事先安装Terraform。与准备服务器相比,使用起来更加方便。因此,比起在EC2等上准备Terraform执行环境更加推荐。然而,如果是多人构建的情况,则需要统一Terraform本身的版本和提供商版本,因此建议按照以下方式在versions.tf中进行记录(包括本地环境)。

terraform {
   required_version = "~> 1.1.0"

   required_providers {
     aws = {
       source  = "hashicorp/aws"
       version = "3.38.0"
     }
   }
 }

4. 持续集成/持续交付环境

这是一个通过GitHub Actions和CircleCI等工具来执行Terraform的环境。通过与GitHub的协作,可以实现自动执行。当想要进行Terraform代码审查时,可以在PR中附上Terraform plan的执行结果,并在CI界面上进行确认。如果一切正常,可以进行合并,并在合并时自动执行terraform apply。另外,如果在CI界面上查看计划结果比较麻烦,我推荐使用Mercari开源的tfnotify工具。它会将Terraform plan和apply的执行结果写入PR评论中。

因此,将CI/CD环境设置为Terraform执行环境是值得推荐的。但是,作为缺点,需要发布具有强大权限的密钥,因此需要管理和规划其生命周期。此外,还会产生构建环境所需的建设成本。

顺便提一下,如果将以下工具与 CI 组合使用,会更加顺利。

您好,非常抱歉,但是我无法对” TFlint ” 进行翻译。感谢您的理解。

TFlint是Terraform的Linter。

我认为在使用Terraform的`terraform plan`命令时无法检测到错误,而往往会在应用(`apply`)时发现错误的情况相当常见。
因此,通过引入TFlint可以在应用(`apply`)时检测到不一致等问题。

TFsec是一个开源的基于规则的静态代码分析工具,用于帮助开发者和团队检查和维护其基础设施即代码的安全性。

TFsec是一款用于对Terraform代码进行静态分析的安全扫描工具。
AWS有一个名为Security Hub的服务,它可以对已构建的资源进行安全检查。
TFsec可以在构建之前通过代码级别进行检查。
因此,将TFsec集成到持续集成中将会更加顺利。

順便提一下,由于TFsec已被Aqua Security收购并整合到Trivy中,您可以查看以下内容以了解详情。

5. Terraform 云端

通过使用 Terraform Cloud,可以获得以下优点。

    • Terraform plan/apply の実行履歴

 

    • ソース管理: GitHubなどと連携が可能

 

    • パイプライン

 

    • tfstate管理: セキュアにtfstate を管理可能(権限管理)

 

    • Sentinel 機能: セキュリティベストプラクティスに則っているかのチェック

 

    • 通知: Slack やメールへの通知、Webhook の利用が可能

 

    証跡ログの管理

如果想要降低准备CI/CD环境的成本,快速建立高安全级别的环境,推荐使用此选项。
但是,如果想要使用所有功能,建议选择付费版本以评估成本效益。

关于目录结构的安排,您打算怎么做呢?

Terraform的目录结构如何安排是一个在业界被广泛讨论的问题,也是一个非常棘手的问题。
此外,当资源不断增加时,更改目录结构会非常耗费成本。
与执行环境一样,尽早考虑配置是非常重要的。

在考虑目录结构时,我们将介绍有关采用哪种方式以及哪种方式更好的方法。
这里说的环境指的是生产环境、验证环境、开发环境等。

就环境隔离的方式而言,主要有以下几种。

    1. 目录分割

 

    1. 模块

 

    工作空间

1. 目录分割

目录划分在出现各种环境差异时容易处理。
然而,由于代码重复,这违反了DRY原则。
不过,由于结构明晰,推荐给第一次使用Terraform的人。

.
├── prod
│   ├── xxx.tf
│   └── xxx.tf
├── stg
│   ├── xxx.tf
│   └── xxx.tf
└── dev
    ├── xxx.tf
    └── waf.tf

2. 模块

通过将模块分割为每个环境,可以实现DRY(Don’t Repeat Yourself)的配置。
需要以重用性为意识来进行配置,但是它有很多好处。
然而,对于初次接触 Terraform 的人来说可能会有些难以理解。
另外,Terraform Registry 上有各种资源的模块可供使用。

.
├── module
│   ├── xxx.tf
│   └── xxx.tf
├── prod
│   ├── xxx.tf
│   └── xxx.tf
├── stg
│   ├── xxx.tf
│   └── xxx.tf
└── dev
    ├── xxx.tf
    └── xxx.tf

工作空间

可以在每个环境中不分隔目录而构建Workspace。
以下是关于Workspace的目录示例解释。

.
├── ec2.tf
└── locals.tf

创建和切换工作空间可以通过输入以下命令进行切换。

### Workspace 作成
$ terraform workspace new dev
### Workspace 切り替え
$ terraform workspace select dev
Switched to workspace "dev".

工作区使用变量`${terraform.workspace}`。
假设该变量被分配给了之前指定的工作区”dev”。

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = local.web[terraform.workspace][type]

  tags = {
    Name = "${terraform.workspace}-hoge"
    Env = "terraform.workspace
  }
}

在locals.tf文件中进行变量指定。

locals {
  instance_web = {
    prod = {
      type   = "c4.large"
      xxx = "xxx"
    }
    stg = {
      type   = "t3a.medium"
      xxx = "xxx"
    }
    dev = {
      type   = "t3a.medium"
      xxx = "xxx"
    }
  }
}

通过使用 Workspace,您可以实现DRY编写并轻松扩展环境。
然而,如果出现了不同环境中的资源差异,您需要使用 count 等方法来吸收这些差异,这可能会导致可读性较差。

此外,在进行终端操作时,有些人可能会觉得不知道自己在哪个工作区中,有可能会发生意外。因此,也有人提出放弃使用工作区的意见。然而,通过改变终端的方式,能够通过视觉方式清楚地看到自己所在的工作区。因此,在使用工作区时,建议进行自定义设置。

スクリーンショット 2021-12-10 8.58.01.png

个人觉得哪种目录结构最好。

就我个人而言,我认为将Workspace和Module进行混合是一个不错的选择。
将共享的身份和访问管理(IAM)等资源放在Module中,而将实际的应用程序和网络服务放在Workspace中,这样可以避免环境差异。
如果出现环境中不同的资源,我个人认为最好的方式是通过添加评论和使用计数等方法来吸收。

其他

事实上,Uber已经发布了一个名为Astro的工具,它能够吸收Terraform资源依赖关系。通过使用它,可以以YAML为基础来控制资源的执行顺序。

如果想要了解关于 Terraform 工具等的信息,可以参考以下内容。

总结

我写了关于使用 Terraform 之前应该考虑的重要事项。

    • プロジェクトの規模を加味した実行環境の構成を決める

 

    メンバのスキルセットなどを加味したディレクトリ構成を決める

只要能对某个人有所帮助,我就会感到幸福。

明天是 @datake914 先生的日子!

请参考

广告
将在 10 秒后关闭
bannerAds