ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • terraform으로 스프링부트 빠르게 배포하기 with ELB
    terraform 2023. 8. 13. 14:37

    https://xodns.tistory.com/136

     

    terraform으로 스프링부트 빠르게 배포하기 with nginx

    https://github.com/TaeWoonJeong/terraform-spring-nginx GitHub - TaeWoonJeong/terraform-spring-nginx Contribute to TaeWoonJeong/terraform-spring-nginx development by creating an account on GitHub. github.com 사전 준비 사용자 2명을 만들겁니다.

    xodns.tistory.com

    이전 포스팅을 한번 읽어보고 오면 좋다.

    https://github.com/TaeWoonJeong/terraform-spring-alb

     

    GitHub - TaeWoonJeong/terraform-spring-alb

    Contribute to TaeWoonJeong/terraform-spring-alb development by creating an account on GitHub.

    github.com

    사전 준비

    이번에도 역시 사용자 2명으로 진행합니다.

    1. terraform 사용자는, 이전 포스팅과 같게 정책 설정을 해준다음

    AmazonEC2FullAccess
    AmazonS3FullAccess
    AWSCodeDeployFullAccess
    IAMFullAccess

    추가로 ALB를 생성할것이므로

    ElasticLoadBalancingFullAccess

    를 추가해줍시다.

    2. spring build를 하고, s3에 올리고, codedeploy를 작동시키기 위한 사용자를 하나 만들어줍니다.

    이전 포스팅과 동일하게 만들어줍시다.

    3. state를 저장해주는 버킷을 하나 만들어줍시다.

    4. 빌드해서 나온 spring.zip 파일을 저장해줄 버킷을 만들어줍니다.

    5. ALB의 액세스 로그를 저장해줄 버킷을 만들어줍니다.

    ALB에서 버킷에 로그를 쓰기 위해 권한 설정을 해줘야합니다.

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::REGION이름을 적어줍니다.:root"
                },
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::버킷이름/프리픽스(terraform 설정과 같게써줍니다.)/AWSLogs/AWS계정ID/*"
            },
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "logdelivery.elb.amazonaws.com"
                },
                "Action": "s3:GetBucketAcl",
                "Resource": "arn:aws:s3:::버킷이름"
            }
        ]
    }

    리전이름은 ap-northeast-2 처럼 적는게 아니라,

    https://docs.aws.amazon.com/ko_kr/elasticloadbalancing/latest/application/enable-access-logging.html

     

    Application Load Balancer 액세스 로그 활성화 - Elastic Load Balancing

    Application Load Balancer 액세스 로그 활성화 로드 밸런서에 대한 액세스 로그를 활성화할 때는 로드 밸런서가 로그를 저장할 S3 버킷의 이름을 지정해야 합니다. 버킷에 액세스 로그를 쓰는 Elastic Load

    docs.aws.amazon.com

    에 가서, 리전을 보고 숫자를 입력하면 됩니다.

    저는 ap-notheast-2 이므로, 가이드에 나온 숫자는 600734575887 라고 합니다.

    버킷이름은 알아서 적으시면 되고, prefix는 테라폼에서 alb-log 라고 써줬으니, 여기서도 alb-log라고 써주면 됩니다.

    만약 terraform 에서 prefix 가 없다면, 안써주면 됩니다.

    AWS계정ID는

    우측상단에서 확인하시면 됩니다.

    6. codedeploy의 어플리케이션을 생성해줍니다.

    workflow를 보면, spring-alb-deploy 라고 적어줬으므로, 이렇게 만들어줍시다.

    로컬에서 테라폼만 따로 실행하려면, aws cli 를 설치한다음, configure를 terraform 사용자로 해줘야 작동합니다.

    스프링 설명

    spring boot 어플리케이션을 하나 만들어준다.

    @RestController
    class Controller {
        val uuid: String = UUID.randomUUID().toString()
        @GetMapping("/health")
        fun health() : String{
            return "OK"
        }
    
        @GetMapping("/info")
        fun info() : String {
            return "현재 시간은 "+ LocalDateTime.now() + "이고, uuid 값 : "+uuid
        }
    }

    target_group이 health체크를 할 경로는 health로 했고, 실제로 로드밸런싱이 잘 되는지 확인은 info 로 들어가면 된다.

    ec2 2개에 각각의 스프링이 실행될것이므로, 정상적으로 로드밸런싱이 된다면, 새로고침할 때마다 UUID값이 바뀔것이다.

     

    테라폼 설명

    1. vpc 를 만든다.

    2. 만든 vpc 의 subnet을 두개 만들어준다.(ALB를 사용할 것이므로 서브넷을 최소 2개 이상 만들어야합니다.)

    3. ec2가 인터넷이 가능해야하므로, 만든 vpc에 인터넷 게이트웨이를 만들어준다.

    4. ec2가 인터넷이 가능해야하므로, 라우팅테이블에 만든 subnet들과 인터넷 게이트웨이를 연결시켜줍니다.(ec2 생성시에 subnet을 선택하는데, 이때 만든 subnet을 선택해주면, private IP가 아니라면, 즉 0.0.0.0/0 이라면 인터넷으로 내보내는 설정을 한겁니다.)

     

    순서에 상관없는 것들

    security-group 생성, key-pair 생성을 해줍니다.

     

    다음으로 ec2가 생성됩니다. 만들면서, eip와 sg, key-pair을 연결해줍니다.

     

    생성이 완료되었다면, role을 만들어주고, ec2와 codedeploy-group에 각각 연결해줍니다.

     

    마지막으로 alb가 생성되고, target group 가 생성됩니다.

     

    성공한다면, 최상위 main.tf에서

      backend "s3" {
        bucket = "tw-spring-alb-tfstate"
        key    = "terraform.tfstate"
        region = "ap-northeast-2"
      }

    설정이 있어서 성공한다면 state파일을 s3에 저장해줍니다.

     

    ALB 설명

    resource "aws_lb" "tw_alb" {
      name               = var.alb_name
      internal           = false
      load_balancer_type = "application"
      security_groups    = [var.aws_sg_id]
      subnets            = var.aws_subnet_ids
    
      access_logs {
        bucket  = "tw-alb-log"
        prefix  = "alb-log"
        enabled = true
      }
    }

    alb를 만들어주고, sg를 연결합니다. 

    물론 sg에는 80번만 열려있으면 됩니다.

    sg를 나누기에는 설정이 너무 복잡해져서 하나로 묶었습니다.

     

    resource "aws_lb_listener" "tw_alb_listener" {
      load_balancer_arn = aws_lb.tw_alb.arn
      port              = "80"
      protocol          = "HTTP"
    
      default_action {
        type             = "forward"
        target_group_arn = aws_lb_target_group.tw_target_group.arn
      }
    }

    80번으로 요청이 온다면, target_group으로 보내줍니다.

     

    resource "aws_lb_target_group" "tw_target_group" {
      name     = var.alb_target_group_name
      port     = 80
      protocol = "HTTP"
      vpc_id   = var.aws_vpc_id
    
      health_check {
        healthy_threshold   = 2
        unhealthy_threshold = 2
        timeout             = 3
        interval            = 30
        path                = "/health"
      }
    }

    target_group는 80번으로 받아서 health_check를 해줍니다.

     

    resource "aws_lb_target_group_attachment" "tw_target_group_attachment" {
      count            = length(var.aws_ec2_instance_ids)
      target_group_arn = aws_lb_target_group.tw_target_group.arn
      target_id        = var.aws_ec2_instance_ids[count.index]
      port             = 8080
    }

    health_check를 해줄 ec2에는 nginx가 없으므로 8080번 포트로 health check를 해줍니다.

     

    정리하자면, ec2의 8080번 포트로 health_check를 해주는 target_group이 성공한다면, 인터넷에서 80번 포트로 ALB의 DNS로 요청을 했을 때, ALB는 target_group들에게 로드밸런싱을 해줍니다.

    우선순위가 같으므로, 50대50으로 동등하게 나눠서 요청이 갑니다.

    또한 ALB의 access_log 설정도 했으므로, s3에 가서 로그를 볼 수도 있습니다.

     

    github actions workflow 설명

    이전 포스팅과 같습니다. 버킷 이름이나 deploy application-name 이 변경되었습니다.

     

    성공모습

    DNS이름을 복사해서 /info 로 접속하면 잘 되는것을 볼 수 있다.

    ec2 2개가 올라갔다.

    로드밸런싱이 잘 되는것을 볼 수 있다.

    로그도 잘 저장된다.

    보완할 점

    이것도 역시 다운타임이 너무 길다.

Designed by Tistory.