使用[Terraform]工具,用代码一键构建AWS的EC2实例!

这次我们将介绍Terraform。

Terraform是HashiCorp公司开发的开源软件。(也有商业付费版本可用。)

只需在代码中编写并执行,即可在云上(如AWS和GCP)搭建服务器等工作。起初可能会有些困难,但一旦习惯,将会有以下优点:

    • AWSコンソールをいちいちポチポチしなくても環境構築ができるようになる。

 

    • コピーしてちょっといじれば他のケースにも流用できる。

 

    • Gitなどのソース管理ソフトが使えるので、

更新履歴が取れる。
万が一のとき前のバージョンにすぐ戻せる。
複数人で開発作業ができるetc…

需要用HCL语言编写,但并不难。

让我们尝试使用Terraform来构建AWS的EC2实例吧。

抱歉备注

文章中出现的固有ID值都是虚拟的。
请根据您自己的环境来进行解释或者调整。

需要的东西

Terraform版本为0.12.XX。

请放心,本文将介绍安装方法。
顺便提一下,本文是使用以下版本撰写的。

$ terraform --version
Terraform v0.12.26
+ provider.aws v2.68.0

AWS相关 (AWS

AWS账户。

当然,请准备好。
只要是类似本文章的操作,完全可以在免费的范围内完成。
(但是,请注意AWS会员注册需要信用卡。)

AWS的初始设置。

新推文> AWS账户注册后需要立即进行的初始设置总结

理解AWS的基本功能包括VPC、子网、IAM、EC2、AMI和安全组。

推荐文章:从零开始学习AWS入门:概览

一个具有从程序中创建EC2实例权限的IAM用户。

请准备好该IAM用户的访问密钥和秘密密钥。

详细来说

    • プログラムからAWSを操作することを許可されている。

 

    • 必要なポリシー(できれば最低限必要なものだけに絞る)を付与している。

こちらを参考にさせて頂きました > IAMポリシーによるEC2インスタンス操作制限(ちょっと試すだけなら管理者権限で実施しても良いですが、後始末は重々ご注意を。)

策略设置示例

除了在AWS控制台上点击来设置策略外,您还可以通过JSON格式进行设置。我们确认已经使用了此策略设置进行了本文档所需的操作。虽然不是完美的,但权限已经相当严格了。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "ec2:RevokeSecurityGroupIngress",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupEgress",
                "ec2:DeleteSecurityGroup"
            ],
            "Resource": "arn:aws:ec2:*:*:security-group/*"
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": [
                "arn:aws:ec2:*::image/ami-*",
                "arn:aws:ec2:*:*:subnet/*",
                "arn:aws:ec2:*:*:key-pair/*",
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ec2:*:*:volume/*",
                "arn:aws:ec2:*:*:security-group/*",
                "arn:aws:ec2:*:*:network-interface/*"
            ]
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "iam:PassRole",
                "iam:Get*",
                "iam:List*",
                "ec2:GetConsole*",
                "ec2:ImportKeyPair",
                "ec2:CreateKeyPair",
                "ec2:CreateSecurityGroup",
                "ec2:DeleteKeyPair"
            ],
            "Resource": "*"
        }
    ]
}

进行终端操作

    • Mac

 

    Linux

本文介绍了如何在上述操作系统的命令界面中使用名为tfenv的工具来使用Terraform的方法。

如果只使用Terraform核心部分,这是下载页面。

https://www.terraform.io/downloads.html 的下载页面

我认为,使用此方法,几乎所有在页面上列出的操作系统终端设备都可以使用。

我们正在谈论Terraform,突然出现了tfenv!?

tfenv是一个工具,用于管理Terraform的多个版本,并且可以通过它来调用所需的Terraform版本。

使用此链接可以访问tfenv的Github页面:https://github.com/tfutils/tfenv

如果升级了Terraform版本,即使是相同的代码也可能无法正常运行…
如果发生这样的情况,您可能会感到很慌张。
这个工具可以避免这种问题发生。
因为很方便,所以我们将在使用tfenv的前提下继续进行。

tfenv安装教程

在Mac方面

安装Homebrew命令(brew)

Homebrew是一款非常方便的工具,可以通过命令操作在Mac上安装软件,非常有名。
如果您还没有安装Homebrew,为了执行本文中的步骤,我推荐您先安装它,可以在这篇文章中找到安装指南。

安装 Homebrew

在安装tfenv之前。

如果您已经单独安装了Terraform,请执行以下命令。

安装tfenv

# もしすでにTerraformが入っていて tfenv install がコケたら、これをする。
brew unlink terraform 

再次改写一下:若要在Mac上安装tfenv,只需执行以下命令即可。

brew install tfenv

如果是关于Linux的情况

如果使用 Linux 的话,可以直接从 GitHub 上获取 tfenv 的全部内容。

只要您将/bin目录中已构建好的tfenv命令文件添加到tfenv的bin目录中,并将其添加到系统的PATH环境变量中,无论从哪里,都可以使用tfenv命令进行安装。

git clone https://github.com/tfutils/tfenv ~/.tfenv
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile

使用tfenv安装Terraform。

首先,让我们尝试获取Terraform的版本列表。

可以用下面的命令来完成。

tfenv list-remote

安装Terraform

既然已经查到了版本清单,那就直接按照latest (“请安装最新的正式版本”)的指定进行安装吧。

tfenv install latest

事先指定所需使用的Terraform版本。

安装后只是不够的,也别忘了这一点。
这正是tfenv可以处理多个版本Terraform的独特之处呢。

tfenv use latest

实践篇

建立工作目录

在Terraform中,通常一个项目对应一个目录。因此,我们需要创建一个目录。

mkdir hogehoge

然后,让我们进入目录里面吧。

cd hogehoge

创建AWS访问信息文件。

首先,如果没有给予Terraform AWS访问信息,它将无法执行任何操作。所以,让我们开始吧。

使用诸如vi等文本编辑器,以terraform.tfvars为文件名开始编辑。(一旦命名为此,系统会自动加载该文件。)

vi terraform.tfvars

关于内部情况,

access_key_sample = "AKAOFUOAE92AFHGHESY" //←ご自分のAWSアクセスキーに書き換えてね
secret_key_sample = "RHaZsoghSOGH93ShlgihhrilirsrurhEzg+" //←ご自分のAWSシークレットキーに書き換えてね
region_sample = "ap-northeast-1" //←日本国外でご利用なら、お好みで書き換えてね

大致就是这样。(顺便提一下,上面的按钮只是个虚拟的占位符。)

注:在HCL编程语言中,如何编写注释。

当您采用这种写法,Terraform将会忽略它。

# #の後に何を書いても無効

// //の後に何を書いても無効

/*
/*(半角)と */(半角)のあいだに何を書いても無効(複数行もOK)
/*(半角)と */(半角)のあいだに何を書いても無効(複数行もOK)
/*(半角)と */(半角)のあいだに何を書いても無効(複数行もOK)
*/

