[AEWS] #9์ฃผ์ฐจ EKS ๋ธ”๋ฃจ ๊ทธ๋ฆฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ with Terraform

25๋…„๋„ AWS EKS Hands-on Study ์Šคํ„ฐ๋”” ์ •๋ฆฌ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.
๋ณธ ์‹ค์Šต ์ฐธ๊ณ  ํŽ˜์ด์ง€ : https://aws-ia.github.io/terraform-aws-eks-blueprints/patterns/blue-green-upgrade/ 

 

๋ธ”๋ฃจ๊ทธ๋ฆฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹ค์Šต

๋ธ”๋ฃจ๊ทธ๋ฆฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด๋ž€

๋ฌด์ค‘๋‹จ ๋ฐฐํฌ๋ฅผ ์‹คํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฐํฌ ์ „๋žต์œผ๋กœ ๋‘ ๊ฐœ์˜ ๊ฑฐ์˜ ๋™์ผํ•œ ์šด์˜ ํ™˜๊ฒฝ(Blue, Green)์„ ํ™œ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฒ„์ „์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐฐํฌํ•˜๊ณ  ๋กค๋ฐฑ ๊ฐ€๋Šฅ์„ฑ๋„ ํ™•๋ณดํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

EKS Blueprints๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋‘ ๊ฐœ ๋ฒ„์ „์˜ ํด๋Ÿฌ์Šคํ„ฐ ๋˜๋Š” ๋‘ ๊ฐœ ๋ฒ„์ „์˜ ๋””ํ”Œ๋กœ์ด๋จผํŠธ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.

 

etc-image-0

 

์‚ฌ์ „ ์ž‘์—…

aws secretsmanager create-secret \
  --name github-blueprint-ssh-key \
  --secret-string "$(cat ~/.ssh/id_rsa.pub)"

 

tfvars ํŒŒ์ผ์—์„œ ์‹œํฌ๋ฆฟ ๋งค๋‹ˆ์ €๋กœ GitHub ๊ฐœ์ธ ssh ํ‚ค ๊ฐ’์„ AWS Secret Manager์˜ ๋น„๋ฐ€์— ์ผ๋ฐ˜ ํ…์ŠคํŠธ๋กœ ์ €์žฅ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ terraform.tfvars.example ์˜ github-blueprint-ssh-keyterraform ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€์ด๋“œ์— ์ ํžŒ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‹œํฌ๋ฆฟ ๋งค๋‹ˆ์ €๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

 

cat ../terraform.tfvars.example
# You should update the below variables

aws_region          = "ap-northeast-2"
environment_name     = "eks-blueprint"
hosted_zone_name    = ์ƒ์„ฑํ•œ ๋„๋ฉ”์ธ
eks_admin_role_name = "Admin" # Additional role admin in the cluster (usually the role I use in the AWS console)

# EKS Blueprint Workloads ArgoCD App of App repository
gitops_workloads_org      = "git@github.com:aws-samples"
gitops_workloads_repo     = "eks-blueprints-workloads"
gitops_workloads_revision = "main"
gitops_workloads_path     = "envs/dev"

#Secret manager secret for github ssk jey
aws_secret_manager_git_private_ssh_key_name = "github-blueprint-ssh-key"

 

terraform.tfvars

cp terraform.tfvars.example terraform.tfvars
ln -s ../terraform.tfvars environment/terraform.tfvars
ln -s ../terraform.tfvars eks-blue/terraform.tfvars
ln -s ../terraform.tfvars eks-green/terraform.tfvars

Environment Stack

cd environment
terraform init
terraform apply

 

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2025-04-03 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 12.18.11.png

 

๋ธ”๋ฃจ ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ

cd eks-blue
terraform init
terraform apply

 

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2025-04-03 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1.18.54.png

access_argocd = <<EOT
export KUBECONFIG="/tmp/eks-********"
aws eks --region ap-northeast-2 update-kubeconfig --name eks-********
echo "ArgoCD URL: https://$(kubectl get svc -n argocd argo-cd-argocd-server -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
echo "ArgoCD Username: admin"
echo "ArgoCD Password: $(aws secretsmanager get-secret-value --secret-id ****-admin-secret.******** --query SecretString --output text --region ap-northeast-2)"
EOT

configure_kubectl = "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********"

eks_blueprints_dev_teams_configure_kubectl = [
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-******** --role-arn arn:aws:iam::************:role/team-burnham-********",
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-******** --role-arn arn:aws:iam::************:role/team-riker-********",
]

