使用Terraform进行AWS配置管理的实战操作

这篇文章的内容适用于 terraform 0.9.0 版本以下。虽然在 terraform 0.9.x 版本中,大致的流程仍然相同,但是在后端方面有一些改动,并且我们计划将来会进行相应的更新。

以下是对给定的内容进行中文翻译的一个选择:
==========================================

Terraform是一种工具,可以通过代码表达和管理基础设施的构建和配置。它支持多种环境,如AWS、Azure和Heroku。

这份资料是为了在Rabbit House公司内进行的、用于处理AWS资源的terraform操作的实践而创建的。我认为对于那些想要使用代码来进行AWS配置管理的人来说,有些人可能会觉得这样的工具很麻烦,或者很容易变得无法使用,但是terraform非常简单,学习成本非常低。而且,我认为通过将AWS配置编码化,我们也可以更深入地理解AWS的各个方面。

你为什么不趁此机会尝试一下 terraform 呢?按照这篇文章的指引输入命令,你很快就能熟练地使用 terraform,可能不到一个小时就能掌握。

1. 环境建设

在这个实践项目中,我们将以 terraform v0.7.4 为基础进行讲解。

对于 Mac 的情况来说

    • https://www.terraform.io/downloads.html

brew install terraform でも可

在Windows的情况下

请访问以下链接获取最新版本的Terraform软件:https://www.terraform.io/downloads.html

AWS准备

事先创建好将用于Terraform的IAM用户。

    1. 访问IAM用户管理页面

 

    1. 创建新用户

 

    1. 附加必要的策略

 

    创建访问密钥和秘密密钥

管理S3存储桶

首先,我们创建、更改并尝试破坏一个 S3 存储桶。作为准备工作,请创建一个合适的工作目录。然后,我们编写访问 AWS 资源所需的设置。

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

创建一个S3存储桶。

我们立即创建一个 S3 存储桶吧。请创建一个如下所示的文件。但是,请确保存储桶的名称在全球范围内是唯一的。

resource "aws_s3_bucket" "terraform_tutorial" {
    bucket = "com.github.53ningen.terraform.tutorial" # S3 bucket 名は global で一意になるように
    acl = "private"
    versioning {
        enabled = true
    }
}

如果按照以上的方式创建了文件,可以尝试使用terraform validate命令来确认是否正确地编写了.tf文件。如果按照上述方式编写,我相信命令应该能够正常执行。

接下来,通过执行terraform plan命令来确认将要执行的操作。这个步骤始终是安全的,并且只会对AWS进行信息的读取操作。

% terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.


The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ aws_s3_bucket.terraform_tutorial
    acceleration_status:         "<computed>"
    acl:                         "private"
    arn:                         "<computed>"
    bucket:                      "com.github.53ningen.terraform.tutorial"
    force_destroy:               "false"
    hosted_zone_id:              "<computed>"
    policy:                      "<computed>"
    region:                      "<computed>"
    request_payer:               "<computed>"
    versioning.#:                "1"
    versioning.69840937.enabled: "true"
    website_domain:              "<computed>"
    website_endpoint:            "<computed>"


Plan: 1 to add, 0 to change, 0 to destroy.

根据 aws_s3_bucket.terraform_tutorial 的设定,我们确认 S3 存储桶已经创建成功了。现在,我们可以通过运行 terraform apply 命令来实际执行它。

% terraform apply
aws_s3_bucket.terraform_tutorial: Creating...
  acceleration_status:         "" => "<computed>"
  acl:                         "" => "private"
  arn:                         "" => "<computed>"
  bucket:                      "" => "com.github.53ningen.terraform.tutorial"
  force_destroy:               "" => "false"
  hosted_zone_id:              "" => "<computed>"
  policy:                      "" => "<computed>"
  region:                      "" => "<computed>"
  request_payer:               "" => "<computed>"
  versioning.#:                "" => "1"
  versioning.69840937.enabled: "" => "true"
  website_domain:              "" => "<computed>"
  website_endpoint:            "" => "<computed>"
aws_s3_bucket.terraform_tutorial: Creation complete

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

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate

由于事情无大碍且成功似乎已经实现,我们先从AWS CLI确认一下S3存储桶是否真实存在。

% aws s3 ls
...
2016-10-10 17:28:13 com.github.53ningen.terraform.tutorial
...

通过s3.tf文件我可以确认已经创建了一个名为com.github.53ningen.terraform.tutorial的bucket。那么,在成功执行terraform apply后,我认为会生成一个名为terraform.tfstate的文件。

