使用Terraform在Mac上进行AWS构建(预备阶段至VPC创建)

首先

Terraform真的很方便,对吧。
它是一种用于通过代码管理服务器配置和设置的工具(即基础设施即代码),可以适用于AWS、GCP、Azure等各种服务。

可以通过更改设置值来一次性建立、修改和删除所需的环境,因此可以使用相同的配置创建开发环境、预演环境和生产环境,非常方便。

当我们掌握基础知识后,我们就能显著提高维护性,因此让我们先至少掌握基本知识。

只有能够使用Linux命令行的人才符合条件。
因为在每个官方网站上都提供了链接,所以对于除Mac以外的环境,请查阅相关链接。

如果你使用Windows操作系统,或许可以考虑使用WSL(Windows Subsystem for Linux)来运行Linux。 更多信息请参考:https://docs.microsoft.com/ja-jp/windows/wsl/

这次要做的事情是什么?

    • 事前準備

 

    • Terraformの初期設定

 

    VPCの作成

提前准备

发行AWS的访问密钥和秘密密钥

    • AWSのアカウント&作業用ユーザーを用意(手順は割愛します)

 

    • 作業用ユーザーに、構築に必要な権限を付与する(してもらう)

 

    • 作業用ユーザーの「認証情報>アクセスキー」からアクセスキーを発行する

 

    アクセスキー、シークレットキーをメモまたはダウンロードしておく(※シークレットキーは作成したときしか知ることはできません。必ず控えておきましょう。)

※如果在个人的AWS账户上进行操作,也建议不要使用根用户,而是创建一个工作用户。(这样可以限制权限到最小必要程度)
※如果不清楚工作用户的权限,可以给予 AdministratorAccess 管理策略。(因为它不是根用户)

安装AWS命令行界面(CLI)

$ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
$ sudo installer -pkg AWSCLIV2.pkg -target /

若需安装到其他环境或获取详细信息,请点击此处链接:
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-chap-install.html

在本地安装tfenv(Terraform管理工具)。

Terraform版本更替时可能会出现部分不兼容情况。如果是自己创建的项目没有问题,但其他人创建的项目可能版本不同。使用tfenv可以快速切换版本,非常便利,我们将使用它进行工作。

$ brew install tfenv

关于在其他环境中的安装和详细信息,请点击这里
https://github.com/tfutils/tfenv

安装Terraform

$ tfenv install latest
Installing Terraform v0.15.4
Downloading release tarball from https://releases.hashicorp.com/terraform/0.15.4/terraform_0.15.4_darwin_amd64.zip
######################################################################## 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.15.4/terraform_0.15.4_SHA256SUMS
==> Downloading https://ghcr.io/v2/homebrew/core/pcre/manifests/8.44
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/pcre/blobs/sha256:ed9b483538da7bc6559d2e63dd36659736fab9510681661d970d707a18731de4
〜中略〜
All commands have been installed with the prefix "g".
If you need to use these commands with their normal names, you
can add a "gnubin" directory to your PATH from your bashrc like:
  PATH="/usr/local/opt/grep/libexec/gnubin:$PATH"
No keybase install found, skipping OpenPGP signature verification
Archive:  tfenv_download.xfh6sb/terraform_0.15.4_darwin_amd64.zip
  inflating: /usr/local/Cellar/tfenv/2.2.2/versions/0.15.4/terraform  
Installation of terraform v0.15.4 successful. To make this your default version, run 'tfenv use 0.15.4'

当你想要指定安装版本时,请在install之后写上版本,如下所示。

$ tfenv install 0.12.6
Installing Terraform v0.12.6
Downloading release tarball from https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_darwin_amd64.zip
######################################################################## 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
Archive:  tfenv_download.Y85qVG/terraform_0.12.6_darwin_amd64.zip
  inflating: /usr/local/Cellar/tfenv/2.2.2/versions/0.12.6/terraform  
