https://gasidaseo.notion.site/gasidaseo/CloudNet-Blog-c9dfa44a27ff431dafdd2edacc8a1863
<1> VPC 모듈 실습
<2> Local 실습 해보자. S3 웹사이트 예제
<3> 모듈 사용시 주의점
<1> VPC 모듈 실습
참고 사이트
https://developer.hashicorp.com/terraform/tutorials/modules/module-use
vpc module(v3.14.0) , ec2 module(v3.5.0)
1
cd
mkdir study
cd study
2
코드 다운로드
git clone https://github.com/hashicorp/learn-terraform-modules-use.git
cd learn-terraform-modules-use
tree
├── LICENSE
├── main.tf
├── outputs.tf
├── README.md
├── terraform.tf
└── variables.tf
3
서울리전으로 변경
sed -i -e 's/"us-west-2a", "us-west-2b", "us-west-2c"/"ap-northeast-2a", "ap-northeast-2c"/g' variables.tf
sed -i -e 's/us-west-2/ap-northeast-2/g' main.tf
sed -i -e 's/ami-0c5204531f799e0c6/ami-09cf633fe86e51bf0/g' main.tf
4
테라폼 init
모듈관련한 부분을 가져 온다.
tree로 확인
terraform init
tree .terraform -L 2
.terraform
├── modules
│ ├── ec2_instances
│ ├── modules.json
│ └── vpc
└── providers
└── registry.terraform.io
5
코드 내용 확인
[root@ip-172-31-61-209 learn-terraform-modules-use]# more *.tf
::::::::::::::
main.tf
::::::::::::::
provider "aws" {
region = "ap-northeast-2"
default_tags {
tags = {
hashicorp-learn = "module-use"
}
}
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "3.14.0"
name = var.vpc_name
cidr = var.vpc_cidr
azs = var.vpc_azs
private_subnets = var.vpc_private_subnets
public_subnets = var.vpc_public_subnets
enable_nat_gateway = var.vpc_enable_nat_gateway
tags = var.vpc_tags
}
module "ec2_instances" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "3.5.0"
count = 2
name = "my-ec2-cluster"
ami = "ami-09cf633fe86e51bf0"
instance_type = "t2.micro"
vpc_security_group_ids = [module.vpc.default_security_group_id]
subnet_id = module.vpc.public_subnets[0]
tags = {
Terraform = "true"
Environment = "dev"
}
}
::::::::::::::
outputs.tf
::::::::::::::
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.tf
::::::::::::::
terraform {
/* Uncomment this block to use Terraform Cloud for this tutorial
cloud {
organization = "organization-name"
workspaces {
name = "learn-terraform-module-use"
}
}
*/
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.4.0"
}
}
required_version = ">= 1.1.0"
}
::::::::::::::
variables.tf
::::::::::::::
variable "vpc_name" {
description = "Name of VPC"
type = string
default = "example-vpc"
}
variable "vpc_cidr" {
description = "CIDR block for VPC"
type = string
default = "10.0.0.0/16"
}
variable "vpc_azs" {
description = "Availability zones for VPC"
type = list(string)
default = ["ap-northeast-2a", "ap-northeast-2c"]
}
variable "vpc_private_subnets" {
description = "Private subnets for VPC"
type = list(string)
default = ["10.0.1.0/24", "10.0.2.0/24"]
}
variable "vpc_public_subnets" {
description = "Public subnets for VPC"
type = list(string)
default = ["10.0.101.0/24", "10.0.102.0/24"]
}
variable "vpc_enable_nat_gateway" {
description = "Enable NAT gateway for VPC"
type = bool
default = true
}
variable "vpc_tags" {
description = "Tags to apply to resources created by VPC module"
type = map(string)
default = {
Terraform = "true"
Environment = "dev"
}
}
[root@ip-172-31-61-209 learn-terraform-modules-use]#
변경해 테스트해보자.
6
배포
nat 는 비용이 나오므로 제외하고 배포하자.
인스턴스는 기본 2개 만들어진다.
# (옵션) NATGW 제거
export TF_VAR_vpc_enable_nat_gateway=false # macOS/Linux
set TF_VAR_vpc_enable_nat_gateway=false # windows
# plan & apply
terraform plan && terraform apply -auto-approve
Outputs:
ec2_instance_public_ips = [
"13.125.73.197",
"3.38.255.38",
]
vpc_public_subnets = [
"subnet-02f60311e4e985c68",
"subnet-0f59b5b9bdb55562c",
]
7
# 확인
terraform state list
[root@ip-172-31-61-209 learn-terraform-modules-use]# terraform state list
module.ec2_instances[0].aws_instance.this[0]
module.ec2_instances[1].aws_instance.this[0]
module.vpc.aws_internet_gateway.this[0]
module.vpc.aws_route.public_internet_gateway[0]
module.vpc.aws_route_table.private[0]
module.vpc.aws_route_table.private[1]
module.vpc.aws_route_table.public[0]
module.vpc.aws_route_table_association.private[0]
module.vpc.aws_route_table_association.private[1]
module.vpc.aws_route_table_association.public[0]
module.vpc.aws_route_table_association.public[1]
module.vpc.aws_subnet.private[0]
module.vpc.aws_subnet.private[1]
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
module.vpc.aws_vpc.this[0]
8
콘솔에서 확인하자.
vpc , ec2 확인하자.
<2> Local 실습 해보자. S3 웹사이트 예제
참고
https://developer.hashicorp.com/terraform/tutorials/modules/module-create
vpc module(v2.21.0) , ec2 module(v2.12.0), website s3 bucket
1
다운로드
# 신규 폴더에 clone
mkdir local
cd local
git clone https://github.com/hashicorp/learn-terraform-modules-create.git
cd learn-terraform-modules-create
tree
├── LICENSE
├── main.tf
├── modules
│ └── aws-s3-static-website-bucket
│ ├── LICENSE
│ ├── main.tf
│ ├── outputs.tf
│ ├── README.md
│ ├── variables.tf
│ └── www
│ ├── error.html
│ └── index.html
├── outputs.tf
├── README.md
└── variables.tf
2
서울 리전으로 변경
버킷 이름 변경
#
sed -i -e 's/"us-west-2a", "us-west-2b", "us-west-2c"/"ap-northeast-2a", "ap-northeast-2c"/g' variables.tf
sed -i -e 's/us-west-2/ap-northeast-2/g' main.tf
sed -i -e 's/ami-0c5204531f799e0c6/ami-09cf633fe86e51bf0/g' main.tf
# 버킷 이름 변경
NICKNAME=<각자 자신의 닉네임>
NICKNAME=masterseo
sed -i -e "s/robin-test-dec-17-2019/$NICKNAME-t101-s3/g" main.tf
3
# init
terraform init
# 폴더 확인
tree .terraform
# (옵션) NATGW 제거
export TF_VAR_vpc_enable_nat_gateway=false # macOS/Linux
set TF_VAR_vpc_enable_nat_gateway=false # windows
# plan & apply
terraform plan && terraform apply -auto-approve
Outputs:
ec2_instance_public_ips = [
"43.201.103.19",
"3.38.209.42",
]
vpc_public_subnets = [
"subnet-0fe0a2a5b460bf4bd",
"subnet-0f2b34e374a72c70e",
]
website_bucket_arn = "arn:aws:s3:::masterseo-t101-s3"
website_bucket_domain = "s3-website.ap-northeast-2.amazonaws.com"
website_bucket_name = "masterseo-t101-s3"
# 확인
terraform state list
4
s3를 static web 으로 만들자.
aws s3 cp 로 index.html 올리자.
#
aws s3 cp modules/aws-s3-static-website-bucket/www/ s3://$(terraform output -raw website_bucket_name)/ --recursive
upload: modules/aws-s3-static-website-bucket/www/index.html to s3://masterseo-t101-s3/index.html
upload: modules/aws-s3-static-website-bucket/www/error.html to s3://masterseo-t101-s3/error.html
# curl 혹은 웹 브라우저에서 S3 버킷 접속
curl -s http://$NICKNAME-t101-s3.s3-website.ap-northeast-2.amazonaws.com/
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Static Website</title>
</head>
<body>
<p>Nothing to see here.</p>
</body>
</html>
5
확인
브라우저로 확인
http://masterseo-t101-s3.s3-website.ap-northeast-2.amazonaws.com/
6
삭제
aws s3 rm s3://$(terraform output -raw website_bucket_name)/ --recursive
terraform destroy -auto-approve
<3> 모듈 사용시 주의점
1
별도의 폴더에 정의된 모듈에서 file 함수를 사용하기 위해서 경로 참조path reference 표현식 필요
- path.module : 표현식이 정의된 모듈의 파일 시스템 경로를 반환
- path.root : 루트 모듈의 파일 시스템 경로를 반환
- path.cwd : 현재 작업 중인 디렉터리의 파일 시스템 경로를 반환
user_data = templatefile("${path.module}/user-data.sh", {
server_port = var.server_port
db_address = data.terraform_remote_state.db.outputs.address
db_port = data.terraform_remote_state.db.outputs.port
})
2
'인라인 블록'과 '별도의 리소스'를 혼합 사용 시 서로 덮어쓰는 오류가 발생함!!!
3
[별도의 리소스] : aws_security_group 리소스와 aws_security_group_rule 리소스를 통해서 별도로 정의 사용을 권장한다.
별도의 리소스 사용 권장 이유?
스테이징 환경에서 테스트를 위해 추가로 포트를 노출 시, aws_security_group_rule 리소스를 stage/services/webserver-cluster/main.tf 에 추가.
인라인 블록으로 규칙을 정의한 경우에는 코드가 작동하지 않습니다
별도의 리소스
resource "aws_security_group" "alb" {
name = "${var.cluster_name}-alb"
}
resource "aws_security_group_rule" "allow_http_inbound" {
type = "ingress"
security_group_id = aws_security_group.alb.id
from_port = local.http_port
to_port = local.http_port
protocol = local.tcp_protocol
cidr_blocks = local.all_ips
}
resource "aws_security_group_rule" "allow_all_outbound" {
type = "egress"
security_group_id = aws_security_group.alb.id
from_port = local.any_port
to_port = local.any_port
protocol = local.any_protocol
cidr_blocks = local.all_ips
}
4
기타
[인라인 블록] : aws_security_group 리소스에 인라인 블록을 통해 인/아웃 규칙을 정의
스테이징 환경에서 테스트를 위해 추가로 포트를 노출 시, aws_security_group_rule 리소스를 stage/services/webserver-cluster/main.tf 에 추가
인라인 블록으로 규칙을 정의한 경우에는 코드가 작동하지 않습니다
resource "aws_security_group" "alb" {
name = "${var.cluster_name}-alb"
ingress {
from_port = local.http_port
to_port = local.http_port
protocol = local.tcp_protocol
cidr_blocks = local.all_ips
}
egress {
from_port = local.any_port
to_port = local.any_port
protocol = local.any_protocol
cidr_blocks = local.all_ips
}
}
다음
https://brunch.co.kr/@topasvga/2809
https://brunch.co.kr/@topasvga/2421
감사합니다.