IaC( Infrastructure as Code )が叫ばれる昨今ようやく「Terraform」触りました。IaCってなに?ていうのはググればすぐのなの任せます。
Terraformのインストール
環境(GCPに構築)
Red Hat Enterprise Linux Server release 7.6 (Maipo)
1.Terraformのダウンロード
ここから環境にあったものをダウンロード
2.インストール
ダウンロードしたものを/usr/local/srcなんかに移動
unzip terraform_0.11.11_linux_amd64.zip
解凍したら/usr/local/binなんかに移動してパス追加
[root@terraform terraform_work]# export PATH=/usr/local/bin:$PATH
##ついでにprofileにも追記
[root@terraform terraform_work]# vi ~/bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin:/usr/local/bin ##ココに追加
export PATH
するとこうなる
[root@terraform ~]# terraform
Usage: terraform [-version] [-help] <command> [args]
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
Common commands:
apply Builds or changes infrastructure
console Interactive console for Terraform interpolations
destroy Destroy Terraform-managed infrastructure
env Workspace management
fmt Rewrites config files to canonical format
get Download and install modules for the configuration
graph Create a visual graph of Terraform resources
import Import existing infrastructure into Terraform
init Initialize a Terraform working directory
output Read an output from a state file
plan Generate and show an execution plan
providers Prints a tree of the providers used in the configuration
push Upload this Terraform module to Atlas to run
refresh Update local state file against real resources
show Inspect Terraform state or plan
taint Manually mark a resource for recreation
untaint Manually unmark a resource as tainted
validate Validates the Terraform files
version Prints the Terraform version
workspace Workspace management
All other commands:
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
state Advanced state management
AWS環境向けに作ってみる
とりあえず作業ディレクトリを作って移動
1.コード書く
単純にインスタンスを作成するだけのやつです
[root@terraform terraform_work]# vi example.tf
provider "aws" {
access_key = "xxxxhogexxxxxx"
secret_key = "xxxxhogexxxxxxxxxxhogexxxxxx"
region = "ap-northeast-1"
}
resource "aws_instance" "example" {
ami = "ami-05cd6c87a37390178"
instance_type = "t3.nano"
}
事前にアクセスキーを作成してシークレットキーとともに控える
(これって直接書くしかないのかな。。なんか別ファイルにキーだけ置いとくのもできそうな気がするがまだちゃんと調べてない。。)
2.コードをイニシャライズする
[root@terraform terraform_work]# terraform init
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "aws" (1.60.0)...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = "~> 1.60"
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
3.コードを実行
途中作っていい?と聞かれるので"yes"と答える
[root@terraform terraform_work]# terraform apply
aws_instance.example: Refreshing state... (ID: i-0c933621e39daa09b)
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
id: <computed>
ami: "ami-05cd6c87a37390178"
arn: <computed>
associate_public_ip_address: <computed>
availability_zone: <computed>
cpu_core_count: <computed>
cpu_threads_per_core: <computed>
ebs_block_device.#: <computed>
ephemeral_block_device.#: <computed>
get_password_data: "false"
host_id: <computed>
instance_state: <computed>
instance_type: "t3.nano"
ipv6_address_count: <computed>
ipv6_addresses.#: <computed>
key_name: <computed>
network_interface.#: <computed>
network_interface_id: <computed>
password_data: <computed>
placement_group: <computed>
primary_network_interface_id: <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>
tenancy: <computed>
volume_tags.%: <computed>
vpc_security_group_ids.#: <computed>
Plan: 1 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_instance.example: Creating...
ami: "" => "ami-05cd6c87a37390178"
arn: "" => "<computed>"
associate_public_ip_address: "" => "<computed>"
availability_zone: "" => "<computed>"
cpu_core_count: "" => "<computed>"
cpu_threads_per_core: "" => "<computed>"
ebs_block_device.#: "" => "<computed>"
ephemeral_block_device.#: "" => "<computed>"
get_password_data: "" => "false"
host_id: "" => "<computed>"
instance_state: "" => "<computed>"
instance_type: "" => "t3.nano"
ipv6_address_count: "" => "<computed>"
ipv6_addresses.#: "" => "<computed>"
key_name: "" => "<computed>"
network_interface.#: "" => "<computed>"
network_interface_id: "" => "<computed>"
password_data: "" => "<computed>"
placement_group: "" => "<computed>"
primary_network_interface_id: "" => "<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>"
tenancy: "" => "<computed>"
volume_tags.%: "" => "<computed>"
vpc_security_group_ids.#: "" => "<computed>"
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Creation complete after 13s (ID: i-028e10437889aeeca)
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
4.コードの内容
[root@terraform terraform_work]# terraform show
aws_instance.example:
id = i-028e10437889aeeca
ami = ami-05cd6c87a37390178
arn = arn:aws:ec2:ap-northeast-1:363717127291:instance/i-028e10437889aeeca
associate_public_ip_address = true
availability_zone = ap-northeast-1a
cpu_core_count = 1
cpu_threads_per_core = 2
credit_specification.# = 1
credit_specification.0.cpu_credits = unlimited
disable_api_termination = false
ebs_block_device.# = 0
ebs_optimized = false
ephemeral_block_device.# = 0
get_password_data = false
iam_instance_profile =
instance_state = running
instance_type = t3.nano
ipv6_addresses.# = 0
key_name =
monitoring = false
network_interface.# = 0
network_interface_id = eni-0e09848f22985016b
password_data =
placement_group =
primary_network_interface_id = eni-0e09848f22985016b
private_dns = ip-172-31-17-100.ap-northeast-1.compute.internal
private_ip = 172.31.17.100
public_dns = ec2-3-112-72-247.ap-northeast-1.compute.amazonaws.com
public_ip = 3.112.72.247
root_block_device.# = 1
root_block_device.0.delete_on_termination = true
root_block_device.0.iops = 100
root_block_device.0.volume_id = vol-09e1eadc149aa8700
root_block_device.0.volume_size = 8
root_block_device.0.volume_type = gp2
security_groups.# = 1
security_groups.3814588639 = default
source_dest_check = true
subnet_id = subnet-e7ce5eae
tags.% = 0
tenancy = default
volume_tags.% = 0
vpc_security_group_ids.# = 1
vpc_security_group_ids.1170673366 = sg-ca8649b3
コードを変更して再作成
1.使用するAMIを変更
[root@terraform terraform_work]# vi example.tf
provider "aws" {
access_key = "xxxxhogexxxxxx"
secret_key = "xxxxhogexxxxxxxxxxhogexxxxxx"
region = "ap-northeast-1"
}
resource "aws_instance" "example" {
ami = "ami-00a5245b4816c38e6"
instance_type = "t3.nano"
}
2.そのまま実行
[root@terraform terraform_work]# terraform apply
aws_instance.example: Refreshing state... (ID: i-028e10437889aeeca)
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
-/+ aws_instance.example (new resource required)
id: "i-028e10437889aeeca" => <computed> (forces new resource)
ami: "ami-05cd6c87a37390178" => "ami-00a5245b4816c38e6" (forces new resource)
arn: "arn:aws:ec2:ap-northeast-1:363717127291:instance/i-028e10437889aeeca" => <computed>
associate_public_ip_address: "true" => <computed>
availability_zone: "ap-northeast-1a" => <computed>
cpu_core_count: "1" => <computed>
cpu_threads_per_core: "2" => <computed>
ebs_block_device.#: "0" => <computed>
ephemeral_block_device.#: "0" => <computed>
get_password_data: "false" => "false"
host_id: "" => <computed>
instance_state: "running" => <computed>
instance_type: "t3.nano" => "t3.nano"
ipv6_address_count: "" => <computed>
ipv6_addresses.#: "0" => <computed>
key_name: "" => <computed>
network_interface.#: "0" => <computed>
network_interface_id: "eni-0e09848f22985016b" => <computed>
password_data: "" => <computed>
placement_group: "" => <computed>
primary_network_interface_id: "eni-0e09848f22985016b" => <computed>
private_dns: "ip-172-31-17-100.ap-northeast-1.compute.internal" => <computed>
private_ip: "172.31.17.100" => <computed>
public_dns: "ec2-3-112-72-247.ap-northeast-1.compute.amazonaws.com" => <computed>
public_ip: "3.112.72.247" => <computed>
root_block_device.#: "1" => <computed>
security_groups.#: "1" => <computed>
source_dest_check: "true" => "true"
subnet_id: "subnet-e7ce5eae" => <computed>
tenancy: "default" => <computed>
volume_tags.%: "0" => <computed>
vpc_security_group_ids.#: "1" => <computed>
Plan: 1 to add, 0 to change, 1 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_instance.example: Destroying... (ID: i-028e10437889aeeca)
aws_instance.example: Still destroying... (ID: i-028e10437889aeeca, 10s elapsed)
aws_instance.example: Still destroying... (ID: i-028e10437889aeeca, 20s elapsed)
aws_instance.example: Destruction complete after 29s
aws_instance.example: Creating...
ami: "" => "ami-00a5245b4816c38e6"
arn: "" => "<computed>"
associate_public_ip_address: "" => "<computed>"
availability_zone: "" => "<computed>"
cpu_core_count: "" => "<computed>"
cpu_threads_per_core: "" => "<computed>"
ebs_block_device.#: "" => "<computed>"
ephemeral_block_device.#: "" => "<computed>"
get_password_data: "" => "false"
host_id: "" => "<computed>"
instance_state: "" => "<computed>"
instance_type: "" => "t3.nano"
ipv6_address_count: "" => "<computed>"
ipv6_addresses.#: "" => "<computed>"
key_name: "" => "<computed>"
network_interface.#: "" => "<computed>"
network_interface_id: "" => "<computed>"
password_data: "" => "<computed>"
placement_group: "" => "<computed>"
primary_network_interface_id: "" => "<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>"
tenancy: "" => "<computed>"
volume_tags.%: "" => "<computed>"
vpc_security_group_ids.#: "" => "<computed>"
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Creation complete after 13s (ID: i-0aad086be18339bfd)
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
変更点がわかりやすく表示されます。
また先に作成したインスタンスは削除されたのち新しいものが作成されるのは注意です!別で作成したい場合は新しいコードファイルにしましょう!!
3.作成したインスタンスの削除
[root@terraform terraform_work]# terraform destroy
aws_instance.example: Refreshing state... (ID: i-0aad086be18339bfd)
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
- aws_instance.example
Plan: 0 to add, 0 to change, 1 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: Destroying... (ID: i-0aad086be18339bfd)
aws_instance.example: Still destroying... (ID: i-0aad086be18339bfd, 10s elapsed)
aws_instance.example: Still destroying... (ID: i-0aad086be18339bfd, 20s elapsed)
aws_instance.example: Still destroying... (ID: i-0aad086be18339bfd, 30s elapsed)
aws_instance.example: Destruction complete after 40s
Destroy complete! Resources: 1 destroyed.
これで削除完了です。
まとめ
運用する場合はVPCやらDiskやら設定するものはたくさんあるのでコードも長くなりますが触りとしてはこんなもんで。
こういうのをコード化して残しておくと再作成も楽だしいいですね。学習コストはそこそこありますが。。