eks_blueprints_ecsdemo_teams_configure_kubectl = [
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-******** --role-arn arn:aws:iam::************:role/team-ecsdemo-crystal-********",
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-******** --role-arn arn:aws:iam::************:role/team-ecsdemo-frontend-********",
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-******** --role-arn arn:aws:iam::************:role/team-ecsdemo-nodejs-********",
]

eks_blueprints_platform_teams_configure_kubectl = "aws eks --region ap-northeast-2 update-kubeconfig --name eks-******** --role-arn arn:aws:iam::************:role/team-platform-********"

eks_cluster_id = "eks-********"
gitops_metadata = <sensitive>

 

๋ฐฐํฌ ์™„๋ฃŒ๊นŒ์ง€ ์•ฝ 25๋ถ„๊ฐ€๋Ÿ‰ ๊ฑธ๋ ธ๋‹ค ..!

๊ทธ๋ฆฐ ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ

cd eks-green
terraform init
terraform apply
access_argocd = <<EOT
export KUBECONFIG="/tmp/eks-********"
aws eks --region ap-northeast-2 update-kubeconfig --name eks-********
echo "ArgoCD URL: https://$(kubectl get svc -n argocd argo-cd-argocd-server -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
echo "ArgoCD Username: admin"
echo "ArgoCD Password: $(aws secretsmanager get-secret-value --secret-id ****-admin-secret.******** --query SecretString --output text --region ap-northeast-2)"
EOT

configure_kubectl = "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********"

eks_blueprints_dev_teams_configure_kubectl = [
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********  --role-arn arn:aws:iam::************:role/team-burnham-********",
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********  --role-arn arn:aws:iam::************:role/team-riker-********",
]

eks_blueprints_ecsdemo_teams_configure_kubectl = [
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********  --role-arn arn:aws:iam::************:role/team-ecsdemo-crystal-********",
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********  --role-arn arn:aws:iam::************:role/team-ecsdemo-frontend-********",
  "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********  --role-arn arn:aws:iam::************:role/team-ecsdemo-nodejs-********",
]

eks_blueprints_platform_teams_configure_kubectl = "aws eks --region ap-northeast-2 update-kubeconfig --name eks-********  --role-arn arn:aws:iam::************:role/team-platform-********"

eks_cluster_id = "eks-********"
gitops_metadata = <sensitive>

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2025-04-03 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 1.55.56.png

 

๊ทธ๋ฆฐ ํด๋Ÿฌ์Šคํ„ฐ๋„ ํ™œ์„ฑํ™”๋˜์—ˆ๋‹ค.

 

๋ฐฐํฌ๋œ argocd repourl ๋ณ€๊ฒฝํ•˜๊ธฐ

etc-image-4

 

๋ถ„๋ช… ์‹ค์Šต๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ”๋Š”๋ฐ... ๋ฐฐํฌ๋œ ํŒŒ๋“œ๊ฐ€ ์•ˆ๋ณด์ด๋Š” ๊ฒƒ์ด์˜€๋‹ค..? ์™œ์ผ๊นŒ ํ•˜๊ณ  ArgoCD์— ๋“ค์–ด๊ฐ€๋ณด๋‹ˆ

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2025-04-03 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 4.19.09.png

 

ํ…Œ๋ผํผ์œผ๋กœ ์ƒ์„ฑํ–ˆ๋”๋‹ˆ ๋ ˆํฌ Url์ด.. ๊นƒ์ด ๊ธฐ๋ณธ์œผ๋กœ ๋ผ์žˆ์–ด์„œ https๊ฐ€ ์•„๋‹ˆ์˜€๋‹ค ์œผ์•„์•…!

๊ทธ๋ž˜์„œ...

kubectl patch secret eks-blueprint-blue -n argocd --type merge \
  -p '{"metadata": {"annotations": {"addons_repo_url": "https://github.com/aws-samples/eks-blueprints-add-ons.git"}}}'

 

๊ฐ ์•ฑ์—์„œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์€ ๊นƒ์˜ต์Šค ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ฏ€๋กœ ์ด๋ ‡๊ฒŒ.. ์•„์˜ˆ ์‹œํฌ๋ฆฟ์„ ์ˆ˜์ •ํ•ด์ฃผ์—ˆ๋‹ค.

 

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2025-04-03 แ„‹แ…ฉแ„Œแ…ฅแ†ซ 4.27.09.png

 

๋ ˆํฌ ๊ฒฝ๋กœ๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ๊ณ  ์ œ๋Œ€๋กœ ์‹ฑํฌ๊ฐ€ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

