티스토리 뷰

결과

 

서울리전의 A,B,C 3개의 AZ를 사용하는 VPC와 각 AZ별 public,private 서브넷 생성

 

이후 해당 서브넷을 사용하는 EKS클러스터 를 배포하고 특정IP와 클러스터에서 사용하는 NAT-GW IP만 API접근을 허용 함

 

생성된 private 서브넷을 사용하는 RDS 배포하고 BASTION과 EKS클러스터의 접근을 허용

 

클러스터와 RDS에 접근할수 있는 BASTION을 배포

 

특정IP에서 BASTION으로 ssh접근을 허용함

 

 

먼저 variables.tf에 변수를 수정

 

variable "aws_region" {
  default = "ap-northeast-2"
}

variable "cluster-name" {
  default = "my-cluster"
  type    = string
}

variable "dbpassword" {
  default = "password"
}

variable "key_name" {
  default = "default"
}

클러스터 네임, rds에서 사용할 패스워드, bastion에 적용될 keypair이름 설정

 

 

bastion.tf에서 bastion에 ssh를 허용할 IP설정

 

#클러스터에 접근하거나 관리할때 사용하는 BASTION노드 설정

#BASION에 할당 할 탄력적 ip생성
resource "aws_eip" "bastion-eip" {
  vpc = true
  tags = {
    "Name" = "${var.cluster-name}-bastion-eip"
  }
}

#EC2 인스턴스 생성
resource "aws_instance" "bastion" {
  ami = "ami-0cbec04a61be382d9" //ami2
  instance_type = "t2.medium"
  subnet_id = aws_subnet.public-subnet[0].id //pubilc서브넷 할당
  vpc_security_group_ids = [aws_security_group.bastion.id]
  key_name = "${var.key_name}" //key name
  tags = {
    Name = "${var.cluster-name}-bastion"
  }

}

#생성된 탄력적ip와 인스턴스 연결
resource "aws_eip_association" "eip_assoc" {
  instance_id   = aws_instance.bastion.id
  allocation_id = aws_eip.bastion-eip.id
}


### Bastion에서 사용할 SG및 rule
resource "aws_security_group" "bastion" {
  name        = "${var.cluster-name}-bastion"
  vpc_id      = aws_vpc.vpc.id
  description = "${var.cluster-name}-bastion-sg"

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.cluster-name}-bastion"
  }
}

# 아래 아이피 대역에서 ssh접근을 허용함
resource "aws_security_group_rule" "allowssh" {
  description = "allow andyhome and 10f"
  type = "ingress"
  from_port = 22
  to_port = 22
  protocol = "TCP"
  cidr_blocks= ["110.117.232.147/32"]
  security_group_id = aws_security_group.bastion.id
}

#아래 아이피 대역에서 모든 접근을 허용함(테스트)
resource "aws_security_group_rule" "allowall" {
  description = "allow andyhome"
  type = "ingress"
  from_port = 0
  to_port = 0
  protocol = "-1"
  cidr_blocks= ["110.117.232.147/32"]
  security_group_id = aws_security_group.bastion.id
}

위 코드중 110.117.232.147/32 을 원하는 대역으로 수정

 

 

 

eks-cluster.tf

 

eks 클러스터를 배포

#EKS 클러스터 구성


# eks 에서 사용할 role 생성
resource "aws_iam_role" "eks" {
  name = "${var.cluster-name}"

  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "eks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}
#role에 policy add
resource "aws_iam_role_policy_attachment" "AmazonEKSClusterPolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = aws_iam_role.eks.name
}

resource "aws_iam_role_policy_attachment" "AmazonEKSVPCResourceController" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
  role       = aws_iam_role.eks.name
}

#클러스터에 추가할 SG설정 bastion에서 모든 포트로 ingress허용 정책 rule을 추가한 sg를 추가하여 클러스터 생성시 ADD함
resource "aws_security_group" "cluster-bastion" {
  name        = "${var.cluster-name}-cluster-bastion"
  description = "Cluster communication with bastion nodes"
  vpc_id      = aws_vpc.vpc.id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.cluster-name}-cluster"
  }
}
#bastion에서 오는 모든 트래픽 허용 정책
resource "aws_security_group_rule" "ingress-bastion" {
  description       = "Allow bastion to communicate with the cluster"
  from_port         = 0
  protocol          = "-1"
  security_group_id = aws_security_group.cluster-bastion.id
  source_security_group_id = aws_security_group.bastion.id
  to_port           = 0
  type              = "ingress"
}

