在本地或S3中管理terraform.tfstate文件的方法

首先

在使用Terraform的过程中,我在管理本地和S3中的terraform.tfstate时遇到了相当多的困难。
因此,我总结了针对每个位置进行管理时需要编写的代码和执行的命令。

绊倒与解决

如果您只想查看管理方法,请跳过本节。

跌倒 (diē

因为在各种网站上都有关于管理terraform.tfstate文件的方法,所以我试着根据这些网站上的内容,在S3桶中尝试保存terraform.tfstate文件。但是,即使我执行了被介绍的命令(terraform init),terraform.tfstate文件仍未在S3桶内创建。

为了弄清原因,我考虑了以下两个观点:
1. 查看GitHub的问题报告或博客等,因为可能有其他人也遇到过这个问题。
2. 在查看日志的同时,追踪Terraform源代码。

有一篇关于1的文章,它着重关注了以下几点。然而,实际尝试也未能解决问题。

    • この記事で書いてあるようなファイルの書き方

 

    バケットのポリシー設定方法

关于第2点,我参考了Terraform的官方页面,在执行terraform命令时添加了TF_LOG=TRACE以查看日志。我开始查看Terraform的源代码,但作为一个Go初学者,我只大致了解了流程。

因此,无论是1还是2的方法,都没有达到解决问题的目的。

解决问题

当我试错前进时,突然看到S3的存储桶,意识到有一个terraform.tfstate文件生成了。因此,我回顾了之前所做的修正和命令,逐一进行了区分,并最终得到了此处所记述的模式。

只要懂得Go的人,就能够通过代码理解,并且很快就能够理解其模式。我当时还不了解Go,所以通过这种方法来解决问题。

环境

    • Mac:macOS Catalina Version 10.15.5

 

    Terraform:v0.12.28

前提 tí)
条件
假设 (Jiǎ shè)
先决条件 jué

这里提供了使用Terraform创建VPC的示例。
此外,文章中介绍的IAM用户策略和存储桶设置是针对文章的设定。在实际环境中,请根据需要进行相应的策略和设置。

创建一个IAM用户

为了使用Terraform创建VPC,需要创建满足以下两个条件的IAM用户。

    • AmazonVPCFullAccessのアタッチ

 

    AWSアクセスの種類に「プログラムによるアクセス・アクセスキーを使用」を設定
Screen Shot 2020-07-22 at 19.34.14.png

本地管理

创建文件并执行命令

请按照以下方式创建main.tf。

provider "aws" {
  region  = "ap-northeast-1"
  access_key = "xxxxx"
  secret_key = "yyyyy"
}

# VPC
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-test"
  }
}

创建完main.tf后,执行以下三个命令。
※ 这里在进行terraform apply时加上了-auto-approve选项,但是没有也没问题。

$ terraform init
$ terraform plan
$ terraform apply -auto-approve

执行terraform apply后,会有以下输出,并且会在本地创建terraform.tfstate文件。

$ terraform apply -auto-approve
aws_vpc.vpc: Creating...
aws_vpc.vpc: Creation complete after 4s [id=vpc-aaaaa]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

使用S3进行管理

在IAM用户中添加访问存储桶的策略。

Screen Shot 2020-07-23 at 1.37.11.png

在S3上创建一个存储桶

Screen Shot 2020-07-21 at 21.10.21.png
Screen Shot 2020-07-21 at 20.28.22.png
Screen Shot 2020-07-21 at 6.59.37.png
Screen Shot 2020-07-21 at 21.11.55.png
Screen Shot 2020-07-21 at 21.13.50.png

在桶中设置桶策略。

为了将terraform.tfstate配置到S3中,需要进行存储桶策略的设置。请参考terraform官方网页,并使用所创建的IAM用户和存储桶名称,按照以下方式设置存储桶策略。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111:user/terraform-bucket-manager"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::bucket-for-tf"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::11111:user/terraform-bucket-manager"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::bucket-for-tf/*"
        }
    ]
}
Screen Shot 2020-07-21 at 21.25.34.png