让我们用它来记下备忘录。

事先创建用于SSH连接的密钥文件。

EC2实例启动后,请先创建必要的密钥文件以进行SSH连接。如果没有这个文件,那么即使成功创建了EC2实例,也无法进行关键的连接。

我想有一些人已经了解,但为了谨慎起见,我还是将命令示例写在下方:

ssh-keygen -t rsa -b 4096 -C "foo@example.com" -f aws_key_pair_example

当执行时,会有大约两个英语问题出现,但这次只是个例子,所以只需按下回车即可。这样就会生成以下两个文件。

    • aws_key_pair_example ←秘密鍵ファイル。

 

    aws_key_pair_example.pub ←公開鍵ファイル。

您可以在AWS控制台的“密钥对”页面进行创建,但本次我们将使用通过命令创建的方法进行说明。

写源代码的主体

接下来,我们就开始编写Terraform代码。

让我们使用文本编辑器等工具,以 main.tf 作为文件名编写代码。(如果将文件扩展名设置为 .tf,Terraform将会将其识别为执行对象。)

vi main.tf

以下是代码的内容。
您需要根据您自己的环境在其中更改两个位置。
// 在代码中有标记★,请尝试搜索代码内部。


//terraform.tfvars に書いたアクセスキーなどを格納する変数を宣言しています。
variable access_key_sample {}
variable secret_key_sample {}
variable region_sample {}

/*
この宣言により、AWS操作を実行する際のアクセスキーなどを
自動的に参照してくれるようになります。
*/
provider "aws" {
  access_key = var.access_key_sample
  secret_key = var.secret_key_sample
  region     = var.region_sample
}

/*
 Amazon公式AMIのAmazon Linux2の最新版を取得するための条件を宣言しています。
*/
data "aws_ami" "al2_latest" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "architecture"
    values = ["x86_64"]
  }
  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
  filter {
    name   = "block-device-mapping.volume-type"
    values = ["gp2"]
  }
  filter {
    name   = "state"
    values = ["available"]
  }
}

/*
  SSH鍵ファイルの"公開鍵"の方を指定します。
  秘密鍵の方を指定してしまわないようご注意!
*/
resource "aws_key_pair" "example" {
  key_name   = "example"
  public_key = file("aws_key_pair_example.pub")
}

//新たにセキュリティグループを作成するための宣言です。
resource "aws_security_group" "example" {
  name = "example"
  vpc_id = "vpc-hoge2222222" //★ご自分のVPCのIDを入力してください。
}

/*
  上で宣言した "example"セキュリティグループにインバウンドルールを追加します。
  ポート:22でSSH接続をどこのIPからでも許可するよう設定します。
  (本来はIP制限をかけた方がセキュリティ上良いですが、今回は例なので良しとしましょう。)
  これがないと、SSH接続がAWSのファイアウォールにブロックされてしまいます。
*/
resource "aws_security_group_rule" "example_sg_inbound" {
  type = "ingress" //インバウンドルールである。
  from_port = "22" //接続元(=皆さんの端末)から発信する際のポート番号。
  to_port = "22" //接続先(=EC2インスタンス側)で待ち受けるポート番号。
  protocol = "tcp" //TCPプロトコル通信である。
  cidr_blocks = ["0.0.0.0/0"] //どこのIPからでも接続を許可する。
  security_group_id = aws_security_group.example.id
}