Installation of terraform v0.12.6 successful. To make this your default version, run 'tfenv use 0.12.6'

为了指定使用的版本,需要检查已安装的版本。

$ tfenv list
  0.15.4
  0.12.6
No default set. Set with 'tfenv use <version>'

请使用版本0.15.4,通过使用指令来指定。

$ tfenv use 0.15.4
Switching default version to v0.15.4
Switching completed

$ tfenv list
* 0.15.4 (set by /usr/local/Cellar/tfenv/2.2.2/version)
  0.12.6

设置aws的凭证

请与您使用的AWS帐户所在地域相匹配的地域进行选择。 在此示例中,我们假设选择“亚太地区(东京)”,其标识为“ap-northeast-1”。

$ aws configure
AWS Access Key ID [None]: AAAAAAAAAAAAAAAAAAA
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
$ cat ~/.aws/credentials
[default]
aws_access_key_id = AAAAAAAAAAAAAAAAAAA
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

在实际开发中,由于经常需要在开发环境、生产环境等进行AWS账户分离,我们会设置不同的配置文件以便于切换。(在使用Terraform切换环境时是必需的)

$ aws configure --profile dev-user
AWS Access Key ID [None]: BBBBBBBBBBBBBBBBBBB
AWS Secret Access Key [None]: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
Default region name [None]: ap-northeast-1
Default output format [None]: json
$ cat ~/.aws/credentials
[default]
aws_access_key_id = AAAAAAAAAAAAAAAAAAA
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

[dev-user]
aws_access_key_id = BBBBBBBBBBBBBBBBBBB
aws_secret_access_key = YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

准备工作场所

为了使本地环境整洁,我会预先创建一个工作目录(文件夹名字任意)。

$ mkdir -p ~/work/dev-test-terraform
$ cd ~/work/dev-test-terraform

※ 使用-p选项在mkdir命令中,能够批量创建目录。

请把tfstate文件放在S3中准备好。

tfstate是一个文件,其中包含了使用Terraform构建的信息。
虽然可以只将其放在本地而不放在S3中,但最好从一开始就将其放在S3中,这样可以大大提高方便性。考虑到多人共同操作或工作电脑损坏的情况,建议从一开始就将其放在S3中。

$ aws s3 mb --profile dev-user s3://xxxxxxxx-dev-terraform-tfstate
make_bucket: xxxxxxxx-dev-terraform-tfstate

※S3桶的名称需要在全球范围内是唯一的。如果已经有人使用了这个名称,您将无法进行设置,请正确修改xxxxxxxx部分。

这次我使用AWS CLI创建了S3存储桶。
由于AWS CLI非常方便,一旦掌握了它,开发工作将变得轻松。

【参考】AWS CLI中的S3命令
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli-services-s3-commands.html

在这里,事前准备已经完成。

那么,让我们尝试使用Terraform来构建一个VPC。

使用Terraform进行构建

目录结构

首先,从完成的形象开始。
该目录的形象如下所示。

$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'
/Users/xxxxxxx/work/dev-test-terraform
|--backend.tf
|--dev.tfvars
|--main.tf
|--modules
|  |--vpc
|  |  |--main.tf
|  |  |--output.tf
|  |  |--variables.tf
|--provider.tf

(顺便说一句)如果使用以下命令,即使没有tree命令,也可以模拟显示树形结构,非常方便。

$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|--\1/;s/\/[^/|]*/|  /g'

准备.tf文件

按照完成的形象,准备每个.tf文件。

主.tf

请使用source指定.tf文件的位置。
根据目录结构,此次将指定为”./module/vpc”。
还请在此处设置其他必要的变量。
(例如var.env的变量设置将在之后进行)。

module "vpc" {
  source      = "./modules/vpc"
  env         = var.env
  vpc_cidr    = var.vpc_cidr
  app_name    = "test-application"
}

如果要增加其他资源(例如EC2,RDB,Lambda,API Gateway等),同样也需要增加相应的模块。

