无意中,Terraform已经将磁盘填满了

首先

突然发生了一个情况。在使用MacBook Air时突然收到一条警告。

image.png

我没有保存音乐文件和视频文件,但当我考虑使用Parallels虚拟机时,我发现terraform目录非常大!


$ du -sh terraform/
6.5G    terraform/

进一步查看terraform目录后,我们发现terraform-provider-aws_v2.48.0_x4文件大小达到了173MB。


$ ls -laRh terraform

〜
terraform/anyservice/anyenv/awsconfig/.terraform/plugins/darwin_amd64:
total 354416
drwxr-xr-x  4 nishimura.toru  staff   128B  2 14 20:14 ./
drwxr-xr-x  3 nishimura.toru  staff    96B  2  4 20:16 ../
-rwxr-xr-x  1 nishimura.toru  staff    79B  2 14 20:14 lock.json*
-rwxr-xr-x  1 nishimura.toru  staff   173M  2 14 20:14 terraform-provider-aws_v2.48.0_x4*
〜

这个 terraform-provider-aws_vナンチャラ 是一个用于在Terraform中创建、管理和更新AWS资源的AWS提供商插件。当执行terraform init命令时,它会被下载和安装在执行该命令的目录下的”.terraform/plugins/”文件夹中。

我意识到Terraform的组件(tfstate单位)需要“关注点分离”,所以将其按照服务、环境和AWS资源分开。而且,为每个AWS账户创建了这样的terraform目录。因此,我无意中发现插件文件不断增多,占用了磁盘空间…


$ tree -L 3 terraform/
terraform/
├── anyservice
│   └── anyenv
│       ├── awsconfig
│       ├── budgets
│       ├── cloudwatchevents
│       ├── cost
│       ├── iam
│       ├── s3
│       └── sns
├── credentials
├── サービス名
│   ├── anyenv
│   │   ├── acm
│   │   └── sns
│   ├── base
│   │   ├── backup
│   │   ├── cloudwatchalarm
│   │   ├── ec2
│   │   ├── eip
│   │   ├── route53_xxx.local
│   │   ├── routetable
│   │   ├── s3
│   │   ├── securitygroup
│   │   ├── subnet
│   │   └── vpc
│   ├── development
│   │   ├── alb
│   │   ├── backup
│   │   ├── cloudwatchalarm
│   │   ├── ec2
│   │   ├── eip
│   │   ├── elasticache
│   │   ├── natgateway
│   │   ├── rds
│   │   ├── route53_xxx.xxx.jp
│   │   ├── s3
│   │   └── securitygroup
│   ├── production
│   │   ├── alb
│   │   ├── backup
│   │   ├── cloudwatchalarm
│   │   ├── ec2
│   │   ├── eip
│   │   ├── elasticache
│   │   ├── natgateway
│   │   ├── rds
│   │   ├── route53_xxx.xxx.jp
│   │   ├── s3
│   │   └── securitygroup
│   ├── staging
│   │   ├── alb
│   │   ├── backup
│   │   ├── cloudwatchalarm
│   │   ├── ec2
│   │   ├── eip
│   │   ├── elasticache
│   │   ├── natgateway
│   │   ├── rds
│   │   ├── route53_xxx.xxx.jp
│   │   ├── s3
│   │   └── securitygroup
├── provider.tf
├── terraform_remote_state.tf
└── variable.tf

参考文献:
– Terraform文档:提供者
– Terraform文档:插件安装

2. 应对措施

在Terraform中,有一个名为”提供者插件缓存”的功能,可以控制不必要的插件下载和安装。

由于提供程序插件可能会非常大(数百兆字节),所以默认行为对于具有低速或按量计费的互联网连接的用户来说可能不方便。因此,Terraform提供选项,可以将本地目录用作共享的插件缓存,这样可以将每个插件二进制文件只下载一次。

提供者插件缓存功能可以通过Terraform配置文件或环境变量进行启用。

一旦启用,

如果插件缓存目录已启用,则terraform init命令将继续访问插件分发服务器,并获取与可用插件相关的元数据,但如果选择的插件已被选择为正确版本,则首先会检查选定的插件是否已在缓存中可用目录。在这种情况下,将使用先前下载的插件二进制文件。

如果选择的插件尚未缓存在其中,则首先将其下载到缓存中,然后将其复制到当前工作目录下的正确位置。

(引用:Provider Plugin Cache Google Translate)

使用时需要注意的事项是:

当Terraform安装到插件缓存中后,它将不会被从插件缓存中删除。随着时间的推移,插件可能会进行升级,导致缓存目录中包含一些未使用的版本,这时需要手动进行删除。

3. 「提供者插件缓存」有效的方法

3.1. Terraform配置文件

如果要在terraform配置文件中启用,请在用户的主目录下创建“.terraformrc”文件,并设置插件下载路径如下所示。

$HOME/.terraformrc 可以重新表达为:家目录下的.terraformrc文件。


plugin_cache_dir   = "$HOME/.terraform.d/plugin-cache"

尽管Terraform文档中的示例提到了”.terraform.d”,但实际上,在执行terraform init时创建的目录是”.terraform”,所以也许更好的是使用”plugin_cache_dir = “$HOME/.terraform/plugin-cache”。

在这个设置方法中,要求在该机器上使用相同版本的AWS Provider插件进行terraform操作。
在进行Provider Plugin Cache设置之前,最好先统一AWS Provider插件的版本。