文件的创建和命令执行

创建main.tf如下所示。
基本上与“在本地管理terraform”一节相同。不同之处在于将s3指定为后端。

将以下的main.tf文件创建如下:
基本上与“在本地管理terraform”一节相同。不同之处在于指定了s3作为后端。

provider "aws" {
  region  = "ap-northeast-1"
  access_key = "xxxxx"
  secret_key = "yyyyy"
}

terraform {
  backend "s3" { 
    access_key = "xxxxx"
    secret_key = "yyyyy"
    bucket  = "bucket-for-tf"
    region  = "ap-northeast-1"
    key     = "terraform.tfstate"
    encrypt = true
  }
}

# VPC
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-test"
  }
}

创建后,执行以下三个命令。

$ terraform init
$ terraform plan
$ terraform apply

当执行terraform init命令时,会显示设置s3为后端的完成信息。

$ terraform init

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
・・・略・・・
Screen Shot 2020-07-21 at 21.40.55.png

将本地管理迁移到S3管理中。

本地管理

创建main.tf如下所述。
基本上与“在S3中管理terraform.tfstate”相同。唯一的区别是指定了本地作为后端。

provider "aws" {
  region  = "ap-northeast-1"
  access_key = "xxxxx"
  secret_key = "yyyyy"
}

terraform {
  backend "local" {
    path = "terraform.tfstate"
  }
}

# VPC
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-test"
  }
}

一旦创建完成后,将执行以下三个命令。

$ terraform init
$ terraform plan
$ terraform apply -auto-approve

执行 “terraform init” 命令后,将显示设置本地作为后端的完成消息。

$ terraform init

Initializing the backend...

Successfully configured the backend "local"! Terraform will automatically
use this backend unless the backend configuration changes.
・・・略・・・

更改为S3的管理。

在terraform apply完成之后,将main.tf文件中的backend更改为s3。有关使用的IAM用户和S3存储桶,请参考“创建IAM用户”和“创建S3存储桶”。

provider "aws" {
  region  = "ap-northeast-1"
  access_key = "xxxxx"
  secret_key = "yyyyy"
}

terraform {
  backend "s3" { 
    access_key = "xxxxx"
    secret_key = "yyyyy"
    bucket  = "bucket-for-tf"
    region  = "ap-northeast-1"
    key     = "terraform.tfstate"
    encrypt = true
  }
}

# VPC
resource "aws_vpc" "vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name = "vpc-test"
  }
}

由于更改了后端,请重新执行以下命令。

$ terraform init

由于被询问是否可以将 terraform.tfstate 复制到 s3 中,我们输入“是”。

$ terraform init

Initializing the backend...
Backend configuration changed!

Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.


Terraform detected that the backend type changed from "local" to "s3".
・・・略・・・
 Do you want to copy this state to the new "s3"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes

输入”Yes”后,将在后端显示”S3设置已完成”的消息。

$ terraform init
・・・略・・・
  Enter a value: yes

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
・・・略・・・
Screen Shot 2020-07-23 at 0.01.37.png

我会在此之后执行`terraform apply`。
当查看S3存储桶时,可以看到`terraform.tfstate`已经被更新了。

$ terraform apply -auto-approve
aws_vpc.vpc: Refreshing state... [id=vpc-aaaaa]

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Screen Shot 2020-07-23 at 0.02.09.png

最后

我已经提供了关于如何在本地和S3上管理terraform.tfstate的方法。如果你了解Go语言的话,我认为可以更轻松地解决这个问题。

如果本文能为将来的我或者有困难的某人提供帮助,我将非常高兴。

请参考下列资料

将 Terraform 的 backend 配置为 S3 并初始化的最基本步骤
使用 Terraform 管理 S3 或 DynamoDB 作为后端的设置方法
一些个人在使用 Terraform 一段时间后学到的技巧
无法使用 Terraform 将 tfstate 文件上传到 S3 中

广告
将在 10 秒后关闭
bannerAds