본문 바로가기
카테고리 없음

마이크로서비스 인프라 구축 1

by ^..^v 2022. 3. 17.
728x90
반응형

테라폼의 모듈 구조를 사용해서 인프라 코드를 작성

먼저, 각 모듈을 저장할 깃허브 저장소를 생성하고, 네트워크, 쿠버네티스, Argo CD 모듈을 정의하고, 개발환경(env-sandbox)으로 통합

 

1 테라폼 모듈 저장소 생성

모듈별 깃허브 저장소 

저장소 이름 공개 여부 설명
module-aws-network 공개 네트워크를 생성하는 테라폼 모듈
module-aws-kubernetes 공개 EKS를 구축하는 테라폼 모듈
module-argo-cd 공개 Argo CD를 클러스터에 설치하는 테라폼 모듈

 





2 네트워크 모듈

쿠버네티스 및 마이크로서비스 아키텍처와 워크로드를 지원하는 AWS 네트워크 모듈을 작성

 

2.1 깃 클론

c:\msur> git clone https://github.com/myanjini/module-aws-network.git
Cloning into 'module-aws-network'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.

 

2.2 네트워크 모듈 정의

C:\msur\module-aws-network\main.tf

Amazon VPC 리소스 정의

## AWS 공급자 선언
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs
provider "aws" {
  region = var.aws_region # 모듈을 호출하는 곳에서 파라미터로 전달
}

## 로컬 변수 선언 
## https://www.terraform.io/language/values/locals
locals {
  vpc_name     = "${var.env_name}-${var.vpc_name}"
  cluster_name = "${var.env_name}-${var.cluster_name}"
}

## Amazon VPC 생성을 위한 코드를 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc
resource "aws_vpc" "main" {
  cidr_block           = var.main_vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  ## 리소스 태그
  ## 리소스를 쉽게 식별하고 관리할 수 있으며, 
  ## 자동화된 작업 및 특정 방식으로 관리해야 하는 리소스를 식별할 때 유용
  tags = {
    "Name"                                        = local.vpc_name,
    "kubernetes.io/cluster/${local.cluster_name}" = "shared",
  }
}

 

서브넷 정의

## 공급자에 구성된 리전 내에서 AWS 계정이 액세스할 수 있는 가용 영역 목록을 조회
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones
data "aws_availability_zones" "available" {
  state = "available"
}

## 퍼블릭 서브넷 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet
resource "aws_subnet" "public-subnet-a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnet_a_cidr
  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    "Name"                                        = "${local.vpc_name}-public-subnet-a"
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/elb"                      = "1"
  }
}

resource "aws_subnet" "public-subnet-b" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnet_b_cidr
  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    "Name"                                        = "${local.vpc_name}-public-subnet-b"
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/elb"                      = "1"
  }
}

## 프라이빗 서브넷 정의
resource "aws_subnet" "private-subnet-a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnet_a_cidr
  availability_zone = data.aws_availability_zones.available.names[0]

  tags = {
    "Name"                                        = "${local.vpc_name}-private-subnet-a"
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/internal-elb"             = "1"
  }
}

resource "aws_subnet" "private-subnet-b" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.private_subnet_b_cidr
  availability_zone = data.aws_availability_zones.available.names[1]

  tags = {
    "Name"                                        = "${local.vpc_name}-private-subnet-b"
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/internal-elb"             = "1"
  }
}

 

참고: Network load balancing on Amazon EKS

https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html

EKS가 서브넷을 사용해 ELB를 생성하고 배포할 수 있도록 퍼블릭 서브넷에는 elb 태그를 지정하고, 프라이빗 서브넷에는 internal-elb 태그를 지정

 

퍼블릭 서브넷을 위한 인터넷 게이트웨이 및 라우팅 테이블 정의

## 인터넷 게이트웨이 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${local.vpc_name}-igw"
  }
}

## 퍼블릭 라우팅 테이블 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table
resource "aws_route_table" "public-route" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    "Name" = "${local.vpc_name}-public-route"
  }
}

