# 7주차 테라폼으로 AWS EKS 배포

## 1. 배경지식

### 1.1 EKS

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FnM67ST1weknuhxOhZdx6%2Fimage.png?alt=media&#x26;token=d18df1fd-296d-49d0-88e4-604033ef697d" alt=""><figcaption></figcaption></figure>

* AWS 환경에서 K8S 클러스터 패턴을 제공해줍니다.
* Managed Service로 제공하는 서비스이며, Control Node에 대한 운영은 생각할 필요가 없습니다.
* 다른 AWS 서비스들과 빠른 호환성을 제공하며, AWS 환경 내의 K8S 운영을 도와줍니다.
  * 컨테이너 이미지 저장소 ECR
  * 로드 분산 ELB
  * 인증 IAM
  * 격리 VPC

### 1.2 Fargate

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2F3suWREbvdIBUSgxLNpzQ%2Fimage.png?alt=media&#x26;token=4c66b803-b6f1-4507-8cf3-71b6e3088b2b" alt=""><figcaption></figcaption></figure>

* Fargate는 서버리스 컴퓨팅 엔진으로 서버나 클러스터를 직접 관리할 필요 없습니다.
* 다음과 같이 EKS + Fargate 를 사용하게되면 완전한 서버리스로 운용하고 서버 관리에 대한 복잡성을 줄일 수 있습니다.
* autoscaling에 대한 부담도 자동확장이 되서 처리할 필요가 없어집니다.

### 1.3 Karpenter

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FiaErSBRk5Dcak4YTUoyb%2Fimage.png?alt=media&#x26;token=c853532e-4a0a-4a5f-a0fd-01597ca31a3a" alt=""><figcaption><p><a href="https://ec2spotworkshops.com/karpenter.html">https://ec2spotworkshops.com/karpenter.html</a></p></figcaption></figure>

* ASG를 거치거나 Cluster Autoscaler를 거치지 않고 바로 EC2를 생성해주는 AWS 솔루션입니다.
* 23년 10월에 베타가 완료됨

## 2. AWS EKS Blueprints for Terraform

### 2.1 Karpenter EKS On Fargate Terraform으로 배포하기