#애드온 변수 선언
variable "addons" {
  type = list(object({
    name    = string
  }))

  default = [
    {
      name    = "kube-proxy"
    },
    {
      name    = "vpc-cni"
    },
    {
      name    = "coredns"
    }
  ]
}
#선언된 애드온 변수 이용하여 애드온 설치
resource "aws_eks_addon" "addons" {
  for_each          = { for addon in var.addons : addon.name => addon }
  cluster_name = aws_eks_cluster.eks.name
  addon_name        = each.value.name
  resolve_conflicts = "OVERWRITE"
}
# 클러스터 로그 cloud watch 보관주기 30일 설정
resource "aws_cloudwatch_log_group" "eks" {
  name              = "/aws/eks/${var.cluster-name}/cluster"
  retention_in_days = 30
}
# 클러스터 기본 설정
resource "aws_eks_cluster" "eks" {
  name     = var.cluster-name
  role_arn = aws_iam_role.eks.arn
  version = "1.22" //클러스터 버전 명시
  enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"] //로깅
  
#클러스터 네트워크 설정
  vpc_config {
    security_group_ids = [aws_security_group.cluster-bastion.id] //클러스터 기본 보안그룹 외 추가할 보안그룹 설정(위에서 만든 BASTION허용 정책을 추가)
    subnet_ids         = concat(aws_subnet.public-subnet[*].id, aws_subnet.private-subnet[*].id)
    endpoint_private_access = true
    endpoint_public_access = true
#api access의 cidr제한을 검 허용할 ip외 nat gateway도 허용하여야 exec,logs 등의 명령어를 쓸수 있음
    public_access_cidrs       = ["110.117.232.147/32", "${aws_eip.eip.public_ip}/32"]
  }
  
# policy의 dependency를 검
  depends_on = [
    aws_iam_role_policy_attachment.AmazonEKSClusterPolicy,
    aws_iam_role_policy_attachment.AmazonEKSVPCResourceController,
  ]
}

 

eks-worker-nodes.tf

 

nodegroup을 배포

 

#EKS WORKER 노드 설정


# 워커노드에서 사용할 role 생성
resource "aws_iam_role" "node" {
  name = "${var.cluster-name}-node"

  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}


#생성한 role에 policy 할당
resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
  role       = aws_iam_role.node.name
}

resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
  role       = aws_iam_role.node.name
}

resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = aws_iam_role.node.name
}


#asg는 nodegroup으로 인해 자동으로 생성되나 name을 설정해주기 위해 tag만 지정하여줌
resource "aws_autoscaling_group_tag" "c6i-2xlarge" {

  autoscaling_group_name = aws_eks_node_group.c6i-2xlarge.resources[0].autoscaling_groups[0].name

  tag {
    key   = "Name"
    value = "${var.cluster-name}-node"
    propagate_at_launch = true
  }
}


# c6i 2xlarge node group
resource "aws_eks_node_group" "c6i-2xlarge" {
  cluster_name    = aws_eks_cluster.eks.name
  node_group_name = "${var.cluster-name}-c6i-2xlarge"
  node_role_arn   = aws_iam_role.node.arn
  subnet_ids      = aws_subnet.private-subnet[*].id
  instance_types = ["c6i.2xlarge"]
  disk_size = 50

  labels = {
    "role" = "${var.cluster-name}-c6i-2xlarge"
  }

  scaling_config {
    desired_size = 3
    min_size     = 3
    max_size     = 10
  }

  depends_on = [
    aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,
    aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,
    aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,
  ]

  tags = {
    "Name" = "${var.cluster-name}-c6i-2xlarge-Node",
    "Names" = "${var.cluster-name}-c6i-2xlarge-Node"
  }
}

 

위 예제는 c6i.2xlarge 타입의 인스턴스 노드그룹을 배포 scaling config과 disk_size등 필요하면 수정하여 사용

 

 

소스는 아래 github에

https://github.com/mircyb/eks-deploy

최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함