% ls -a
.  ..  .git  s3.tf  terraform.tfstate  variable.tf

这个文件的内容是一个保存远程(在这种情况下是AWS)状态的文件。由于它包含访问密钥和密钥等信息,所以请将其排除在git管理之外。关于这个文件的管理,我们将在后面的”管理远程状态”部分进行解释。暂时先添加以下类型的.gitignore文件。

.DS_Store
*.tfstate
*.tfstate.backup
vendor/bundle
.bundle/
config.tfvars
.terraform/

修改S3存储桶的状态。

我们之前创建的S3 bucket已经启用了版本控制,现在让我们尝试禁用它。我们可以通过修改s3.tf文件来实现这一点。

resource "aws_s3_bucket" "terraform_tutorial" {
    bucket = "com.github.53ningen.terraform.tutorial" # S3 bucket 名は global で一意になるように
    acl = "private"
    versioning {
-       enabled = true
+       enabled = false
   }
}

接下来,使用 terraform validate 命令验证 tf 文件的语法,并使用 terraform plan 命令确定将对 AWS 资源进行哪些更改。

% terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

aws_s3_bucket.terraform_tutorial: Refreshing state... (ID: com.github.53ningen.terraform.tutorial)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

~ aws_s3_bucket.terraform_tutorial
    versioning.2972667452.enabled: "" => "false"
    versioning.69840937.enabled:   "true" => "false"


Plan: 0 to add, 1 to change, 0 to destroy.

计划:0代表添加,1代表更改,0代表删除。由于这个规划,现有的S3不会被删除,只会更改显示的参数。确认后,只需执行应用程序,S3状态的更改即可完成。

% terraform apply
aws_s3_bucket.terraform_tutorial: Refreshing state... (ID: com.github.53ningen.terraform.tutorial)
aws_s3_bucket.terraform_tutorial: Modifying...
  versioning.2972667452.enabled: "" => "false"
  versioning.69840937.enabled:   "true" => "false"
aws_s3_bucket.terraform_tutorial: Modifications complete

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

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate

销毁S3存储桶。

好的,我们之前作为教程创建了一个 S3 bucket,现在我们可以删除它。可以使用 terraform destroy 命令来执行删除操作,但是在执行之前,最好先确认一下。这种情况下,我们可以先尝试执行 terraform plan –destroy 命令。这样就可以查看 terraform destroy 的执行计划了。

% terraform plan --destroy
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

aws_s3_bucket.terraform_tutorial_tfsate: Refreshing state... (ID: com.github.53ningen.terraform.tutorial.tfstate)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

- aws_s3_bucket.terraform_tutorial_tfsate


Plan: 0 to add, 0 to change, 1 to destroy.

如果执行计划看起来没有问题,就尝试运行terraform destroy。

% terraform destroy
Do you really want to destroy?
  Terraform will delete all your managed infrastructure.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_s3_bucket.terraform_tutorial: Refreshing state... (ID: com.github.53ningen.terraform.tutorial)
aws_s3_bucket.terraform_tutorial: Destroying...
aws_s3_bucket.terraform_tutorial: Destruction complete

Destroy complete! Resources: 1 destroyed.

当运行 “terraform destroy” 命令时,系统会询问您是否确认要删除资源。如果您输入 “yes”,那么此前创建的S3存储桶将被删除。

2-4. 格式化tf文件。

使用Terrform fmt命令可以格式化文件。

% terraform fmt
remote_state.tf
variable.tf

2-5. Terraform的基本命令总结

我认为您已经理解了上述内容中 Terraform 的基本五个命令。总结如下:

terraform validate: .tf ファイルのシンタックスを検証する

terraform plan: terraform がこれから行う実行計画を表示する。–destroy オプションで destroy 時の実行計画を表示できる。

terraform apply: plan を実行する。

terraform destroy: terraform で作ったリソースを破棄する

terraform fmt: tfファイルをフォーマットする

请务必在应用之前仔细查看执行计划。我认为几乎不会使用 destroy 指令。同时,请勿将 terraform.tfstate 文件放入 git 进行管理,也不要使其暴露给他人。

管理远程状态

terraform.tfstate 文件是用来管理远程状态的文件。apply 成功后,它详细记录了每个资源以及被创建时使用的参数。

如果不小心删除 tfstate 文件,terraform 将错误地认为在远程资源不存在,并试图根据 tf 文件中的定义创建新配置。因此,我们需要以某种方式管理此文件,但由于其中包含大量敏感信息,无法简单地使用 git 进行管理。

