编写Terraform时使用的技巧

IaC 确实很困难。

我觉得现在经常听到有关「最好使用IaC」的说法。
但实际上,过去我们在管理控制台上轻松完成的任务,如果想要IaC化,将会非常困难!
你有没有「最后放弃,继续在管理控制台上管理」这样的经验?

我們這次的目標是使用名為Terraform的工具來輕鬆地創建資源,就像在管理控制台上創建一樣簡單!

为了简化IaC的操作步骤

    1. 使用管理控制台或AWS CLI创建实际运行环境。

 

    1. 使用Terraformer自动创建tf文件。

 

    1. 实际上编写Terraform代码。

 

    1. 注意标准模块结构。

 

    1. 通过Terraformer创建的代码仅供参考,不使用生成的代码。

 

    1. 使用JetBrain系列IDE的Terrafrom插件。

 

    1. 使用Terraform官方文档。

 

    1. 使用terraform import/plan来检查和修正在管理控制台中创建的环境与差异。

 

    使用terraform apply来确认所意图创建的资源是否已经被创建。

使用管理控制台或AWS CLI来创建实际运行的环境

在进行Terraform配置时,很难从大量的配置项中找到适当的配置值,即使在管理控制台中可以直观简单地创建资源,但在背后使用了各种资源,当想要进行基础设施即代码时,却无法轻易创建。这种情况经常发生。
为了能够检测到差异,请先在管理控制台上创建资源。
但是,并不需要特意在管理控制台上创建那些可以通过Terraform轻松创建的大量资源。我知道可以使用Terraform模块来简单创建它们。

通过使用Terraformer,机械地创建tf文件。

Terraformer可以读取AWS Config的信息,并将配置信息转化为Terraform的tf文件。由于它是机器生成的,所以并不能完美地生成完整的配置内容,但作为配置值的参考非常方便。所以,让我们先在手头创建当前环境的资源。

我将解释如何使用。

首先,需要安装。

brew install terraformer

可以通过安装来完成。

请用中文解释下面的命令:

terraformer import aws --resources='*' --regions=ap-northeast-1

所以,你可以执行它。

支持的服务列表可在此处找到:
https://github.com/GoogleCloudPlatform/terraformer/blob/master/docs/aws.md

如果创建所有资源太大的话,可以通过VPC ID进行过滤。

--filter="vpc-xxxxxxxxxxxxxxxxxx"

我觉得输出目录的结构很好,按资源类型分别存放文件,非常清晰明了,可以很容易地知道哪个资源写在哪里。

.
├── generated
│   └── aws
│       ├── acm
│       │   ├── provider.tf
│       │   └── terraform.tfstate
│       ├── alb
│       │   ├── lb.tf
│       │   ├── lb_listener.tf
│       │   ├── lb_target_group.tf
│       │   ├── outputs.tf
│       │   ├── provider.tf
│       │   ├── terraform.tfstate
│       │   └── variables.tf

建议您不要直接使用Terraformer生成的代码,因为它们仅供参考使用。

有几个理由。
首先,由Terraformer生成的代码已经过时了。(无法生成Terraform 1系的代码)
此外,它不能完全解决所有依赖关系,所以不能直接部署。
由于依赖关系的arn等硬编码,无法部署到多个环境中,所以我们需要解决这些问题。这可能是一个相当大的工程,所以请将Terraformer的代码仅作为参考实现,而不是出发点。

标准模块结构

当在多个环境(开发、测试、生产等)中进行基础架构即代码(IaC)的规划时,常见的问题是如何设置不同环境的配置值,比如 CPU 的大小。

为了解决这些问题,可以在每个模块中创建资源,使用传递给模块的var值来适当地进行条件判断。

我经常使用以下目录结构和文件结构。

.
├── environments
│   ├── dev
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   ├── variables.tf
│   │   └── versions.tf
│   ├── host
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   ├── variables.tf
│   │   └── versions.tf
│   └── prod
│       ├── main.tf
│       ├── outputs.tf
│       ├── variables.tf
│       └── versions.tf
└── modules
    └── base
        ├── data.tf
        ├── eks.tf
        ├── locals.tf
        ├── outputs.tf
        ├── provider.tf
        ├── variable.tf
        └── vpc.tf

在更复杂的系统中,我们通常会创建不止一个基础模块,还会创建更多的模块。
在这种情况下,建议根据部署频率和生命周期来创建模块。
此外,还可以考虑从多个微服务引用相同的模块。

从声明的角度来看,为了对Terraform 进行编码,重要的是不在其中加入条件分支等逻辑。通过这样做,可以消除可读性和依赖性。

使用JetBrain公司的IDE上的Terraform插件。

在开发体验中,以下几点非常重要。更多详细信息请参考ClassMethod的文章,其中包括了自动补全、自动填入必需值、验证等非常优质的功能。通过这些功能,开发者只需要在管理控制台的文本框中输入设定值,就能将开发体验变得非常接近。

 

顺便提一下,属性的建议可以通过按下ctrl+space来实现,但这个快捷键通常被分配给了“英日转换”,所以经常无法使用。

由于这个命令非常强大而方便,所以我使用shift+space进行操作。关于更改方法,请查看以下链接。

 

使用terraform import/plan命令,可以查看并修正与通过管理控制台创建的环境之间的差异。

使用terraform import命令可以将管理控制台上的资源放置在Terraform管理之下。
让我们首先使用terraform import命令将在管理控制台上创建的资源导入。
然后,参考由Terraformer生成的内容,同时意识到标准模块结构,为所需的资源编写设置。
由于我们导入了管理控制台上的资源,因此可以使用terraform plan命令了解我所编写的Terraform代码与实际在管理控制台上生成的代码之间的差异。
在消除差异之前,我们将修改先前描述的Terraform配置。
以下的博客提供了详细的步骤,并且很容易理解,因此引用如下。

 

如果没有差异,那么我们可以说通过IaC对最初在管理控制台上创建的资源进行了描述。

在进行Terraform导入时,需要在直接的根模块中定义资源。
当采用上述的目录结构时,在environments中管理tfstate,因此需要在那里定义希望导入的资源。
本来我认为应该在modules下的模块中进行编写,但那里导入不成功,请注意这一点。
在进行导入时,在environments/dev/import.tf等文件中定义资源,如果terraform import命令成功,它将被纳入tfstate。
然后,可以将资源的信息迁移到模块中。

如果你不确定在这种情况下应该导入哪个资源,可以使用Terraformer生成的资源来确认。
使用它可以轻松地创建要导入的资源。

总结

事先在管理控制台上创建大部分资源是关键。
因此,与以往的建设经验几乎没有太大差异,可以直观地创建资源。

另外,通过利用强大的IDE建议功能,可以消除DSL的复杂性。您可以获得类似于在管理控制台文本框中输入配置值的体验。

而且,最强大的就是terraform import命令。
通过使用该命令,可以查看当前AWS环境与管理控制台所创建的配置之间的差异。即使存在巨大的差异也会让人感到不便,但通过参考Terraformer生成的文件并填写设置值,可以有效地进行操作。

参考资料

    • https://zenn.dev/sway/articles/terraform_biginner_modules

 

    https://dev.classmethod.jp/articles/multiple-provisionings-with-terraform-and-directory-partition/
广告
将在 10 秒后关闭
bannerAds