k get po -A
NAMESPACE           NAME                                                        READY   STATUS      RESTARTS   AGE
amazon-cloudwatch   aws-cloudwatch-metrics-clvpt                                1/1     Running     0          11m
amazon-cloudwatch   aws-cloudwatch-metrics-f92k6                                1/1     Running     0          11m
amazon-cloudwatch   aws-cloudwatch-metrics-jww4k                                1/1     Running     0          11m
argocd              argo-cd-argocd-application-controller-0                     1/1     Running     0          12m
argocd              argo-cd-argocd-applicationset-controller-55c4c79d49-hrrxs   1/1     Running     0          3h20m
argocd              argo-cd-argocd-dex-server-6c5d66ddf7-lw8ls                  1/1     Running     0          3h20m
argocd              argo-cd-argocd-notifications-controller-69fd44d464-kzrxs    1/1     Running     0          3h20m
argocd              argo-cd-argocd-redis-5f474f9d77-cchxz                       1/1     Running     0          3h20m
argocd              argo-cd-argocd-repo-server-544b5b8d66-5qspv                 1/1     Running     0          93s
argocd              argo-cd-argocd-repo-server-544b5b8d66-86jjn                 1/1     Running     0          10m
argocd              argo-cd-argocd-repo-server-544b5b8d66-p2lpx                 1/1     Running     0          11m
argocd              argo-cd-argocd-repo-server-544b5b8d66-rrmms                 1/1     Running     0          12m
argocd              argo-cd-argocd-repo-server-544b5b8d66-zr9lh                 1/1     Running     0          92s
argocd              argo-cd-argocd-server-dbbd888c8-9zlqw                       1/1     Running     0          12m
cert-manager        cert-manager-5c84984c7b-tftk7                               1/1     Running     0          11m
cert-manager        cert-manager-cainjector-67b46dfbc4-4vbbc                    1/1     Running     0          11m
cert-manager        cert-manager-webhook-557cf8b498-qrcs7                       1/1     Running     0          11m
external-dns        external-dns-6bc79b4c7f-l2w8n                               1/1     Running     0          11m
external-secrets    external-secrets-5f7fc744fb-ntn8p                           1/1     Running     0          11m
external-secrets    external-secrets-cert-controller-6ddf99cb9d-r7wrf           1/1     Running     0          11m
external-secrets    external-secrets-webhook-64449c7c97-d6ccz                   1/1     Running     0          11m
geolocationapi      geolocationapi-7f6bfb647d-v52mm                             2/2     Running     0          82s
geolocationapi      geolocationapi-7f6bfb647d-vdtkb                             2/2     Running     0          82s
geordie             downstream0-7999f7bc68-nlsft                                1/1     Running     0          109s
geordie             downstream1-5ff6b6fd8c-k8pf8                                1/1     Running     0          109s
geordie             frontend-65766fdccc-lcrpf                                   1/1     Running     0          109s
geordie             redis-server-76d7b647dd-28hlq                               1/1     Running     0          109s
geordie             yelb-appserver-56d6d6685b-mwzbc                             1/1     Running     0          109s
geordie             yelb-db-5dfdd5d44f-dvvvk                                    1/1     Running     0          109s
geordie             yelb-ui-56545895f-4zh8r                                     1/1     Running     0          109s
ingress-nginx       ingress-nginx-controller-85b4dd96b4-2lncv                   1/1     Running     0          11m
ingress-nginx       ingress-nginx-controller-85b4dd96b4-8cvdk                   1/1     Running     0          11m
ingress-nginx       ingress-nginx-controller-85b4dd96b4-xst7z                   1/1     Running     0          11m
karpenter           karpenter-5dfb76b559-2tgtr                                  1/1     Running     0          11m
karpenter           karpenter-5dfb76b559-xg4vt                                  1/1     Running     0          11m
kube-system         aws-for-fluent-bit-6pmdh                                    1/1     Running     0          12m
kube-system         aws-for-fluent-bit-75k28                                    1/1     Running     0          12m
kube-system         aws-for-fluent-bit-lcl44                                    1/1     Running     0          12m
kube-system         aws-load-balancer-controller-7c68859454-2q5zn               1/1     Running     0          11m
kube-system         aws-load-balancer-controller-7c68859454-mh9l9               1/1     Running     0          11m
kube-system         aws-node-mzl6k                                              2/2     Running     0          3h35m
kube-system         aws-node-ntwxl                                              2/2     Running     0          3h35m
kube-system         aws-node-p8w8g                                              2/2     Running     0          3h35m
kube-system         coredns-767f9b58bd-cfv4j                                    1/1     Running     0          3h36m
kube-system         coredns-767f9b58bd-g7hjb                                    1/1     Running     0          3h36m
kube-system         kube-proxy-g8c7g                                            1/1     Running     0          3h35m
kube-system         kube-proxy-vsv65                                            1/1     Running     0          3h35m
kube-system         kube-proxy-x4gmg                                            1/1     Running     0          3h35m
kube-system         metrics-server-8794b9cdf-m9gkg                              1/1     Running     0          11m
kyverno             kyverno-admission-controller-757766c5f5-w6rr5               1/1     Running     0          10m
kyverno             kyverno-background-controller-bc589cf8c-2whdj               1/1     Running     0          10m
kyverno             kyverno-cleanup-admission-reports-29060370-w5hr7            0/1     Completed   0          7m30s
kyverno             kyverno-cleanup-cluster-admission-reports-29060370-s8csj    0/1     Completed   0          7m30s
kyverno             kyverno-cleanup-controller-5c9fdbbc5c-2sskr                 1/1     Running     0          10m
kyverno             kyverno-reports-controller-6cc9fd6979-bzw9v                 1/1     Running     0          10m
team-burnham        burnham-869784cc9c-5ghwd                                    1/1     Running     0          117s
team-burnham        burnham-869784cc9c-ds9kz                                    1/1     Running     0          117s
team-burnham        burnham-869784cc9c-qgbck                                    1/1     Running     0          117s
team-burnham        nginx-5769f5bf7c-d5s7s                                      1/1     Running     0          117s
team-riker          deployment-2048-85c46566b7-j9r2s                            1/1     Running     0          116s
team-riker          deployment-2048-85c46566b7-kr89z                            1/1     Running     0          116s
team-riker          deployment-2048-85c46566b7-tf5kp                            1/1     Running     0          116s
team-riker          guestbook-ui-6bb6d8f45d-lvf25                               1/1     Running     0          116s

 

