Terraform Registry 網址: https://registry.terraform.io/
HashiCorp 官方維運的服務,提供各種的供應商外掛跟模組,也可以上傳分享自己製作的模組。
今天我們不一點一點的打造基礎架構,而是要練習用現成的模組完成基礎架構。
你可以在 Terraform Registry 上搜尋適合的模組,Terraform 官方也有準備很多好用的模組,例如 AWS VPC 模組: https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/
打開網頁你會看到詳細的模組說明,右側會有一個快速使用範例。
接下來我們要來試著建立一個完整的基礎架構。完整檔案可以參考 Github 上的範例
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "example-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1d", "ap-northeast-1d"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
tags = {
Terraform = "true"
Environment = "dev"
}
}
module "web_server_sg" {
source = "terraform-aws-modules/security-group/aws//modules/http-80"
name = "web-server"
description = "sg for http ingress"
vpc_id = module.vpc.vpc_id
ingress_cidr_blocks = ["0.0.0.0/0"]
}
data "aws_ami" "ubuntu-focal" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/*ubuntu-focal-20.04-amd64-server-*"]
}
owners = ["099720109477"]
}
data "template_file" "user_data" {
template = file("user_data.yaml")
}
module "ec2_instances" {
source = "terraform-aws-modules/ec2-instance/aws"
name = "example-ec2-cluster"
instance_count = 2
ami = data.aws_ami.ubuntu-focal.id
instance_type = "t2.micro"
vpc_security_group_ids = [module.vpc.default_security_group_id, module.web_server_sg.this_security_group_id]
subnet_ids = module.vpc.public_subnets
#subnet_id = module.vpc.public_subnets[0]
user_data = data.template_file.user_data.rendered
tags = {
Terraform = "true"
Environment = "dev"
}
}
這次我們使用了三個模組:
module "vpc"
: 使用 terraform-aws-modules/vpc/aws
模組,建立 aws VPCmodule "web_server_sg"
: 使用 terraform-aws-modules/security-group/aws//modules/http-80
,建立 http 的安全群組module "ec2_instances"
: 使用 terraform-aws-modules/ec2-instance/aws
,建立兩台虛擬伺服器想要取得模組的輸出資料,格式是 module.<MODULE NAME>.<OUTPUT NAME>
我們試著把 public subnet 跟 public ip 輸出,範例如下:
output "vpc_public_subnets" {
description = "IDs of the VPC's public subnets"
value = module.vpc.public_subnets
}
output "ec2_instance_public_ips" {
description = "Public IP addresses of EC2 instances"
value = module.ec2_instances.public_ip
}
每當使用到新的模組是就要執行指令 terraform init
,Terraform 會把模組下載到 .terraform/modules
資料夾裡。
$ terraform init
Initializing modules...
Downloading terraform-aws-modules/ec2-instance/aws 2.15.0 for ec2_instances...
- ec2_instances in .terraform/modules/ec2_instances
Downloading terraform-aws-modules/vpc/aws 2.51.0 for vpc...
- vpc in .terraform/modules/vpc
Downloading terraform-aws-modules/security-group/aws 3.16.0 for web_server_sg...
- web_server_sg in .terraform/modules/web_server_sg/modules/http-80
- web_server_sg.sg in .terraform/modules/web_server_sg
...
Terraform has been successfully initialized!
.terraform/modules
資料夾裡面大概的長相:
.terraform/modules
├── ec2_instances
├── modules.json
├── vpc
└── web_server_sg
執行指令 terraform apply
的方法是一樣的,確認執行計畫後輸入 yes
。
可以看到這些模組把我們要的 vpc, security-group, instance 都設定好,其他依賴的資源也一起準備好了。
Apply complete! Resources: 34 added, 0 changed, 0 destroyed.
Outputs:
ec2_instance_public_ips = [
"54.238.87.143",
"3.112.40.26",
]
vpc_public_subnets = [
"subnet-0f1fdfe4cf3d3bda0",
"subnet-09410b2bbd87c5876",
"subnet-0f89ceed33412208b",
]
結束這一輪的練習,輸入指令 terraform destroy
,並輸入 yes
刪除剛剛建立的基礎架構。