## 퍼블릭 서브넷과 퍼블릭 라우팅 테이블 연결
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association
resource "aws_route_table_association" "public-a-association" {
  subnet_id      = aws_subnet.public-subnet-a.id
  route_table_id = aws_route_table.public-route.id
}

resource "aws_route_table_association" "public-b-association" {
  subnet_id      = aws_subnet.public-subnet-b.id
  route_table_id = aws_route_table.public-route.id
}

 

프라이빗 서브넷을 위한 NAT 게이트웨이 설정

## EIP를 생성해 NAT에 할당
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip
resource "aws_eip" "nat-a" {
  vpc = true
  tags = {
    "Name" = "${local.vpc_name}-NAT-a"
  }
}

resource "aws_eip" "nat-b" {
  vpc = true
  tags = {
    "Name" = "${local.vpc_name}-NAT-b"
  }
}

## NAT 게이트웨이 생성
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway
resource "aws_nat_gateway" "nat-gw-a" {
  allocation_id = aws_eip.nat-a.id
  subnet_id     = aws_subnet.public-subnet-a.id
  depends_on    = [aws_internet_gateway.igw]

  tags = {
    "Name" = "${local.vpc_name}-NAT-gw-a"
  }
}

resource "aws_nat_gateway" "nat-gw-b" {
  allocation_id = aws_eip.nat-b.id
  subnet_id     = aws_subnet.public-subnet-b.id
  depends_on    = [aws_internet_gateway.igw]

  tags = {
    "Name" = "${local.vpc_name}-NAT-gw-b"
  }
}

 

프라이빗 서브넷에 대한 라우팅을 정의

## 프라이빗 라우팅 테이블 정의
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table
resource "aws_route_table" "private-route-a" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat-gw-a.id
  }

  tags = {
    "Name" = "${local.vpc_name}-private-route-a"
  }
}

resource "aws_route_table" "private-route-b" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat-gw-b.id
  }

  tags = {
    "Name" = "${local.vpc_name}-private-route-b"
  }
}

## 프라이빗 서브넷과 프라이빗 라우팅 테이블을 연결
## https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table_association
resource "aws_route_table_association" "private-a-association" {
  subnet_id      = aws_subnet.private-subnet-a.id
  route_table_id = aws_route_table.private-route-a.id
}

resource "aws_route_table_association" "private-b-association" {
  subnet_id      = aws_subnet.private-subnet-b.id
  route_table_id = aws_route_table.private-route-b.id
}

 

2.3 입력 값 정의

https://www.terraform.io/language/values/variables

 

C:\msur\module-aws-network\variables.tf

variable "env_name" {
  type = string
}

variable "aws_region" {
  type = string
}

variable "cluster_name" {
  type = string
}

variable "vpc_name" {
  type    = string
  default = "ms-up-running"
}

variable "main_vpc_cidr" {
  type = string
}

variable "public_subnet_a_cidr" {
  type = string
}

variable "public_subnet_b_cidr" {
  type = string
}

variable "private_subnet_a_cidr" {
  type = string
}

variable "private_subnet_b_cidr" {
  type = string
}

 

2.4 출력 값 정의

https://www.terraform.io/language/values/outputs

명령줄에서 사용할 수 있는 인프라에 대한 정보를 만들고, 다른 테라폼 구성에서 사용할 정보를 노출

 

C:\msur\module-aws-network\outputs.tf

output "vpc_id" {
  value = aws_vpc.main.id
}

output "subnet_ids" {
  value = [
    aws_subnet.public-subnet-a.id,
    aws_subnet.public-subnet-b.id,
    aws_subnet.private-subnet-a.id,
  aws_subnet.private-subnet-b.id]
}

output "public_subnet_ids" {
  value = [aws_subnet.public-subnet-a.id, aws_subnet.public-subnet-b.id]
}

output "private_subnet_ids" {
  value = [aws_subnet.private-subnet-a.id, aws_subnet.private-subnet-b.id]
}

output "route53_id" {
  value = aws_route53_zone.private-zone.zone_id
}

 

2.5 형식 지정 → 작업 디렉터리 초기화 → 구성 검사

C:\msur\module-aws-network> terraform fmt

C:\msur\module-aws-network> terraform init