有多种管理方法,但在这里我们将介绍使用私有S3存储桶来管理此文件的方法。

创建一个用于tfsate管理的S3存储桶。

我想您肯定已经对前面讲过的S3存储桶的创建有所理解了。让我们进行一次复习吧。让我们创建一个名为remote_state.tf的文件,内容如下。

resource "aws_s3_bucket" "terraform_tutorial_tfsate" {
    bucket = "com.github.53ningen.terraform.tutorial.tfstate" # S3 bucket 名は global で一意になるように
    acl = "private"
    versioning {
        enabled = true
    }
}

在使用 Terraform 时,可以先通过 `terraform plan` 命令确认执行计划,然后使用 `terraform apply` 命令创建存储桶。根据 Terraform 官方文档的推荐,建议启用版本控制。

进行tfstate管理设置。

一旦创建了无事S3存储桶,使用terraform remote config命令来进行tfstate文件的管理配置。请根据自己的情况相应更改以下命令中的桶名和访问密钥等内容。

% terraform remote config \
    -backend=S3 \
    -backend-config="bucket=com.github.53ningen.terraform.tutorial.tfstate" \
    -backend-config="region=ap-northeast-1" \
    -backend-config="key=terraform.tfstate" \
    -backend-config="access_key=${access_key}" \
    -backend-config="secret_key=${ecret_key}"
Remote state management enabled
Remote state configured and pulled.

在这里,键(key)是指在S3上管理tfstate文件的名称。如果命令成功执行,我认为当前目录中的terraform.tfstate文件将被移动到.terraform目录下。

将tfstate推送到远程

好的,管理设置完成后,让我们将 tfstate 文件传输到 S3 上。

% terraform remote push
State successfully pushed!

如果对远程进行terraform apply,请务必执行terraform remote push。

3-4. 从远程下载 tfstate

这通常用于多人开发的情况,例如希望在别人 apply 之后同步远程状态。

% terraform remote pull
Local and remote state in sync

进行更高级的资源定义

4-1. 使用变量

在variable.tf中直接写入了aws的access_key和secret_key,但是可以使用变量功能来在运行时指定它们。

provider "aws" {
  region = "ap-northeast-1"
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
}

variable "access_key" {}
variable "secret_key" {}

在执行terraform plan之前,请按照上述步骤在对话框中指定每个参数应该取哪个值。

% terraform plan
var.access_key
  Enter a value: hoge

var.secret_key
  Enter a value: fuga

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

...以下略

另外,还可以通过指定变量的默认值来实现以下功能。

provider "aws" {
  region = "${var.region}"
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
}

variable "access_key" {}
variable "secret_key" {}
variable "region" {
  default = "ap-northeast-1"
}

使用环境变量

由于每次都要在 CLI 中指定 access_key 和 secret_key 有些麻烦,所以使用环境变量似乎更方便。在 terraform 中,您可以在 .tf 文件中使用以 TF_VAR_ 为前缀的环境变量。让我们立即使用它来从环境变量中获取 access_key 和 secret_key。

% echo 'export TF_VAR_MY_AWS_ACCESS_KEY=XXXXXXXXXXX' >> ~/.bash_profile
% echo 'export TF_VAR_MY_AWS_SECRET_KEY=XXXXXXXXXXX' >> ~/.bash_profile
% source ~/.bash_profile

接着我们来修改 variable.tf 文件,修改如下:

provider "aws" {
  region = "${var.region}"
  access_key = "${var.MY_AWS_ACCESS_KEY}"
  secret_key = "${var.MY_AWS_SECRET_KEY}"
}

variable "MY_AWS_ACCESS_KEY" {}
variable "MY_AWS_SECRET_KEY" {}
variable "region" {
  default = "ap-northeast-1"
}

如果能够在没有变量指定的情况下使用terraform plan,则可以确认环境变量已成功使用。

4-3. 进行具有依存管理的资源定义

在构建更复杂的资源时,资源之间会产生依赖关系。例如,当想要为使用 Terraform 创建的 IAM 用户附加策略时,我认为资源之间存在依赖关系。

我想现在要创建一个名为cocoa的IAM用户并附加IAMReadOnlyAccess策略。对应的.tf文件可按以下方式描述即可。

# IAM ユーザーの作成
resource "aws_iam_user" "cocoa" {
  name = "cocoa"
  path = "/"
}