provider.tf
提供者.tf

在Terraform中,我们需要指定要使用的提供商(如AWS,GCP,Azure,Datadog等)。
由于我们要进行AWS的构建,因此我们将指定为“aws”。
默认情况下,“shared_credentials_file”的值是这个,所以如果您有单独的包含AWS认证信息的文件,请设置该文件的路径。
另外,我们将从credentials中读取通过“profile”指定的值(本次我们将使用预先设置的“dev-user”)。

provider "aws" {
  region = var.region
  profile = var.profile
  shared_credentials_file = "~/.aws/credentials"
}

后端.tf

在这个文件中,我们设置了要使用的Terraform版本以及.tfstate文件的位置。
正如前面所述,Terraform的语法在不同版本下可能会有所不同。为了避免因版本导致的语法错误,我们需要固定版本。(本次使用的是0.15.4)

terraform {
  required_version    = "0.15.4"

  backend "s3" {
    region  = "ap-northeast-1"
    bucket  = "xxxxxxxx-dev-terraform-tfstate"
    key     = "terraform/aws.tfstate"
  }
}

设定项目.tfvars

可以指定每个环境的配置。
还可以创建其他文件,如 stg.tfvars、prd.tfvars,以设置暂存环境和生产环境的值。

请将.tf文件和.tfvars文件创建为可以推送到Git或与他人共享的文件。
将AWS的认证信息和DB的密码等机密信息设置为环境变量,在构建时使用命令传递环境变量,以更安全地进行操作。

env      = "dev"
region   = "ap-northeast-1"
profile  = "dev-user"
vpc_cidr = "172.31.0.0/16"

VPC的CIDR范围推荐使用以下之一,请指定其中一个值:
– 10.0.0.0/16
– 172.31.0.0/16
– 192.168.0.0/20
详细信息请参考:
https://docs.aws.amazon.com/zh_cn/vpc/latest/userguide/VPC_Subnets.html

模块/虚拟私有云/主要文件.tf

设置用于构建VPC的资源。
使用lower()函数可以将所有字符转换为小写,非常方便。

#####################################
# VPC Settings
#####################################
resource "aws_vpc" "vpc" {
    cidr_block           = var.vpc_cidr
    enable_dns_hostnames = true

    tags = {
        Name    = lower("${var.env}-${var.app_name}-vpc")
        project = var.app_name
    }
}

模块/虚拟私有云/变量.tf

在这里,我们将设置在模块内(vpc/main.tf)中使用的变量。您可以直接写入值,但在这里,我们将值保持为空,并从dev.tfvars中接收main.tf的设置值。

variable "env" {}
variable "app_name" {}
variable "vpc_cidr" {}

模块/虚拟私有云/output.tf

可以输出已经设置好的值,并且可以在其他模块中使用。
这个文件可以为空,但是这次我们将尝试输出VPC的ID。

output "vpc_id" {
  value = aws_vpc.vpc.id
}

建立VPC

那么,让我们用Terraform构建VPC。
首先执行初始化命令,准备搭建AWS环境。

terraform初始化命令

执行「terraform init」。

$ terraform init
Initializing modules...
- dev-test in modules/vpc

Initializing the backend...

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

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.47.0...
- Installed hashicorp/aws v3.47.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

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.

通过这个过程,会安装所需的库,并创建一个.tfstate文件来管理状态。
我建议你实际去查看每个文件的内容。

/Users/xxxxxxx/work/dev-test-terraform
|--.terraform.lock.hcl
|--.terraform
|  |--modules
|  |  |--modules.json
|  |--providers
|  |  |--registry.terraform.io
|  |  |  |--hashicorp
|  |  |  |  |--aws
|  |  |  |  |  |--3.47.0
|  |  |  |  |  |  |--darwin_amd64
|  |  |  |  |  |  |  |--terraform-provider-aws_v3.47.0_x5
|  |--terraform.tfstate

