카테고리 없음

4주차 - State & 모듈

카이도스 2023. 7. 27. 12:07
728x90
반응형
CloudNet@-가시다(Gasida)님의 Terraform 스터디와
테라폼으로 시작하는 IaC’ 책을 기준하여 정리하였습니다.

2023.07.05 - [Terraform] - 1주차 - 테라폼 기본 사용 1/2

 

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
반응형