[Terraform] 모듈

728x90

모듈

공식 문서: https://registry.terraform.io/browse/modules

자주 사용되는 리소스들의 모음을 모듈이라고 부른다.

루트 모듈(https://www.terraform.io/language/modules)?? 실행되는 하나의 큰 테라폼 폴더, 그냥 내가 만든 테라폼 파일들의 모음을 루트 모듈이라고 부른다.

차일드 모듈?

퍼블리시 모듈? 레지스터리에 공개된 모듈들을 뜻함

module "myvpc" {
  source = "..."

  ...입력 변수...
}

terraform init

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "app_vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c", "ap-northeast-2d"]
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"]
  private_subnets = ["10.0.10.0/24", "10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"]
}

resource "aws_instance" "web" {
	subnet_id = module.myvpc.<출력 값>
}

모듈을 사용하여 간단한 인스턴스 구성

how 🐳  ~/terraform/01 $ cat main.tf

module "app_vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "app_vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-2a", "ap-northeast-2b"]
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24"]
  private_subnets = ["10.0.10.0/24", "10.0.11.0/24"]
}

resource "aws_key_pair" "app_server_key" {
  key_name   = "app_server_key"
  public_key = file("/Users/csw/.ssh/id_rsa.pub")
}

resource "aws_instance" "app_server" {
  ami           = var.aws_amazon_linux_ami[var.aws_region]
  instance_type = var.instance.type
  subnet_id = module.app_vpc.public_subnets[0]

  key_name = aws_key_pair.app_server_key.key_name

  connection {
    type        = "ssh"
    user        = "ec2-user"
    host        = self.public_ip
    private_key = file("/Users/csw/.ssh/id_rsa")
    timeout     = "1m"
  }

  provisioner "local-exec" {
    command = "echo ${self.public_ip} ansible_user=ec2-user > inven.ini"
  }

  provisioner "local-exec" {
    command = "ansible-playbook -i inven.ini web_install.yml -b"
  }

  tags = local.common_tags

  vpc_security_group_ids = [aws_security_group.app_server_sg.id]

  # 명시적 의존성
  depends_on = [
    aws_s3_bucket.b
  ]
}

resource "aws_instance" "app_server2" {
  ami           = var.aws_amazon_linux_ami[var.aws_region]
  instance_type = var.instance.type

  subnet_id = module.app_vpc.private_subnets[1]

  key_name = aws_key_pair.app_server_key.key_name

  tags = local.common_tags

  vpc_security_group_ids = [aws_security_group.app_server_sg.id]

  # 명시적 의존성
  depends_on = [
    aws_s3_bucket.b
  ]
}

resource "aws_eip" "app_server_eip" {
  # 암시적 의존성
  instance = aws_instance.app_server.id
  vpc      = true
  tags     = local.common_tags
}

resource "aws_s3_bucket" "b" {
  bucket = "csw-test-bucker"

  tags = local.common_tags
}

resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.b.id
  acl    = "private"
}

how 🐳  ~/terraform/01 $ cat provider.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = var.aws_region
}

how 🐳  ~/terraform/01 $ cat local.tf

locals {
  common_tags = {
    Name        = "My Terraform"
    Environment = var.env
    AZ          = var.aws_availability_zone[var.aws_region]
  }
}

how 🐳  ~/terraform/01 $ cat security_group.tf

resource "aws_security_group" "app_server_sg" {
  name = "allow SSH & HTTPD"

  vpc_id = module.app_vpc.vpc_id

  # 인바운드 규칙
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # 인바운드 규칙
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  # 인바운드 규칙
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["1.236.102.10/32"]
  }

  # 아웃바운드 규칙
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = local.common_tags

}

how 🐳  ~/terraform/01 $ cat web_install.yml

- hosts: all

  tasks:
    - yum:
        name: httpd
    - service:
        name: httpd
        state: started
        enabled: yes
    - copy:
        content: "<h1>hello teraform</h1>"
        dest: "/var/www/html/index.html"

how 🐳  ~/terraform/01 $ cat var.tf

variable "env" {
  type    = string
  default = "Environment"
}

variable "instance" {
  type = object({
    name = string
    type = string
  })
  default = {
    name = "test"
    type = "t3.small"
  }
}

variable "aws_region" {
  description = "AWS Region"
  type        = string
  default     = "ap-northeast-2"
}

variable "aws_availability_zone" {
  description = "AWS AZs"
  type        = map(string)
  default = {
    ap-northeast-1 = "ap-northeast-1c"
    ap-northeast-2 = "ap-northeast-2c"
    ap-northeast-3 = "ap-northeast-3c"
  }
}

variable "aws_amazon_linux_ami" {
  description = "Amazon Linux 5.10 AMI Image"
  type        = map(string)
  default = {
    ap-northeast-1 = "ami-0bcc04d20228d0cf6" # 도쿄
    ap-northeast-2 = "ami-02de72c5dc79358c9" # 서울 
    ap-northeast-3 = "ami-0fe7b77eb0549da6c" # 오사카
  }
}

variable "project_name" {
  description = "Project Name"
  type        = string
  default     = "My First Terraform Project"
}

variable "projcet_environment" {
  description = "Project Environment"
  type        = string
  default     = "Local"
}
728x90