3.2. 环境变量

如果您想为Terraform的每个组件指定AWS Provider插件的版本,请在运行terraform init之前,在环境变量中启用它。


export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"

使用这种设置方法,当shell会话结束时,它会消失。

由于每次执行环境变量命令都很烦人,因此最好使用direnv等工具,在每个目录中预先设置环境变量。

尝试使用提供者插件缓存。

我这次尝试了在terraform配置文件中启用Provider Plugin Cache的方法。
在启用Provider Plugin Cache后,我删除了每个Terraform组件中已存在的.terraform目录,然后执行了terraform init命令。

4.1. 在配置提供者插件缓存之前,进行配置和设置的确认。

terraformディレクトリ構成

$ tree -a terraform/

〜
├── anyservice
│   └── anyenv
│       ├── awsconfig
│       │   ├── .terraform
│       │   │   ├── plugins
│       │   │   │   └── darwin_amd64
│       │   │   │       ├── lock.json
│       │   │   │       └── terraform-provider-aws_v2.48.0_x4
│       │   │   └── terraform.tfstate
│       │   ├── backend.tf
│       │   ├── config-rule.tf
│       │   ├── main.tf
│       │   ├── provider.tf -> ../../../provider.tf
│       │   └── terraform_remote_state.tf -> ../../../terraform_remote_state.tf
│       ├── budgets
│       │   ├── .terraform
│       │   │   ├── plugins
│       │   │   │   └── darwin_amd64
│       │   │   │       ├── lock.json
│       │   │   │       └── terraform-provider-aws_v2.45.0_x4
│       │   │   └── terraform.tfstate
│       │   ├── backend.tf
│       │   ├── main.tf
│       │   └── provider.tf -> ../../../provider.tf
│       ├── cloudwatchevents
│       │   ├── .terraform
│       │   │   ├── plugins
│       │   │   │   └── darwin_amd64
│       │   │   │       ├── lock.json
│       │   │   │       └── terraform-provider-aws_v2.47.0_x4
│       │   │   └── terraform.tfstate
│       │   ├── awsconfig.tf
│       │   ├── backend.tf
│       │   ├── health.tf
│       │   ├── provider.tf -> ../../../provider.tf
│       │   └── variable.tf -> ../../../variable.tf
〜
    • provider.tf ファイル

AWSプロバイダーバージョンを 2.48.0 に固定

provider "aws" {
  version                 = "2.48.0"
  shared_credentials_file = "../../../credentials"
  profile                 = "terraform"
  region                  = "ap-northeast-1"
}
provider "aws" {
  version                 = "2.48.0"
  shared_credentials_file = "../../../credentials"
  profile                 = "terraform"
  alias                   = "virginia"
  region                  = "us-east-1"
}
    • backend.tf ファイル (terraform/anyservice/anyenv/awsconfig/backend.tfの例)

backendは S3 を利用
terraform のバージョンは 0.12.9 以上

terraform {
  required_version = ">= 0.12.9"
  backend "s3" {
    shared_credentials_file = "../../../credentials"
    profile                 = "terraform"
    bucket                  = "terraform-tfstate-チョメチョメ"
    key                     = "anyservice/anyenv/awsconfig/terraform.tfstate"
    region                  = "ap-northeast-1"
  }
}
    credentials ファイル

[terraform]
aws_access_key_id = チョメチョメ
aws_secret_access_key = チョメチョメ
    .gitignore ファイル

.terraform/
credentials

4.2. 启用提供者插件缓存的设置

$HOME/.terraformrc :家目录下的.terraformrc


plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"

创建目录


$ mkdir -p $HOME/.terraform.d/plugin-cache

4.3. 运行提供者插件缓存设置

4.3.1. 第一项(首次)

删除 terraform/anyservice/anyenv/awsconfig/.terraform,并执行 terraform init。


$ cd terraform/anyservice/anyenv/awsconfig/
$ rm -rf .terraform/
$ terraform init

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (hashicorp/aws) 2.48.0...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

$ ls -lh $HOME/.terraform.d/plugin-cache/darwin_amd64/terraform-provider-aws_v2.48.0_x4
-rwxr-xr-x  2 nishimura.toru  staff   173M  2 15 17:29 /Users/nishimura.toru/.terraform.d/plugin-cache/darwin_amd64/terraform-provider-aws_v2.48.0_x4*

$ terraform plan

4.3.2. 第二个

删除 terraform/anyservice/anyenv/budgets/.terraform,然后执行 terraform init。

检查容量之前的执行


$ du -sh terraform/
6.5G    terraform/

 


$ cd terraform/anyservice/anyenv/budgets/
$ rm -rf .terraform/
$ terraform init

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (hashicorp/aws) 2.48.0...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

 


$ terraform plan

 


$ du -sh terraform/
6.3G    terraform/

4.3.3. 第三项

删除terraform/anyservice/anyenv/cloudwatchevents/.terraform,并运行terraform init。

进行


$ cd terraform/anyservice/anyenv/cloudwatchevents/
$ rm -rf .terraform/
$ terraform init

 


$ terraform plan

 


$ du -sh terraform/
6.2G    terraform/

4.3.4. 在所有的Terraform组件中执行。

执行后的容量确认


$ du -sh terraform/
180M    terraform/

 

广告
将在 10 秒后关闭
bannerAds