使用Terraform创建AWS的EC2实例
按照标题所描述的,我们将使用terraform来启动一个EC2实例,并进行最基本的配置。
这篇文章适合那些没有任何接触过terraform或AWS的人阅读。
结构界
Terraform是一种工具,用于安全、高效地构建、更改和版本管理基础设施。Terraform可以管理现有的服务提供商和自定义的内部解决方案。
除了AWS,还支持Google Cloud和Heroku等多种提供商。这次我们打算使用Terraform,在代码中编写最基本的EC2实例配置,并通过Terraform命令来实际启动它。
基础设施即代码
通过编写代码来管理基础架构的配置和自动化是一个概念。
通过版本控制和持续集成等方式,实现基础架构构建的运作方式与软件开发类似。
由于有这样的概念,我明白了像terraform这样通过代码编写配置的做法是很好的。
首先安装Terraform。
$ brew install terraform
如果是MacOS Sierra,可能会出现错误。(在第一次执行brew install时发生了错误。)
只需卸载homebrew,然后重新安装即可解决。
% ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
% ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
“我与AMI”
在启动EC2实例之前,这是必须要做的事情。
我是
要从外部访问AWS,必须使用名为IAM(身份和访问管理)的服务。在AWS环境中,管理外部访问S3或RDS等各个服务的权限的是IAM服务,而不是各个服务本身。详细信息请参考http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/introduction.html。
AWS身份和访问管理(IAM)是一种用于安全控制用户在AWS上访问的机制,IAM本身的使用是没有费用的。通过IAM,您可以对哪些用户可以访问您的AWS资源(身份验证),以及这些用户可以以什么方式访问哪些资源(授权)进行控制。
通过创建IAM用户来获取访问密钥和秘密密钥。在控制台右上方的登录用户名处,选择“安全凭证”选项。通过在这里创建用户可以获取访问密钥和秘密密钥。
可以再次确认访问密钥,但无法确认密钥。因此,必须将其妥善保存在安全的地方,否则需要重新创建。
另外,用户具有权限。如果创建没有权限的用户,则无论在terraform中执行哪个命令都会导致错误。因此,我们会选择从现有的管理策略副本中选择AmazonEC2FullAccess。
AMI 可以将人类的语音转化为机器语言。
亚马逊机器镜像(AMI)提供了启动云虚拟服务器实例所需的信息。在启动实例时需要指定所使用的AMI。
即使不需要自己创建,AMI也有Amazon提供的公共镜像可用。
在EC2控制台上,我们将获取公共镜像的ID。
在导航栏(类似于控制台左侧的侧边栏)中的AMI图像中可以找到。
此次我们将使用”ami-f80e0596″。
写代码
让我们首先创建一个适用于Terraform的目录。
在该目录中,创建两个文件:ec2.tf和terraform.tfvars。
对于文件的结构,我认为有很多种方法,但我认为在对Terraform有了更深入的了解后,考虑什么样的文件结构是好的会更有益。
ec2.tf的含义是什么?
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "aws_region" {
default = "ap-northeast-1"
}
variable "aws_zone" {
default = "ap-northeast-1c"
}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.aws_region}"
}
resource "aws_instance" "web1" {
ami = "ami-f80e0596"
instance_type = "t2.micro"
monitoring = true
tags {
Name = "web1"
}
}
将aws_access_key等作为变量使用,并在terraform.tfvars中进行记录。
region的ap-northeast-1代表东京。
另外,根据instance_type的不同,费用也会有所变化。因为有t2.micro的一年免费计划,所以建议选择t2.micro作为免费计划的实例类型。
然而,请确认当前免费计划的相关信息,因为可能会有变更。
您可以通过以下链接从aws确认相关信息:
https://aws.amazon.com/jp/free/
terraform.tfvars可以被理解为”地球形态.tfvars”。
aws_access_key = "ACCESS_KEY_HERE"
aws_secret_key = "SECRET_ACCESS_KEY_HERE"
在terraform.tfvars文件中添加刚刚获取的访问密钥和密钥,然后启动。
在执行terraform命令时,将读取这个文件。
如果不进行此设置,每次都会要求输入访问密钥和秘密密钥(如果将其硬编码在ec2.tf中则不会出现)。
var.aws_access_key
Enter a value:
var.aws_secret_key
Enter a value:
我在Github上看到一篇关于有人不慎上传了Access Key和Secret Key,结果收到了约60万日元的账单的文章,请大家注意保管这些信息。
如果你要将terraform上传到GitHub进行管理,那么你应该创建一个.gitignore文件。
让我们尝试使用Terraform进行确认
这次我会介绍五个命令。
1. terraform init
初期化
2. terraform plan
dry run
3. terraform apply
AWS上にリソースを作成
4. terraform show
今の状態を表示。
5. terraform destroy
リソース一式を削除
进行terraform初始化
如果不先运行 terraform init,则会出现错误,要求进行插件初始化。
$ terraform plan
Plugin reinitialization required. Please run "terraform init".
Reason: Could not satisfy plugin requirements.
Plugins are external binaries that Terraform uses to access and manipulate
resources. The configuration provided requires plugins which can't be located,
don't satisfy the version constraints, or are otherwise incompatible.
首先,我们要先来初始化。
$ terraform init
terraform 计划
你可以使用 Terraform plan 来检查语法是否正确,参数是否正确等,如果没有问题,则会显示执行计划。
你可以了解将以什么配置进行执行,并在计划的最后看到添加、更改、删除操作的数量,从而可以确认是否发生了意外更改。
在这个版本中,+符号表示了新加入的内容。在这种情况下,即为+ aws_instance.web1的部分。
在底部还会显示整体的添加和更改数量,但由于我们只打算创建一个实例,所以看起来没有问题。
Plan: 1 to add, 0 to change, 0 to destroy.
$ terraform plan
+ aws_instance.web1
ami: "ami-f80e0596"
associate_public_ip_address: "<computed>"
availability_zone: "<computed>"
ebs_block_device.#: "<computed>"
ephemeral_block_device.#: "<computed>"
instance_state: "<computed>"
instance_type: "t2.micro"
key_name: "<computed>"
monitoring: "true"
network_interface_id: "<computed>"
placement_group: "<computed>"
private_dns: "<computed>"
private_ip: "<computed>"
public_dns: "<computed>"
public_ip: "<computed>"
root_block_device.#: "<computed>"
security_groups.#: "<computed>"
source_dest_check: "true"
subnet_id: "<computed>"
tags.%: "1"
tags.Name: "web1"
tenancy: "<computed>"
vpc_security_group_ids.#: "<computed>"
Plan: 1 to add, 0 to change, 0 to destroy.
执行terraform应用
当你看到“Apply complete!”的提示时,你可以确认AWS控制台是否已经成功启动。此外,与plan命令一样,在最后会显示添加、更改和删除项目的数量,因此你可以确认没有发生意外的更改。
$ terraform apply
aws_instance.web1: Creating...
ami: "" => "ami-f80e0596"
associate_public_ip_address: "" => "<computed>"
availability_zone: "" => "<computed>"
ebs_block_device.#: "" => "<computed>"
ephemeral_block_device.#: "" => "<computed>"
instance_state: "" => "<computed>"
instance_type: "" => "t2.micro"
key_name: "" => "<computed>"
monitoring: "" => "true"
network_interface_id: "" => "<computed>"
placement_group: "" => "<computed>"
private_dns: "" => "<computed>"
private_ip: "" => "<computed>"
public_dns: "" => "<computed>"
public_ip: "" => "<computed>"
root_block_device.#: "" => "<computed>"
security_groups.#: "" => "<computed>"
source_dest_check: "" => "true"
subnet_id: "" => "<computed>"
tags.%: "" => "1"
tags.Name: "" => "web1"
tenancy: "" => "<computed>"
vpc_security_group_ids.#: "" => "<computed>"
aws_instance.web1: Still creating... (10s elapsed)
aws_instance.web1: Creation complete
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
但请注意,即使在执行计划中没有错误,执行apply时也可能会发生错误。
例如,如果在IAM中创建的用户没有权限。
计划不会执行,所以即使没有权限,它也会告诉您会出现什么情况,但是一旦执行apply,如果没有权限,将会发生以下错误。
在这种情况下,请检查IAM用户的权限。
$ terraform apply
Error applying plan:
1 error(s) occurred:
* aws_instance.web1: Error launching source instance: UnauthorizedOperation: You are not authorized to perform this operation. Encoded authorization failure message: ~
展示 terraform
您可以使用以下命令来显示当前状态。
$ terraform show
aws_instance.web1:
id = i-0aa958d0237y1ee90
ami = ami-f80e0596
associate_public_ip_address = true
availability_zone = ap-northeast-1a
(長いので省略)
销毁托管云
如果它是不必要的,因为这只是一个试验,我们可以使用这个命令删除它。
我们这次省略了,但是您可以使用terraform plan -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_instance.web1: Refreshing state... (ID: i-0aa958d0237y1ee90)
aws_instance.web1: Destroying...
aws_instance.web1: Still destroying... (10s elapsed)
aws_instance.web1: Still destroying... (20s elapsed)
aws_instance.web1: Still destroying... (30s elapsed)
aws_instance.web1: Still destroying... (40s elapsed)
aws_instance.web1: Still destroying... (50s elapsed)
aws_instance.web1: Destruction complete
Destroy complete! Resources: 1 destroyed.
如果能做到这一点
触碰了这么多terraform之后,我总结了我认为下一步可以做的事情。
参考ドキュメントを使用して、他のリソースを作成します。
使用Terraform构建AWS的方法详细说明在官方文档中。
https://www.terraform.io/docs/providers/aws/index.html
如果你想要创建一个VPC,可以在Data Source: aws_vpc的页面上找到示例。
若要创建VPC,请参考Data Source: aws_vpc页面上的示例。
resource "aws_vpc" "vpc-main" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags {
Name = "vpc-main"
}
}
resource "aws_subnet" "example" {
vpc_id = "${aws_vpc.vpc-main.id}" // 作成したvpcはこのように指定できる
cidr_block = "10.0.0.0/24"
availability_zone = "ap-northeast-1a"
map_public_ip_on_launch = true
tags {
Name = "example"
}
}
如果在目录结构上感到困惑,我认为可以参考Terraform中的最佳实践来进行操作。
地球工程化
通过使用 terraforming,您可以将现有的基础架构环境放置在 terraform 的管理下,适用于已经使用 AWS 的用户(在存储库中有使用指南)。现有的基础架构环境可以以 terraform 的格式输出,这样即使您不知道如何编写,也可以使用它。
$ terraforming ec2
resource "aws_instance" "sitename_web1" {
ami = "ami-374db956"
availability_zone = "ap-northeast-1a"
ebs_optimized = false
instance_type = "t2.medium"
monitoring = true
key_name = "ec2_test_keypair"
subnet_id = "subnet-9f18c0d6"
vpc_security_group_ids = ["sg-62486b04"]
associate_public_ip_address = false
private_ip = "10.0.0.66"
source_dest_check = true
root_block_device {
volume_type = "gp2"
volume_size = 8
delete_on_termination = true
}
tags {
"Name" = "sitename_web1"
}
}
总结
虽然只是最低限的,但我成功地使用terraform创建了一个EC2实例。(实际上还需要进行更多的设置)
对于第一次接触AWS的人来说,即使只是创建一个实例,也需要了解许多概念,所以我认为先尝试启动一个几乎是默认设置的实例是个不错的主意。
另外,我推荐您先通过操作AWS控制台建立实例,而不是直接开始使用Terraform。这样可以帮助您了解是否可以将所有操作自动化。