# IAM ポリシーのアタッチ
resource "aws_iam_policy_attachment" "IAMReadOnlyAccess-policy-attachment" {
  name       = "IAMReadOnlyAccess-policy-attachment"

  # IAMReadOnlyAccess の ARN
  policy_arn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
  groups     = []

  # 上で定義した cocoa ユーザーの name を参照している
  users      = ["${aws_iam_user.cocoa.name}"]  
  roles      = []
}

当执行terraform plan命令时,您将会看到依赖关系已经被解析。

% terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

aws_s3_bucket.terraform_tutorial_tfsate: Refreshing state... (ID: com.github.53ningen.terraform.tutorial.tfstate)

The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ aws_iam_policy_attachment.IAMReadOnlyAccess-policy-attachment
    name:             "IAMReadOnlyAccess-policy-attachment"
    policy_arn:       "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
    users.#:          "1"
    users.3920907786: "cocoa"

+ aws_iam_user.cocoa
    arn:           "<computed>"
    force_destroy: "false"
    name:          "cocoa"
    path:          "/"
    unique_id:     "<computed>"


Plan: 2 to add, 0 to change, 0 to destroy.

4-4. 使用设定文件

在处理复杂资源的管理时,使用只包含设置的配置文件似乎非常方便。Terraform也配备了使用配置文件的机制。这次我们将AWS的区域指定切分到配置文件中。请删除variable.tf文件中的region变量的默认值。

provider "aws" {
  region = "${var.region}"
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
}

variable "access_key" {}
variable "secret_key" {}
variable "region" {
-  default = "ap-northeast-1"
}

然后我们将在名为 config.tfvars 的文件中进行以下设置描述。

region = "ap-northeast-1"

只需在 terraform plan 或 terraform apply 时指定配置文件即可。可以使用 -var-file= 选项来指定配置文件。

% terraform plan -var-file=./config.tfvars
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.

# 以下略

4-5. 进行产出

如果您想获取在运行 terrform apply 后创建的资源的ARN等信息,可以使用 output 功能来实现。例如,如果您想输出刚刚创建的 cocoa 用户的ARN,只需按照以下步骤即可。

resource "aws_iam_user" "cocoa" {
  name = "cocoa"
  path = "/"
}

# IAM policy attatchments

resource "aws_iam_policy_attachment" "IAMReadOnlyAccess-policy-attachment" {
  name       = "IAMReadOnlyAccess-policy-attachment"
  policy_arn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
  groups     = []
  users      = ["${aws_iam_user.cocoa.name}"]
  roles      = []
}

+ output "cocoa_arn" {
+   value = "${aws_iam_user.cocoa.arn}"
+ }

我们来执行terraform plan和terraform apply。

% terraform apply
aws_iam_user.cocoa: Refreshing state... (ID: cocoa)
aws_s3_bucket.terraform_tutorial_tfsate: Refreshing state... (ID: com.github.53ningen.terraform.tutorial.tfstate)
aws_iam_policy_attachment.IAMReadOnlyAccess-policy-attachment: Refreshing state... (ID: IAMReadOnlyAccess-policy-attachment)

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

Outputs:

cocoa_arn = arn:aws:iam::XXXXXXXXXXXX:user/cocoa

可以确认ARN已经被正确地输出。

5. 支持模块与多个阶段的适配能力。

terraform 在当前目录中具有执行 .tf 文件的非常简单的行为。但是,由于各种原因,例如希望将文件保存在多个结构化的目录中,或者只想通过更改参数来调用以创建多个阶段等等,您可能希望调用位于不同目录下的文件。在这种情况下,可以使用模块功能。

5-1. 使用模块的基本知识

为了测试模块,首先让我们创建如下所示的目录结构。

% tree
.
├── dev
│   ├── modules.tf
│   └── variable.tf
├── modules
│   └── s3
│       └── s3.tf
└── prod
    ├── modules.tf
    └── variable.tf

我们将为每个模块定义资源。作为示例,让我们创建 dev/prod 方向的 S3 存储桶。首先从 modules/s3/s3.tf 开始。

resource "aws_s3_bucket" "tutorial_s3" {
  bucket = "${var.env}.53nigen.github.com.tutorial.s3" # S3 bucket 名は global で一意になるように
  acl    = "private"

  versioning {
    enabled = false
  }
}

variable "env" {}

接下来我们来编写代码,将 modules/s3 文件夹下的内容分别导入到 dev/modules.tf 和 prod/modules.tf 文件中。这里我们可以使用新的 modules 语法。

module "s3" {
  source = "../modules/s3"  # ここで読み込むパスを指定

  env = "${var.env}"
}