์ด ์ƒํƒœ์—์„œ ๋“œ๋””์–ด ์•ฑ์ด ์ œ๋Œ€๋กœ ๋ฐฐํฌ๊ฐ€ ๋˜์–ด ํŒŒ๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ™•์ธ๋œ๋‹ค.

 

burnham pod ํ™•์ธ

kubectl get deployment -n team-burnham -l app=burnham
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
burnham   3/3     3            3           2m45s
nginx     1/1     1            1           2m45s

kubectl get pods -n team-burnham -l app=burnham
NAME                       READY   STATUS    RESTARTS   AGE
burnham-869784cc9c-5ghwd   1/1     Running   0          2m54s
burnham-869784cc9c-ds9kz   1/1     Running   0          2m54s
burnham-869784cc9c-qgbck   1/1     Running   0          2m54s

kubectl logs -n team-burnham -l app=burnham
2025/04/02 19:37:21 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:37:31 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:37:36 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:37:46 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:37:51 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:38:01 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:38:06 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:38:16 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:38:21 {url: / }, cluster: eks-blueprint-blue }
2025/04/02 19:38:31 {url: / }, cluster: eks-blueprint-blue }

 

curl -s ***.ap-northeast-2.elb.amazonaws.com | grep CLUSTER_NAME | awk -F "<span>|</span>" '{print $4}'
eks-blueprint-blue

 

๋ธ”๋ฃจ -> ๊ทธ๋ฆฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

etc-image-7

cat eks-blue/main.tf | grep route
  argocd_route53_weight      = "100"
  route53_weight             = "100"
  ecsfrontend_route53_weight = "100"

cat eks-green/main.tf | grep route
  argocd_route53_weight      = "0" # We control with theses parameters how we send traffic to the workloads in the new cluster
  route53_weight             = "0"
  ecsfrontend_route53_weight = "0"

 

ํ˜„์žฌ๋Š” DNS ๋ ˆ์ฝ”๋“œ์˜ ๊ฐ€์ค‘์น˜๊ฐ€ eksโ€‘blue์— 100, eksโ€‘green์— 0์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ์–ด ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์ด eksโ€‘blue๋กœ๋งŒ ๋ผ์šฐํŒ…๋œ๋‹ค.

 

main.tf

module "eks_cluster" {
  source = "../modules/eks_cluster"

  aws_region      = var.aws_region
  service_name    = "green"
  cluster_version = "1.27"

  argocd_route53_weight = "0"
  route53_weight        = var.route53_weight
}

 

variables.tf

variable "route53_weight" {
  type        = string
  description = "Route53 weight for DNS records"
  default     = "50"
}

 

 

eks-blueprint-blue
eks-blueprint-blue
eks-blueprint-blue
eks-blueprint-green
eks-blueprint-green
eks-blueprint-green