* AWS EKS Blueprints for terraform은 필요한 요구사항에 따른 terraform 예제 코드가 제공되어있어서 각각 알맞게 적용할 수 있습니다. [(링크)](https://aws-ia.github.io/terraform-aws-eks-blueprints/)
* 모듈로 구성되어 있진 않아서, 알맞게 모듈로 구성해서 사용하면 됩니다.
* 또한, blueprint addon들을 제공해줘서 helm 차트 기반으로 빠르게 요구사항을 충족시킬 수 있습니다.
  * [terraform-aws-eks-blueprint-addon](https://github.com/aws-ia/terraform-aws-eks-blueprints-addon)&#x20;
  * [terraform-aws-eks-blueprint-addons](https://github.com/aws-ia/terraform-aws-eks-blueprints-addons) (여러 애드온을 한번에 프로비저닝 할 수 있는 모듈)
  * [terraform-aws-eks-blueprints-teams](https://github.com/aws-ia/terraform-aws-eks-blueprints-teams) (멀티 테넌시 리소스 구성을 위한 모듈)

### 2.2 주요 준비 사항

```
aws --version
terraform --version
kubectl version --client=true
helm -h
// 해당 툴들에 대한 준비를 해줍니다.

git clone https://github.com/aws-ia/terraform-aws-eks-blueprints
cd terraform-aws-eks-blueprints/patterns/karpenter

// repository를 받아옵니다.

terraform init
```

### 2.3 배포된 리소스들 확인

1. VPC 배포

````
// VPC 코드에는 다음과 같이 CIDR 이 있는데 해당 FUNCTION은 간편한 TERRAFORM FUNCTION이다.

```
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
```
````

```
// 현재 VPC 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
Vpcs: []

terraform apply -target="module.vpc" -auto-approve
Apply complete! Resources: 23 added, 0 changed, 0 destroyed.
```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2F6NVdytPEIZjS1cn54HNV%2Fimage.png?alt=media&#x26;token=a1509777-ef0c-41ea-9e2d-a80e8e7605ec" alt=""><figcaption></figcaption></figure>

* 다음과 같이 vpc는 잘 구성이 되었다

2. eks 배포

```
terraform apply -target="module.eks" -auto-approve
// Apply complete! Resources: 24 added, 0 changed, 0 destroyed.
terraform state list  // 정상적으로 배포된 것을 확인 할 수 있습니다.
// data.aws_availability_zones.available
module.eks.data.aws_caller_identity.current
module.eks.data.aws_iam_policy_document.assume_role_policy[0]
module.eks.data.aws_iam_session_context.current
module.eks.data.aws_partition.current
module.eks.data.tls_certificate.this[0]
module.eks.aws_cloudwatch_log_group.this[0]
module.eks.aws_ec2_tag.cluster_primary_security_group["Blueprint"]
module.eks.aws_ec2_tag.cluster_primary_security_group["GithubRepo"]
module.eks.aws_ec2_tag.cluster_primary_security_group["karpenter.sh/discovery"]
module.eks.aws_eks_access_entry.this["cluster_creator"]
module.eks.aws_eks_access_policy_association.this["cluster_creator_admin"]
module.eks.aws_eks_cluster.this[0]
module.eks.aws_iam_openid_connect_provider.oidc_provider[0]
module.eks.aws_iam_policy.cluster_encryption[0]
module.eks.aws_iam_role.this[0]
module.eks.aws_iam_role_policy_attachment.cluster_encryption[0]
module.eks.aws_iam_role_policy_attachment.this["AmazonEKSClusterPolicy"]
module.eks.aws_iam_role_policy_attachment.this["AmazonEKSVPCResourceController"]
module.eks.time_sleep.this[0]
module.vpc.aws_default_network_acl.this[0]
module.vpc.aws_default_route_table.default[0]
module.vpc.aws_default_security_group.this[0]
module.vpc.aws_eip.nat[0]
module.vpc.aws_internet_gateway.this[0]
module.vpc.aws_nat_gateway.this[0]
module.vpc.aws_route.private_nat_gateway[0]
module.vpc.aws_route.public_internet_gateway[0]
module.vpc.aws_route_table.private[0]
module.vpc.aws_route_table.public[0]
module.vpc.aws_route_table_association.private[0]
module.vpc.aws_route_table_association.private[1]
module.vpc.aws_route_table_association.private[2]
module.vpc.aws_route_table_association.public[0]
module.vpc.aws_route_table_association.public[1]
module.vpc.aws_route_table_association.public[2]
module.vpc.aws_subnet.private[0]
module.vpc.aws_subnet.private[1]
module.vpc.aws_subnet.private[2]
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
module.vpc.aws_subnet.public[2]
module.vpc.aws_vpc.this[0]
module.eks.module.fargate_profile["karpenter"].data.aws_caller_identity.current
module.eks.module.fargate_profile["karpenter"].data.aws_iam_policy_document.assume_role_policy[0]
module.eks.module.fargate_profile["karpenter"].data.aws_partition.current
module.eks.module.fargate_profile["karpenter"].data.aws_region.current
module.eks.module.fargate_profile["karpenter"].aws_eks_fargate_profile.this[0]
module.eks.module.fargate_profile["karpenter"].aws_iam_role.this[0]
module.eks.module.fargate_profile["karpenter"].aws_iam_role_policy_attachment.this["AmazonEKSFargatePodExecutionRolePolicy"]
module.eks.module.fargate_profile["karpenter"].aws_iam_role_policy_attachment.this["AmazonEKS_CNI_Policy"]
module.eks.module.fargate_profile["kube_system"].data.aws_caller_identity.current
module.eks.module.fargate_profile["kube_system"].data.aws_iam_policy_document.assume_role_policy[0]
module.eks.module.fargate_profile["kube_system"].data.aws_partition.current
module.eks.module.fargate_profile["kube_system"].data.aws_region.current
module.eks.module.fargate_profile["kube_system"].aws_eks_fargate_profile.this[0]
module.eks.module.fargate_profile["kube_system"].aws_iam_role.this[0]
module.eks.module.fargate_profile["kube_system"].aws_iam_role_policy_attachment.this["AmazonEKSFargatePodExecutionRolePolicy"]
module.eks.module.fargate_profile["kube_system"].aws_iam_role_policy_attachment.this["AmazonEKS_CNI_Policy"]
module.eks.module.kms.data.aws_caller_identity.current[0]
module.eks.module.kms.data.aws_iam_policy_document.this[0]
module.eks.module.kms.data.aws_partition.current[0]
module.eks.module.kms.aws_kms_alias.this["cluster"]
module.eks.module.kms.aws_kms_key.this[0]
```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FMcR5weg2n9FAAkLSrC9t%2Fimage.png?alt=media&#x26;token=e7e222d4-5f38-42d5-8af8-125b2ac5f059" alt=""><figcaption></figcaption></figure>

```
# k8s 노드, 파드 정보 확인
kubectl cluster-info
kubectl get node
kubectl get pod -A
```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FzrgBxGBCb7BNl2d23DUm%2Fimage.png?alt=media&#x26;token=e987235c-89eb-4ef0-bbd5-3671624e6394" alt=""><figcaption></figcaption></figure>

* kube-ops-view 설치 : 노드의 파드 상태 정보를 웹 페이지에서 실시간으로 출력해 줍니다.

```
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system

# 포트 포워딩
kubectl port-forward deployment/kube-ops-view -n kube-system 8080:8080

# 접속 주소 확인 : 각각 1배, 1.5배, 3배 크기
echo -e "KUBE-OPS-VIEW URL = http://localhost:8080/#scale=3"
```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FmJOx1HqKhu9cLobt5ujQ%2Fimage.png?alt=media&#x26;token=de1cb325-831d-4c9c-ba03-21d51fd43c46" alt=""><figcaption></figcaption></figure>

* 다음과 같이 local에서 바로 확인할  수 있습니다.

```
// karpenter 설치
helm install karpenter oci://public.ecr.aws/karpenter/karpenter --namespace "default"

// karpenter terraform 실행을 해주면 
kubectl apply -f karpenter.yaml

```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FuNod32mbrH9OXFdxm4p9%2Fimage.png?alt=media&#x26;token=11f1a323-b769-4984-9be1-7fb5b7937217" alt=""><figcaption></figcaption></figure>

```
// deployment 생성하고 3개로 스케일합니다.

kubectl apply -f example.yaml
kubectl scale deployment inflate --replicas=3
```

* 이렇게 provisioning이 되는 것을 확인할 수 있다.

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FYDy60mlZl1Fh7aCiZvpZ%2Fimage.png?alt=media&#x26;token=be38d6f5-a66b-4e3b-97d1-5c00d5643390" alt=""><figcaption></figcaption></figure>

```
terraform destroy -auto-approve
// 으로 vpc, eks, addon 등, 모두 삭제해주면 된다.
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
// kubeconfig 삭제 확인
rm -rf ~/.kube/config 


```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FMbqoCVoCJ63xHt7lUKXH%2Fimage.png?alt=media&#x26;token=b98f5914-56f3-4aea-a89e-84990029e16f" alt=""><figcaption></figcaption></figure>

## 3. EKS Workshop

### 3.1 EKS 배포

```
git clone https://github.com/aws-samples/eks-workshop-v2
terraform init
tree .terraform
cat .terraform/modules/modules.json | jq
tree .terraform/providers/registry.terraform.io/hashicorp -L 2

terraform apply -auto-approve
// 리소스 생성
```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2FEvEKc0u9jrCcJ02bRRkV%2Fimage.png?alt=media&#x26;token=d82c0f60-b444-4463-b8dd-11bf214f00f6" alt=""><figcaption></figcaption></figure>

```
terraform show
// 상세 정보 확인
```

```
# EKS 자격증명
## aws eks --region <REGION> update-kubeconfig --name <CLUSTER_NAME> --alias <CLUSTER_NAME>
aws eks --region ap-northeast-2 update-kubeconfig --name eks-workshop
cat ~/.kube/config

# 각자 자신의 IAM User 의 access entry 생성
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
MYIAMUSER=<각자 자신의 IAM User>
MYIAMUSER=admin

echo $ACCOUNT_ID $MYIAMUSER
aws eks create-access-entry --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER}
aws eks list-access-entries --cluster-name eks-workshop

# 각자 자신의 IAM User에 AmazonEKSClusterAdminPolicy 연동
aws eks associate-access-policy --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster

aws eks list-associated-access-policies --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} | jq
aws eks describe-access-entry --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} | jq
 
# (참고) context name 변경
kubectl config rename-context "arn:aws:eks:ap-northeast-2:$(aws sts get-caller-identity --query 'Account' --output text):cluster/eks-workshop" "T101-Lab"



```

<figure><img src="https://579161259-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1gwifHg6wHBbDMYTGIsL%2Fuploads%2F3GYdJsNRlkYz4WFovKNB%2Fimage.png?alt=media&#x26;token=182fdd0d-5d88-415b-b226-55a51c4a95a2" alt=""><figcaption></figcaption></figure>

* 위와 같이 kube-ops-view를 설치해서 프로비져닝에 대한 모니터링이 바로 가능하다.

```
helm uninstall kube-ops-view -n kube-system

terraform destroy -auto-approve

# VPC 삭제 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml

# kubeconfig 삭제
rm -rf ~/.kube/config
```

* Terraform을 이용한 aws eks 배포를 배웠고, 해당 워크숍에서 terraform으로 빠르고 쉽게 배포할 수 있습니다.