//ここから、実際にEC2インスタンスを構築する設定が書かれています。
resource "aws_instance" "example" {

  /* 【必須】
   ベースにしたいAMIのIDを指定します。
   ここでは、上の方で宣言しておいた「最新のAmazon Linux2」という設定を動的に指定しています。
  */
  ami = data.aws_ami.al2_latest.image_id

  /* 【必須】
   インスタンスタイプを指定します。
   今回は、一番安くて低スペックな t2.micro にしましょう。
  */
  instance_type = "t2.micro"

  /*
    EC2インスタンスに適用するセキュリティグループをIDで指定します。
    カンマ区切りで複数指定もできます。
    今回は、上の方で宣言した "example"セキュリティグループ のIDを指定しておきます。
  */
  security_groups = [ aws_security_group.example.id ]

  /*
    構築先のネットワークのサブネットをお好みで指定できます。
    省略するとデフォルトサブネットが適用されます。
    ただしセキュリティグループの作成もTerraformで行う場合は、指定しないとエラーになります。
  */
  subnet_id = "subnet-hoge2222222" //★ご自分のVPCに紐づくサブネットのIDを入力してください。

  //上の方で作ったキーペア設定のIDを動的に指定しています。
  key_name = aws_key_pair.example.id

  /*
   プライベートIPをお好みで指定することもできます。
   (サブネットルールに従わないIPや、すでに使われているIPを指定したらエラー)
  */
//  private_ip = "172.31.0.1"

  //パブリックIPもお好みで指定可能。(こちらも、ルールに合わないIPを指定したらエラー)
//  public_ip = "xxx.xxx.xxx.xxx"

  //ここでは、ルートディスクの容量やタイプを指定できます。
  root_block_device {
    volume_size           = "20"   //容量:20GiB
    volume_type           = "gp2"  //タイプ:gp2
    delete_on_termination = "true" //EC2インスタンスを破棄するとき、このディスクも一緒に破棄する:YES

    //...今回書いた以外にも、色々オプションがあります。
  }
}

执行。

初始化目录

由于Terraform的需求,只需在Terraform工作目录的最顶层执行以下命令一次即可,因此需要进行一些准备工作。

terraform init

查看执行计划

请尝试执行以下命令。

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.

data.aws_ami.al2_latest: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                          = "ami-hogehogehoge22222"
      + arn                          = (known after apply)
      + associate_public_ip_address  = (known after apply)
      + availability_zone            = (known after apply)
      + cpu_core_count               = (known after apply)
      + cpu_threads_per_core         = (known after apply)
      + get_password_data            = false
...
...
...

如果执行这个操作,会发生这样的情况。因为这次没有详细指定,所以大部分项目会在应用后被知晓。

进行实际执行

请执行这个命令。

terraform apply

在这种情况下,会弹出一个询问:“确定要执行吗?”请键入“是”并按下回车键。

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

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

  Enter a value:     ←ここに yes と打ち込む!

那样一来,一连串的命令日志就会滚动显示出来…

aws_key_pair.example: Creating...
aws_key_pair.example: Creation complete after 0s [id=example]
aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Creation complete after 23s [id=i-hogehogehoge]

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

如果能以这样的方式收尾,那就算是成功了!

确定当前的情况

你可以使用下面的命令来确认当前的情况。

terraform show

用这个方法,您也可以查找到被拒绝的IP地址。(虽然它也会显示在terraform apply的结果中。)

使用SSH进行连接并查看

请顺便尝试一下实际连接到EC2实例。

ssh -l ec2-user -i ./aws_key_pair_example XXX.XXX.XXX.XXX

请使用刚才确认的IP地址来设置连接IP。

摧毁创建的EC2实例

这次我们来尝试输入下面的命令吧。

terraform destroy

执行废弃操作后,会出现一系列信息显示:“一旦执行废弃,就会变成这样。”最后会询问:“确定要执行废弃吗?”此时输入“是”并按下回车键。

...
...
...
      - tags        = {} -> null
    }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value:     ←ここに yes と打ち込む!

这样一来,命令日志会滚滚地流动…

...
...
...
aws_instance.example: Still destroying... [id=i-hogehogehoge, 30s elapsed]
aws_instance.example: Destruction complete after 35s
aws_key_pair.example: Destroying... [id=example]
aws_key_pair.example: Destruction complete after 0s

Destroy complete! Resources: 4 destroyed.

当显示出“销毁完成!”时,表示成功!

请在AWS控制台的EC2界面上确认实例已被销毁。另外,还可以使用Terraform删除由其创建的其他资源(例如安全组、密钥对等)。

后记

请问您使用如何呢?
除了Terraform外,我们还可以创建VPC本身以及负载均衡器。
请务必尝试并充分利用。

bannerAds