😊
Terraform modulesを試してみる
https://developer.hashicorp.com/terraform/language/modules を試してみたいと思います。
検証内容
AWSでec2インスタンスを構築する。
環境
- AWS
- Terraform Cloud(CLI Driven)
ディレクトリ構成
環境固有のサブディレクトリにアプリケーションを分割する を参考に以下のような構成にしたいと思います。
ec2
のmoduleを作成します。
-- SERVICE-DIRECTORY/
-- modules/
-- ec2/
-- main.tf
-- variables.tf
-- outputs.tf
-- provider.tf
-- README
-- ...other…
-- environments/
-- dev/
-- main.tf
実装
ec2 modules作成
modules/ec2/main.tf
resource "aws_instance" "example" {
ami = var.ami_id
instance_type = var.instance_type
tags = {
Name = var.instance_name
}
}
modules/ec2/output.tf
output "instance_id" {
value = aws_instance.example.id
}
output "instance_public_ip" {
value = aws_instance.example.public_ip
}
modules/ec2/variavles.tf
variable "ami_id" {
description = "The AMI to use for the instance."
type = string
}
variable "instance_type" {
description = "The type of instance to start."
type = string
default = "t2.micro"
}
variable "instance_name" {
description = "The name tag of the instance."
type = string
default = "EC2Instance"
}
dev環境用のmain.tf作成
environments/dev/main.tf
terraform {
cloud {
organization = "tsaeki"
workspaces {
name = "20240119_aws_dev" # 事前にworkspaceを作成しておく
}
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "ap-northeast-1"
}
## ここで先程作成したec2 moduleを指定する
module "ec2" {
source = "../../modules/ec2"
ami_id = "ami-0506f0f56e3a057a4" # 適切なAMI IDに置き換えてください
instance_type = "t2.micro"
instance_name = "MyEC2Instance"
}
実行
作成したのでinit/planで試す。
-> % terraform init
Initializing Terraform Cloud...
Initializing modules...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v4.67.0
Terraform Cloud has been successfully initialized!
You may now begin working with Terraform Cloud. Try running "terraform plan" to
see any changes that are required for your infrastructure.
If you ever set or change modules or Terraform Settings, run "terraform init"
again to reinitialize your working directory.
tsaeki@DESKTOP-9A4RRVS [19:36:39] [~/Develop/20240119_aws/environments/dev] [main *]
-> % terraform plan
Running plan in Terraform Cloud. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.
Preparing the remote plan...
To view this run in a browser, visit:
https://app.terraform.io/app/tsaeki/20240119_aws_dev/runs/run-zS2Wr6M1sEjyJufs
Waiting for the plan to start...
Terraform v1.7.0
on linux_amd64
Initializing plugins and modules...
Initializing Terraform Cloud...
Initializing modules...
- ec2 in
╷
│ Error: Unreadable module directory
│
│ Unable to evaluate directory symlink: lstat ../../modules: no such file or
│ directory
╵
╷
│ Error: Unreadable module directory
│
│ The directory could not be read for module "ec2" at main.tf:24.
╵
Operation failed: failed running terraform init (exit 1)
あれ? ../../modules
が無いだろ、と怒られる。はて?
調べたらどうやらTerraform Cloudを使ってるのが原因のようだ。
対象のworkspacesのTerraform Working Directory
に設定が必要だったようだ。
Edit: After scrolling around Terraform Cloud, I found the setting.
Project & Workspaces -> Your Workspace -> Settings (on the left hand side)
The General tab should open up, scroll down.
Set your Terraform Version
Set your Terraform Working Directory. In my case, its /staging
ふむ。自分の場合は/environments/dev
を設定すればいいのかなと
設定して再度plan実行。できました!
-> % terraform plan
Running plan in Terraform Cloud. Output will stream here. Pressing Ctrl-C
will stop streaming the logs, but will not stop the plan running remotely.
Preparing the remote plan...
The remote workspace is configured to work with configuration at
/environments/dev relative to the target repository.
Terraform will upload the contents of the following directory,
excluding files or directories as defined by a .terraformignore file
at /home/tsaeki/Develop/20240119_aws/.terraformignore (if it is present),
in order to capture the filesystem context the remote workspace expects:
/home/tsaeki/Develop/20240119_aws
To view this run in a browser, visit:
https://app.terraform.io/app/tsaeki/20240119_aws_dev/runs/run-4Lehn25Bp22dTQQU
Waiting for the plan to start...
Terraform v1.7.0
on linux_amd64
Initializing plugins and modules...
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.ec2.aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0506f0f56e3a057a4"
+ 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)
+ disable_api_stop = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ get_password_data = false
+ host_id = (known after apply)
+ host_resource_group_arn = (known after apply)
+ iam_instance_profile = (known after apply)
+ id = (known after apply)
+ instance_initiated_shutdown_behavior = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ monitoring = (known after apply)
+ outpost_arn = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ placement_partition_number = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ secondary_private_ips = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "MyEC2Instance"
}
+ tags_all = {
+ "Name" = "MyEC2Instance"
}
+ tenancy = (known after apply)
+ user_data = (known after apply)
+ user_data_base64 = (known after apply)
+ user_data_replace_on_change = false
+ vpc_security_group_ids = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Cost Estimation:
Resources: 1 of 1 estimated
$8.6304/mo +$8.6304
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
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.
参考
Discussion