使用[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本身以及负载均衡器。
请务必尝试并充分利用。