Terraform으로 VPC를 구축하는 방법

30315 단어 vpciacterraformaws
새로운 aws 계정을 적용한 후 모두가 VPC를 구축해야 하는 가장 중요한 것 중 하나입니다. 이 블로그의 목적은 Terraform을 사용하여 빌드하는 데 도움을 주는 것입니다.

네트워킹을 위한 디자인




  • 퍼블릭 서브넷: 배포 웹 사이트는 인터넷에서 직접 액세스할 수 있습니다
  • .
  • 프라이빗 서브넷: 애플리케이션 배포는 퍼블릭 서브넷의 웹 사이트에서만 액세스할 수 있습니다. 또한 응용 프로그램은 NAT 게이트웨이를 통해 인터넷에 액세스할 수 있습니다.

  • 구축 방법



    VPC를 생성하기 전에 먼저 TerraForm을 설치해야 합니다.

    코드 구조




    infrastructure
    ├── module
    │   └── networking
    │       ├── main.tf
    │       ├── outputs.tf
    │       └── variables.tf
    ├── region
    │   └── virginia
    │       ├── main.tf
    │       └── providers.tf
    └── setup
        ├── main.tf
        ├── outputs.tf
        ├── providers.tf
        └── variables.tf
    


    설정 환경


    setup 폴더의 소스 코드는 다음과 같습니다.
  • 메인.tf

  • locals {
      region = var.region
    }
    
    # Define a s3 bucket to store terraform state file.
    resource "aws_s3_bucket" "terraform_state" {
      bucket        = format("terraform-state-%s", local.region)
      force_destroy = false
      lifecycle {
        ignore_changes = [bucket]
      }
    }
    
    resource "aws_s3_bucket_versioning" "terraform_state" {
      bucket = aws_s3_bucket.terraform_state.id
      versioning_configuration {
        status = "Enabled"
      }
    }
    
    resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state" {
      bucket = aws_s3_bucket.terraform_state.bucket
      rule {
        apply_server_side_encryption_by_default {
          sse_algorithm = "AES256"
        }
      }
    }
    


  • 출력.tf

  • output "s3_bucket_terraform_state" {
      value = aws_s3_bucket.terraform_state.bucket
    }
    


  • 공급자.tf

  • terraform {
      required_version = ">= 0.13.7"
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = ">= 4.8.0"
        }
      }
    }
    


  • 변수.tf

  • variable "region" {
      description = "The name of the aws Region"
      type        = string
    }
    


    그런 다음 원격 백엔드용 s3 버킷을 생성해야 합니다. s3 버킷 이름은 s3_bucket_terraform_state 의 출력입니다.

    $ terraform init
    



    $ terraform apply
    


    네트워킹


    networking 폴더의 소스 코드는 다음과 같습니다.
  • 메인.tf

  • locals {
      name                       = var.name
      cidr_block                 = var.vpc_cidr_block
      public_subnets_cidr_block  = var.public_subnets_cidr_block
      private_subnets_cidr_block = var.private_subnets_cidr_block
      availability_zones         = var.availability_zones
      tags                       = var.vpc_tags
    }
    
    # VPC
    resource "aws_vpc" "vpc" {
      cidr_block           = local.cidr_block
      enable_dns_hostnames = true
      enable_dns_support   = true
    
      tags = merge( {
        Name = local.name
      }, local.tags)
    }
    
    # Subnets
    # Internet Gateway for Public Subnet
    resource "aws_internet_gateway" "internet_gateway" {
      vpc_id = aws_vpc.vpc.id
      tags   = merge({
        Name = "${local.name} Internet Gateway"
      }, local.tags)
    }
    
    # EIP for NAT
    resource "aws_eip" "nat_eip" {
      vpc        = true
      depends_on = [aws_internet_gateway.internet_gateway]
    }
    
    # NAT
    resource "aws_nat_gateway" "nat_gateway" {
      allocation_id = aws_eip.nat_eip.id
      subnet_id     = element(aws_subnet.public_subnet.*.id, 0)
    
      tags = merge({
        Name = "${local.name} Nat Gateway"
      }, local.tags)
    }
    
    # Public subnet
    resource "aws_subnet" "public_subnet" {
      vpc_id                  = aws_vpc.vpc.id
      count                   = length(local.public_subnets_cidr_block)
      cidr_block              = element(local.public_subnets_cidr_block, count.index)
      availability_zone       = element(local.availability_zones, count.index)
      map_public_ip_on_launch = true
      tags                    = merge( {
        Name = "${local.name} Public Subnet ${element(var.availability_zones, count.index)}"
      }, local.tags)
    }
    
    # Private Subnet
    resource "aws_subnet" "private_subnet" {
      vpc_id                  = aws_vpc.vpc.id
      count                   = length(local.private_subnets_cidr_block)
      cidr_block              = element(local.private_subnets_cidr_block, count.index)
      availability_zone       = element(local.availability_zones, count.index)
      map_public_ip_on_launch = false
      tags                    = merge({
        Name = "${local.name} Private Subnet ${element(var.availability_zones, count.index)}"
      }, local.tags)
    }
    
    
    # Routing tables to route traffic for Private Subnet
    resource "aws_route_table" "private" {
      vpc_id = aws_vpc.vpc.id
    
      tags = merge({
        Name = "${local.name} Private Route Table"
      }, local.tags)
    }
    
    # Routing tables to route traffic for Public Subnet
    resource "aws_route_table" "public" {
      vpc_id = aws_vpc.vpc.id
    
      tags = merge({
        Name = "${local.name} Public Route Table"
      }, local.tags)
    }
    
    # Route for Internet Gateway
    resource "aws_route" "public_internet_gateway" {
      route_table_id         = aws_route_table.public.id
      destination_cidr_block = "0.0.0.0/0"
      gateway_id             = aws_internet_gateway.internet_gateway.id
    }
    
    # Route for NAT
    resource "aws_route" "private_nat_gateway" {
      route_table_id         = aws_route_table.private.id
      destination_cidr_block = "0.0.0.0/0"
      nat_gateway_id         = aws_nat_gateway.nat_gateway.id
    }
    
    # Route table associations for Public Subnets
    resource "aws_route_table_association" "public" {
      count          = length(local.public_subnets_cidr_block)
      subnet_id      = element(aws_subnet.public_subnet.*.id, count.index)
      route_table_id = aws_route_table.public.id
    }
    
    # Route table associations for Private Subnets
    resource "aws_route_table_association" "private" {
      count          = length(local.private_subnets_cidr_block)
      subnet_id      = element(aws_subnet.private_subnet.*.id, count.index)
      route_table_id = aws_route_table.private.id
    }
    
    # Default Security Group of VPC
    resource "aws_security_group" "security_group" {
      name        = "${local.name} Security Group"
      description = "Default SG to allow traffic from the VPC"
      vpc_id      = aws_vpc.vpc.id
      depends_on  = [
        aws_vpc.vpc
      ]
    
      ingress {
        from_port = "0"
        to_port   = "0"
        protocol  = "-1"
        self      = true
      }
    
      egress {
        from_port = "0"
        to_port   = "0"
        protocol  = "-1"
        self      = "true"
      }
    
      tags = merge({}, local.tags)
    }
    


  • 출력.tf

  • output "vpc_id" {
      value = aws_vpc.vpc.id
    }
    
    output "public_subnets_id" {
      value = [aws_subnet.public_subnet.*.id]
    }
    
    output "private_subnets_id" {
      value = [aws_subnet.private_subnet.*.id]
    }
    
    output "security_groups_ids" {
      value = [aws_security_group.security_group.id]
    }
    
    output "public_route_table" {
      value = aws_route_table.public.id
    }
    


  • 변수.tf

  • variable "name" {
      description = "The VPC name"
    }
    
    variable "vpc_cidr_block" {
      description = "CIDR block of the vpc"
    }
    
    variable "public_subnets_cidr_block" {
      type        = list
      description = "CIDR block for Public Subnet"
    }
    
    variable "private_subnets_cidr_block" {
      type        = list
      description = "CIDR block for Private Subnet"
    }
    
    variable "availability_zones" {
      type        = list
      description = "AZ in which all the resources will be deployed"
    }
    
    variable "vpc_tags" {
      description = "A map of tags to add to VPC"
      type        = map(string)
      default     = {}
    }
    


    VPC 구축


    virginia 폴더의 소스 코드는 다음과 같습니다.
  • 메인.tf

  • locals {
      // the region code of virginia
      region             = "us-east-1"
      availability_zones = ["${local.region}a", "${local.region}b", "${local.region}c"]
      tags               = {
        "Environment" : "PROD"
        "Project" : "Infrastructure"
      }
    }
    
    provider "aws" {
      region = local.region
    }
    
    module "Networking" {
      source                     = "../../module/networking"
      name                       = "VPC"
      availability_zones         = local.availability_zones
      vpc_cidr_block             = "10.0.0.0/16"
      public_subnets_cidr_block  = ["10.0.32.0/24", "10.0.96.0/24", "10.0.224.0/24"]
      private_subnets_cidr_block = ["10.0.0.0/19", "10.0.64.0/19", "10.0.128.0/19"]
      vpc_tags                   = local.tags
    }
    


  • 공급자.tf

  • terraform {
      required_version = ">= 0.13.7"
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = ">= 4.8.0"
        }
      }
    
      backend "s3" {
        // the s3 bucket name
        bucket  = "*********"
        key     = "terraform/backend.tfstate"
        region  = "us-east-1"
        encrypt = "true"
      }
    }
    


    이제 VPC를 구축할 수 있습니다.

    $ terraform init
    



    $ terraform apply
    


    결과



    좋은 웹페이지 즐겨찾기