카테고리 없음
4주차 - State & 모듈
카이도스
2023. 7. 27. 12:07
728x90
반응형
CloudNet@-가시다(Gasida)님의 Terraform 스터디와
테라폼으로 시작하는 IaC’ 책을 기준하여 정리하였습니다.
1주차 - 테라폼 기본 사용 1/2
CloudNet@-가시다(Gasida)님의 Terraform 스터디와 테라폼으로 시작하는 IaC’ 책을 기준하여 정리하였습니다. 1. Iac와 테라폼 1-1. 테라폼 : Terraform의 구성 언어는 선언적입니다. 즉, 인프라에 대해 원하
djdakf1234.tistory.com
2023.07.12 - [Terraform] - 2주차 - 테라폼 기본 사용 2/3
2주차 - 테라폼 기본 사용 2/3
CloudNet@-가시다(Gasida)님의 Terraform 스터디와 테라폼으로 시작하는 IaC’ 책을 기준하여 정리하였습니다. 2023.07.05 - [Terraform] - 1주차 - 테라폼 기본 사용 1/2 1주차 - 테라폼 기본 사용 1/2 CloudNet@-가시
djdakf1234.tistory.com
2023.07.21 - [Terraform] - 3주차 - 기본 사용 3/3 & 프로바이더
3주차 - 기본 사용 3/3 & 프로바이더
CloudNet@-가시다(Gasida)님의 Terraform 스터디와 테라폼으로 시작하는 IaC’ 책을 기준하여 정리하였습니다. 2023.07.05 - [Terraform] - 1주차 - 테라폼 기본 사용 1/2 1주차 - 테라폼 기본 사용 1/2 CloudNet@-가시
djdakf1234.tistory.com
[도전과제1] T101 1기 노션내용에 AWS DynamoDB/S3를 원격 저장소로 사용하는 실습
# 디렉터리 생성
mkdir dynamo-s3 && cd dynamo-s3
- dynamo-s3.tf 생성
provider "aws" {
region = "ap-northeast-2"
}
# Terraform의 State를 저장 할 S3
resource "aws_s3_bucket" "pjhs3bucket" {
bucket = "pjh-t101study-tfstate"
}
# State Versioning을 위하여 만들어진 S3를 Versioning 설정 추가
resource "aws_s3_bucket_versioning" "pjhs3bucket_versioning" {
bucket = aws_s3_bucket.pjhs3bucket.id
versioning_configuration {
status = "Enabled"
}
}
# RDS
resource "aws_dynamodb_table" "pjhdynamodbtable" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST" # 사용량에 따른 과금 모드
hash_key = "LockID" # DynamoDB 테이블에서 사용 될 해시 키의 이름
attribute {
name = "LockID"
type = "S"
}
}
output "s3_bucket_arn" {
value = aws_s3_bucket.pjhs3bucket.arn
description = "The ARN of the S3 bucket"
}
output "dynamodb_table_name" {
value = aws_dynamodb_table.pjhdynamodbtable.name
description = "The name of the DynamoDB table"
}
- 배포
# init
terraform init
# 배포
terraform plan && terraform apply -auto-approve
# 확인
terraform state list
aws_dynamodb_table.pjhdynamodbtable
aws_s3_bucket.pjhs3bucket
aws_s3_bucket_versioning.pjhs3bucket_versioning
# DynamoDB 테이블 생성 확인
aws dynamodb list-tables --output text
TABLENAMES terraform-locks
aws dynamodb describe-table --table-name terraform-locks --output table
----------------------------------------------------------------------------------------------
| DescribeTable |
+--------------------------------------------------------------------------------------------+
|| Table ||
|+------------------+-----------------------------------------------------------------------+|
|| CreationDateTime| 1690432423.923 ||
|| ItemCount | 0 ||
|| TableArn | arn:aws:dynamodb:ap-northeast-2:20....:table/terraform-locks ||
|| TableId | 6381663c-edbd-4b54-8a8a-5f9f89fa001b ||
|| TableName | terraform-locks ||
|| TableSizeBytes | 0 ||
|| TableStatus | ACTIVE ||
|+------------------+-----------------------------------------------------------------------+|
||| AttributeDefinitions |||
||+-------------------------------------------------------+--------------------------------+||
||| AttributeName | LockID |||
||| AttributeType | S |||
||+-------------------------------------------------------+--------------------------------+||
||| BillingModeSummary |||
||+---------------------------------------------------------+------------------------------+||
||| BillingMode | PAY_PER_REQUEST |||
||| LastUpdateToPayPerRequestDateTime | 1690432423.923 |||
||+---------------------------------------------------------+------------------------------+||
||| KeySchema |||
||+-------------------------------------------------------+--------------------------------+||
||| AttributeName | LockID |||
||| KeyType | HASH |||
||+-------------------------------------------------------+--------------------------------+||
||| ProvisionedThroughput |||
||+-------------------------------------------------------------------------+--------------+||
||| NumberOfDecreasesToday | 0 |||
||| ReadCapacityUnits | 0 |||
||| WriteCapacityUnits | 0 |||
||+-------------------------------------------------------------------------+--------------+||
- ec2 생성 및 배포
# 디렉터리 생성
mkdir ec2 && cd ec2
- aws_availability_zones.tf
data "aws_availability_zones" "available" {
state = "available"
}
- vpc.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "pjhvpc" {
cidr_block = "10.10.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "t101-study"
}
}
resource "aws_subnet" "pjhsubnet1" {
vpc_id = aws_vpc.pjhvpc.id
cidr_block = "10.10.1.0/24"
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "t101-subnet1"
}
}
resource "aws_subnet" "pjhsubnet2" {
vpc_id = aws_vpc.pjhvpc.id
cidr_block = "10.10.2.0/24"
availability_zone = data.aws_availability_zones.available.names[1]
tags = {
Name = "t101-subnet2"
}
}
resource "aws_internet_gateway" "pjhigw" {
vpc_id = aws_vpc.pjhvpc.id
tags = {
Name = "t101-igw"
}
}
resource "aws_route_table" "pjhrt" {
vpc_id = aws_vpc.pjhvpc.id
tags = {
Name = "t101-rt"
}
}
resource "aws_route_table_association" "pjhrtassociation1" {
subnet_id = aws_subnet.pjhsubnet1.id
route_table_id = aws_route_table.pjhrt.id
}
resource "aws_route_table_association" "pjhrtassociation2" {
subnet_id = aws_subnet.pjhsubnet2.id
route_table_id = aws_route_table.pjhrt.id
}
resource "aws_route" "pjhdefaultroute" {
route_table_id = aws_route_table.pjhrt.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.pjhigw.id
}
output "aws_vpc_id" {
value = aws_vpc.pjhvpc.id
}
- sg.tf
resource "aws_security_group" "pjhsg" {
vpc_id = aws_vpc.pjhvpc.id
name = "T101 SG"
description = "T101 Study SG"
}
resource "aws_security_group_rule" "pjhsginbound" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.pjhsg.id
}
resource "aws_security_group_rule" "pjhsgoutbound" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.pjhsg.id
}
- ec2.tf
data "aws_ami" "pjh_amazonlinux2" {
most_recent = true
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-ebs"]
}
owners = ["amazon"]
}
resource "aws_instance" "pjhec2" {
depends_on = [
aws_internet_gateway.pjhigw
]
ami = data.aws_ami.pjh_amazonlinux2.id
associate_public_ip_address = true
instance_type = "t2.micro"
vpc_security_group_ids = ["${aws_security_group.pjhsg.id}"]
subnet_id = aws_subnet.pjhsubnet1.id
user_data = <<-EOF
#!/bin/bash
wget https://busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64
mv busybox-x86_64 busybox
chmod +x busybox
RZAZ=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone-id)
IID=$(curl 169.254.169.254/latest/meta-data/instance-id)
LIP=$(curl 169.254.169.254/latest/meta-data/local-ipv4)
echo "<h1>RegionAz($RZAZ) : Instance ID($IID) : Private IP($LIP) : Web Server</h1>" > index.html
nohup ./busybox httpd -f -p 80 &
EOF
user_data_replace_on_change = true
tags = {
Name = "t101-pjhec2"
}
}
output "pjhec2_public_ip" {
value = aws_instance.pjhec2.public_ip
description = "The public IP of the Instance"
}
- backend.tf
terraform {
backend "s3" {
bucket = "pjh-t101study-tfstate"
key = "dev/terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-locks"
# encrypt = true
}
}
- 배포
# init
terraform init
# 배포
terraform plan && terraform apply -auto-approve
# 확인
terraform state list
- 삭제
terraform destroy -auto-approve
[도전과제2] 각자 사용하기 편리한 리소스를 모듈화 해보고, 해당 모듈을 활용해서 반복 리소스들 배포
2-1. 모듈과 프로바이더
# 디렉터리 생성
mkdir -p ec2-module/modules/ec2 && cd ec2-module/modules/ec2
- main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
resource "aws_default_vpc" "default" {}
data "aws_ami" "default" {
most_recent = true
owners = ["amazon"]
filter {
name = "owner-alias"
values = ["amazon"]
}
filter {
name = "name"
values = ["amzn2-ami-hvm*"]
}
}
resource "aws_instance" "default" {
depends_on = [aws_default_vpc.default]
ami = data.aws_ami.default.id
instance_type = var.instance_type
tags = {
Name = var.instance_name
}
}
- var.tf
variable "instance_type" {
description = "vm 인스턴스 타입 정의"
default = "t2.micro"
}
variable "instance_name" {
description = "vm 인스턴스 이름 정의"
default = "my_ec2"
}
- output.tf
output "private_ip" {
value = aws_instance.default.private_ip
}
# 모듈을 사용할 루트 모듈 디렉터리 생성
mkdir -p ec2-module/provider_for_module && cd ec2-module/provider_for_module
- main.tf
provider "aws" {
region = "ap-southeast-1"
}
provider "aws" {
alias = "seoul"
region = "ap-northeast-2"
}
module "ec2_singapore" {
source = "../modules/ec2"
}
module "ec2_seoul" {
source = "../modules/ec2"
providers = {
aws = aws.seoul
}
instance_type = "t3.small"
}
- output.tf
output "module_output_singapore" {
value = module.ec2_singapore.private_ip
}
output "module_output_seoul" {
value = module.ec2_seoul.private_ip
}
- 배포
# init
cd ec2-module/provider_for_module/
terraform init
# 확인
cat .terraform/modules/modules.json | jq
{
"Modules": [
{
"Key": "",
"Source": "",
"Dir": "."
},
{
"Key": "ec2_seoul",
"Source": "../modules/ec2",
"Dir": "../modules/ec2"
},
{
"Key": "ec2_singapore",
"Source": "../modules/ec2",
"Dir": "../modules/ec2"
}
]
}
# 배포
terraform plan && terraform apply -auto-approve
Outputs:
module_output_seoul = "172.31.45.184"
module_output_singapore = "172.31.35.116"
# 확인
terraform state list
module.ec2_seoul.data.aws_ami.default
module.ec2_seoul.aws_default_vpc.default
module.ec2_seoul.aws_instance.default
module.ec2_singapore.data.aws_ami.default
module.ec2_singapore.aws_default_vpc.default
module.ec2_singapore.aws_instance.default
- 삭제
terraform destroy -auto-approve
2-2. 모듈의 반복문
# 디렉터리 생성
mkdir -p ec2-module/module_loop_count && cd ec2-module/module_loop_count
- main.tf
provider "aws" {
region = "ap-northeast-2"
}
module "ec2_seoul" {
count = 2
source = "../modules/ec2"
instance_type = "t3.small"
}
output "module_output" {
value = module.ec2_seoul[*].private_ip
}
- 배포
# init
terraform init
# 확인
cat .terraform/modules/modules.json | jq
{
"Modules": [
{
"Key": "",
"Source": "",
"Dir": "."
},
{
"Key": "ec2_seoul",
"Source": "../modules/ec2",
"Dir": "../modules/ec2"
}
]
}
# 배포
terraform plan && terraform apply -auto-approve
Outputs:
module_output = [
"172.31.35.156",
"172.31.38.198",
]
# 확인
terraform state list
module.ec2_seoul[0].data.aws_ami.default
module.ec2_seoul[0].aws_default_vpc.default
module.ec2_seoul[0].aws_instance.default
module.ec2_seoul[1].data.aws_ami.default
module.ec2_seoul[1].aws_default_vpc.default
module.ec2_seoul[1].aws_instance.default
- 삭제
terraform destroy -auto-approve
모듈 묶음에 일관된 구성과 구조로 프로비저닝이 되는 경우라면 count가 간편한 방안이지만, 동일한 모듈 구성에 필요한 인수 값이 다르다면 for_each를 활용한다.
- main.tf 수정
locals {
env = {
dev = {
type = "t3.micro"
name = "dev_ec2"
}
prod = {
type = "t3.medium"
name = "prod_ec2"
}
}
}
module "ec2_seoul" {
for_each = local.env
source = "../modules/ec2"
instance_type = each.value.type
instance_name = each.value.name
}
output "module_output" {
value = [
for k in module.ec2_seoul: k.private_ip
]
}
- 배포
# 배포
terraform plan && terraform apply -auto-approve
Outputs:
module_output = [
"172.31.34.10",
"172.31.45.113",
]
# 확인
terraform state list
module.ec2_seoul["dev"].data.aws_ami.default
module.ec2_seoul["dev"].aws_default_vpc.default
module.ec2_seoul["dev"].aws_instance.default
module.ec2_seoul["prod"].data.aws_ami.default
module.ec2_seoul["prod"].aws_default_vpc.default
module.ec2_seoul["prod"].aws_instance.default
- 삭제
terraform destroy -auto-approve
[도전과제3] 테라폼 레지스트리에 공개된 모듈을 사용하여 리소스를 배포
# 모듈 다운로드
git clone https://github.com/terraform-aws-modules/terraform-aws-iam
tree terraform-aws-iam/examples -L 1
cd terraform-aws-iam/examples/iam-policy
# 확인
cat main.tf
## main.tf 수정
## 서울 리전 변경
sed -i -e 's/eu-west-1/ap-northeast-2/g' main.tf
- 배포
# init
terraform init
cat .terraform/modules/modules.json| jq
# 배포 및 확인
terraform plan && terraform apply -auto-approve
terraform state list
data.aws_iam_policy_document.bucket_policy
module.iam_policy.aws_iam_policy.policy[0]
module.iam_policy_from_data_source.aws_iam_policy.policy[0]
- 삭제
terraform destroy -auto-approve
728x90
반응형