C:\msur\module-aws-network> terraform validate
╷
│ Error: Reference to undeclared resource
│
│   on outputs.tf line 22, in output "route53_id":
│   22:   value = aws_route53_zone.private-zone.zone_id
│
│ A managed resource "aws_route53_zone" "private-zone" has not been declared in the root module.

 

2.6 수정 후 다시 검사

C:\msur\module-aws-network\outputs.tf
# 오류가 발생하는 부분 주석 처리
# output "route53_id" {
#   value = aws_route53_zone.private-zone.zone_id
# }


C:\msur\module-aws-network> terraform validate
Success! The configuration is valid.

 

2.7 깃허브 저장소에 푸시

C:\msur\module-aws-network> git add .
c:\msur\module-aws-network> git commit -m "네트워크 모듈 생성"
C:\msur\module-aws-network> git push

 

2.8 샌드박스 환경에 네트워크 생성

네트워크 모듈 추가

C:\kubernetes\env-sandbox\main.tf

terraform {
  backend "s3" {
    bucket = "sk403-003-bucket"
    key    = "terraform/backend"
    region = "us-west-2"
  }
}

locals {
  env_name         = "sandbox"
  aws_region       = "us-west-2"
  vpc_name         = "sk403-003-vpc"
  k8s_cluster_name = "sk403-003-ms-cluster"
}

# AWS 네트워크 구성
module "aws-network" {
  source = "git::https://github.com/naanjini/module-aws-network.git"

  env_name              = local.env_name
  aws_region            = local.aws_region
  vpc_name              = local.vpc_name
  cluster_name          = local.k8s_cluster_name
  main_vpc_cidr         = "10.10.0.0/16"
  public_subnet_a_cidr  = "10.10.0.0/18"
  public_subnet_b_cidr  = "10.10.64.0/18"
  private_subnet_a_cidr = "10.10.128.0/18"
  private_subnet_b_cidr = "10.10.192.0/18"
}

# TODO EKS 클러스터 구성

# TODO GitOps 구성

 

형식 지정, 작업 디렉터리 초기화, 구성 검사

c:\msur\env-sandbox> terraform fmt
c:\msur\env-sandbox> terraform init
c:\msur\env-sandbox> terraform validate

 

인프라 구축을 위한 실행 계획 확인 (모의 테스트, dry run)

c:\msur\env-sandbox> terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.aws-network.aws_eip.nat-a will be created
  	:

Plan: 17 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

 

릴리스 태그 지정 및 깃허브 저장소에 푸시

c:\msur\env-sandbox> git add .
c:\msur\env-snadbox> git commit -m "네트워크 구성"
c:\msur\env-snadbox> git push origin

c:\msur\env-snadbox> git tag -a v1.0 -m "네트워크 구성"
c:\msur\env-snadbox> git push origin v1.0

 

워크플로우 실행 확인

 

VPC 생성 확인

c:\msur\env-sandbox> aws ec2 describe-vpcs --filters Name=cidr,Values=10.10.0.0/16
{
    "Vpcs": [
        {
            "CidrBlock": "10.10.0.0/16",
            "DhcpOptionsId": "dopt-070584ca7a8169184",
            "State": "available",
            "VpcId": "vpc-003e20f45f753961f",
            "OwnerId": "286943186215",
            "InstanceTenancy": "default",
            "CidrBlockAssociationSet": [
                {
                    "AssociationId": "vpc-cidr-assoc-07fc143983e5027bc",
                    "CidrBlock": "10.10.0.0/16",
                    "CidrBlockState": {
                        "State": "associated"
                    }
                }
            ],
            "IsDefault": false,
            "Tags": [
                {
                    "Key": "kubernetes.io/cluster/sandbox-sk403-003-ms-cluster",
                    "Value": "shared"
                },
                {
                    "Key": "Name",
                    "Value": "sandbox-sk403-003-vpc"
                }
            ]
        }
    ]
}

 

2.9 생성한 리소스 모두 삭제

c:\msur\env-sandbox> terraform destroy
        :
Plan: 0 to add, 0 to change, 17 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes
        :
Destroy complete! Resources: 17 destroyed.

 

 

 

728x90
반응형

댓글