variable "env" {
  default = "dev"  # prod のほうには prod と書いてください
}

最后,我们将为dev/variable.tf和prod/variable.tf文件编写关于AWS操作的设置值等内容。

provider "aws" {
  region = "${var.region}"
  access_key = "${var.access_key}"
  secret_key = "${var.secret_key}"
}

variable "access_key" {}
variable "secret_key" {}
variable "region" {
  default = "ap-northeast-1"
}

这样就准备好了。如果从dev目录下执行,可以管理dev环境的配置;如果从prod目录下执行,可以管理prod环境的配置。现在来创建dev环境所需的资源吧。前往dev目录,执行terraform get将依赖模块的代码导入,并且基本上操作与之前相同,除了需要提前进行导入外。

% cd dev/                                                                                                     % terraform get                                                                                               
Get: file:///Users/*******/tutoterra/sample/modules/s3
% terraform plan                                                                                              Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but
will not be persisted to local or remote state storage.


The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ module.s3.aws_s3_bucket.tutorial_s3
    acceleration_status:           "<computed>"
    acl:                           "private"
    arn:                           "<computed>"
    bucket:                        "dev.53nigen.github.com.tutorial.s3"
    force_destroy:                 "false"
    hosted_zone_id:                "<computed>"
    policy:                        "<computed>"
    region:                        "<computed>"
    request_payer:                 "<computed>"
    versioning.#:                  "1"
    versioning.2972667452.enabled: "false"
    website_domain:                "<computed>"
    website_endpoint:              "<computed>"


Plan: 1 to add, 0 to change, 0 to destroy.
% terraform apply
module.s3.aws_s3_bucket.tutorial_s3: Creating...
  acceleration_status:           "" => "<computed>"
  acl:                           "" => "private"
  arn:                           "" => "<computed>"
  bucket:                        "" => "dev.53nigen.github.com.tutorial.s3"
  force_destroy:                 "" => "false"
  hosted_zone_id:                "" => "<computed>"
  policy:                        "" => "<computed>"
  region:                        "" => "<computed>"
  request_payer:                 "" => "<computed>"
  versioning.#:                  "" => "1"
  versioning.2972667452.enabled: "" => "false"
  website_domain:                "" => "<computed>"
  website_endpoint:              "" => "<computed>"
module.s3.aws_s3_bucket.tutorial_s3: Creation complete

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

The state of your infrastructure has been saved to the path
below. This state is required to modify and destroy your
infrastructure, so keep it safe. To inspect the complete state
use the `terraform show` command.

State path: terraform.tfstate

5-2. 利用模块适应多个阶段的案例

如果你想利用类似这样的模块功能来对开发、生产等多个阶段进行部署改造,没有特别固定的目录结构,但建议参考以下优秀的形式来进行操作。

    • オレオレterraformディレクトリ構成ベストプラクティス

 

    Terraformにおけるディレクトリ構造のベストプラクティス

6. 使用terraform管理现有的AWS资源

6-1. 引入地球化

terraform是一种工具,它可以访问现有的AWS资源并生成terraform代码,生成tfstate文件。要安装它,只需在Gemfile中写入以下内容,然后运行bundle install即可。

source "https://rubygems.org"

gem 'terraforming', '0.10.0'

用terraform管理现有的IAM用户。

几乎所有拥有AWS帐户的人都已经拥有了IAM用户等资源。因此,让我们首先使用terraform来管理这些资源。使用下面的方法可以输出与当前IAM用户资源对应的HCL。

% terraforming iamu --profile default
resource "aws_iam_user" "gomi_ningen" {
    name = "gomi_ningen"
    path = "/"
}

让我们将这个写入文件中。

resource "aws_iam_user" "gomi_ningen" {
    name = "gomi_ningen"
    path = "/"
}

如果不将远程状态同步到本地的 .tfstate 文件中,terraform 将会尝试创建资源。因此,请按照以下方式操作。

通过以下命令进行土地整形:iamu –tfstate –profile default –merge=.terraform/terraform.tfstate

如果通过检查输出没有问题的话,您可以在该命令中添加 “–overwrite” 选项来进行反映。然后进行 “terraform plan”,如果没有差异,那么就可以正式将 IAM 用户的管理转移到 terraform。

如果在执行”terraform plan”命令时,如果显示出将被销毁的资源,请特别谨慎操作,因为这可能导致现有的资源或系统被破坏。此外,有关IAM策略的JSON换行位置和缩进等差异容易出现,当困惑时建议检查是否与现有的策略设置有冲突。