创建Workspace

我已经根据上述内容创建了配置文件”dev.tfvars”。
由于Terraform使用了名为Workspace的功能,可以单独管理配置文件(.tfstate),因此我将创建一个名为”dev”的工作区。

$ terraform workspace new dev
Created and switched to workspace "dev"!

You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.

执行此命令将在S3上创建以下文件。

xxxxxxxx-dev-terraform-tfstate.s3.ap-northeast-1.amazonaws.com / env: / dev / terraform / dev-aws.tfstate

接下来,我们将确认工作空间。

$ terraform workspace list
  default
* dev

如果已经选择了dev,请执行以下命令,如果选择了不同的Workspace。

$ terraform workspace select dev

只要再次使用”terraform workspace list”命令来确认一下,如果没有任何输出,那就没有问题。

执行terraform plan命令

由于Terraform的执行环境已准备好,接下来我们将尝试执行”terraform plan”命令。
这个命令可以在实际应用之前,查看执行计划。

如果在语法上有错误之类的情况,将在这里报错。
那么,会顺利进行吗?

$ terraform plan -var-file=dev.tfvars

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.dev-test.aws_vpc.vpc will be created
  + resource "aws_vpc" "vpc" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "172.31.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = (known after apply)
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = true
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name"    = "dev-test-application-vpc"
          + "project" = "test-application"
        }
      + tags_all                         = {
          + "Name"    = "dev-test-application-vpc"
          + "project" = "test-application"
        }
    }

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

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

毫麻煩,顯示了創建VPC的內容對吧。那麼接下來,我們要開始將其實際應用到AWS上並構建起來。

执行terraform apply命令

先前只是确认了执行计划,但这次确认后,会用”是”来批准。

$ terraform apply -var-file=dev.tfvars

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.dev-test.aws_vpc.vpc will be created
  + resource "aws_vpc" "vpc" {
      + arn                              = (known after apply)
      + assign_generated_ipv6_cidr_block = false
      + cidr_block                       = "172.31.0.0/16"
      + default_network_acl_id           = (known after apply)
      + default_route_table_id           = (known after apply)
      + default_security_group_id        = (known after apply)
      + dhcp_options_id                  = (known after apply)
      + enable_classiclink               = (known after apply)
      + enable_classiclink_dns_support   = (known after apply)
      + enable_dns_hostnames             = true
      + enable_dns_support               = true
      + id                               = (known after apply)
      + instance_tenancy                 = "default"
      + ipv6_association_id              = (known after apply)
      + ipv6_cidr_block                  = (known after apply)
      + main_route_table_id              = (known after apply)
      + owner_id                         = (known after apply)
      + tags                             = {
          + "Name"    = "dev-test-application-vpc"
          + "project" = "test-application"
        }
      + tags_all                         = {
          + "Name"    = "dev-test-application-vpc"
          + "project" = "test-application"
        }
    }

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

Do you want to perform these actions in workspace "dev"?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

module.dev-test.aws_vpc.vpc: Creating...
module.dev-test.aws_vpc.vpc: Still creating... [10s elapsed]
module.dev-test.aws_vpc.vpc: Creation complete after 12s [id=vpc-0308ce2f14a10adfd]

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

看起来terraform apply成功了。
我们可以在控制台页面上确认VPC是否已创建。

スクリーンショット 2021-07-04 10.11.52.png

VPC已经创建成功了!

这次就结束了,大家都能创建好 VPC 了吗?

只要理解了这部分内容,就可以应用到其他资源中,所以我打算逐步添加。

最后

本次我们进行了关于使用Terraform构建AWS的准备工作,并完成了从准备到创建VPC的步骤。
为了更直观易懂,我直接写出了命令,但一旦熟悉了,也可以使用Shell等方式,通过执行环境特定的脚本来进行构建。

下次我们会使用API网关和Lambda构建一个无服务器环境。

广告
将在 10 秒后关闭
bannerAds