可以考虑使用 terraforming 将现有的 AWS 资源迁移到 terraform 中,因为 terraforming 适用于多数常用的 AWS 资源。在 v0.7.0 版本中, terraforming 支持以下功能。

% terraforming help
Commands:
  terraforming asg             # AutoScaling Group
  terraforming dbpg            # Database Parameter Group
  terraforming dbsg            # Database Security Group
  terraforming dbsn            # Database Subnet Group
  terraforming ec2             # EC2
  terraforming ecc             # ElastiCache Cluster
  terraforming ecsn            # ElastiCache Subnet Group
  terraforming eip             # EIP
  terraforming elb             # ELB
  terraforming help [COMMAND]  # Describe available commands or one specific command
  terraforming iamg            # IAM Group
  terraforming iamgm           # IAM Group Membership
  terraforming iamgp           # IAM Group Policy
  terraforming iamip           # IAM Instance Profile
  terraforming iamp            # IAM Policy
  terraforming iampa           # IAM Policy Attachment
  terraforming iamr            # IAM Role
  terraforming iamrp           # IAM Role Policy
  terraforming iamu            # IAM User
  terraforming iamup           # IAM User Policy
  terraforming igw             # Internet Gateway
  terraforming lc              # Launch Configuration
  terraforming nacl            # Network ACL
  terraforming nat             # NAT Gateway
  terraforming nif             # Network Interface
  terraforming r53r            # Route53 Record
  terraforming r53z            # Route53 Hosted Zone
  terraforming rds             # RDS
  terraforming rs              # Redshift
  terraforming rt              # Route Table
  terraforming rta             # Route Table Association
  terraforming s3              # S3
  terraforming sg              # Security Group
  terraforming sn              # Subnet
  terraforming sqs             # SQS
  terraforming vgw             # VPN Gateway
  terraforming vpc             # VPC

创建一个用于管理terraform代码的存储库。

在本行的程式碼存儲庫中放置個人AWS配置會引起顧慮,所以建議事先創建CodeCommit存儲庫。

# このアカウントのAWS構成を管理するterraformコードを配置するレポジトリ
resource "aws_codecommit_repository" "my-terraform" {
  repository_name = "my-terraform"
  description = "terrform"
}

可以使用terraform来附加策略并注册公钥,以访问在code commit上创建的存储库。

#...

resource "aws_iam_policy_attachment" "my_codecommit_policy_attachment" {
  name       = "my_terraform_codecommit_policy_attachment"
  policy_arn = "arn:aws:iam::aws:policy/AWSCodeCommitPowerUser"
  groups     = []
  users      = ["${aws_iam_user.gomi_ningen.name}"]
  roles      = []
}

resource "aws_iam_user_ssh_key" "gomi_ningen" {
    username = "${aws_iam_user.gomi_ningen.name}"
    encoding = "PEM"
    public_key = <<EOF
######################
##### public_key #####
######################
EOF
}

output "aws_iam_user_ssh_key.gomi_ningen.ssh_key_id"  {
    value = "${aws_iam_user_ssh_key.gomi_ningen.ssh_public_key_id}"
}

我会在这个状态下尝试执行terraform plan和terraform apply。

% terraform apply                                                                                                                                                     aws_s3_bucket.my_terraform_tfstate: Refreshing state... (ID: com.53ningen.aws.terraform.tfstates)
aws_codecommit_repository.my-terraform: Refreshing state... (ID: my-terraform)

# 中略

Outputs:

aws_iam_user_ssh_key.gomi_ningen.ssh_key_id = XXXXXXXXXXXX

当执行此操作后,将会输出类似以上所示的 ssh_public_key_id,然后只需将其应用到 ~/.ssh/config 文件中,您就可以通过本地设备与创建的 code commit 存储库进行通信。

Host git-codecommit.*.amazonaws.com
  User XXXXXXXXXXXX
  IdentityFile ~/.ssh/id_rsa

6-4. 地形改造的导入

待定

7. 简化构成管理方法

7-1. 如果是个人开发的情况

如果要管理个人的AWS资源,大致有以下两种方法。

.tfstate ごと git で管理して、 code commit にぶちこむ

.tfstate は S3 で管理、コードは code commit で管理

7-2. 在团队开发的情况下

.tfstate はセキュリティ上の理由から S3 で管理することが望ましい

.tfstate やアクセスキーなどを含むものをコミットせず、GitHub Enterprise, code commit, GitHub private repository に push する

广告
将在 10 秒后关闭
bannerAds