ABOUT ME

-

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

    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명을 만들겁니다.

    1. terraform을 사용하면서, ec2생성을 위해

    AmazonEC2FullAccess

    s3에 state저장을 위해

    AmazonS3FullAccess

    codedeploy deployment group 을 만들기 위해

    AWSCodeDeployFullAccess

    role 생성을 위해

    IAMFullAccess

    를 주고, 사용자를 만든다음, 키를 만들어서 저장해준다.

    2. github actions으로 spring을 build하고, s3와 codedeploy를 작동시키기 위한 사용자를 하나 더 만든다.

    s3에 zip 파일을 올릴것이므로

    AmazonEC2FullAccess

    를 주고, codedeploy의 deploy를 생성할 것이므로,

    AWSCodeDeployFullAccess

    를 주고, 사용자를 만들고, key를 저장해준다.

     

    s3에 state를 저장하는 적절한 이름의 버킷을 하나 만들어준다.

    스프링을 빌드해서 나온 zip 파일을 저장하는 버킷을 만들어준다.

    버킷이름은 unique해야하므로, 코드 클론 후, 실행하면 이미 있어서 에러납니다.

     

    codedeploy어플리케이션을 만들어준다.

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

    스프링 설명

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

    @RestController
    class Controller {
        @GetMapping("/")
        fun getTime(): String {
            return LocalDateTime.now().toString()
        }
    }

    기본경로로 요청이 오면 현재 시간을 반환해준다.

     

    테라폼 설명

    1. vpc 를 만든다.

    2. 만든 vpc 의 subnet을 하나 만들어준다.

    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에 각각 연결해줍니다.

     

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

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

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

     

    github actions workflow 설명

    3가지 job들로 나뉩니다.

    1. Destroy

    s3에서 state를 받아옵니다.

    정상적으로 받았다면 destroy를 해줍니다.(최초실행이면 실패하므로, 실패해도 넘어가게 만들었습니다.)

     

    2. Create

    terraform을 적용시켜줍니다.

    성공한다면 s3에 state를 저장해줍니다.

     

    3. BuildAndDeploy

    spring 을 build 합니다.

    성공하면, s3에 zip파일을 올립니다.

    codedeploy의 deploy를 만들어줍니다.

    codedeploy에서는 deploy를 할 때 appspec.yml을 보고, 만들어준 start.sh을 실행시켜줍니다.

     

    destroy만 하기위해, Create에서는 apply 부분과, BuildAndDeploy 부분에서

            if: github.ref == 'refs/heads/develop' && github.event_name == 'push'

    를 추가해서,

      workflow_dispatch:

    사용자가 위의 코드로 인해 수동으로 jobs를 실행한다면, state가 s3에 있다는 전제하에 destroy만 작동하고, create에서는 plan 까지만 실행, BuildAndDeploy 에는 s3에 업로드까지만 실행됩니다.

    즉 Destroy만 된다는 거죠 ㅎㅎ

    수동 실행시 state가 있는 경우 리소스들 삭제한 모습
    수동실행해서 apply 가 적용되지 않았습니다.
    s3업로드까지만 하고 codedeploy는 패스합니다.(연결해줄 ec2가 없어졌기 때문이예요)

    성공모습

    github actions 성공
    ec2 생성 성공
    state 저장 성공
    spring build 해서 zip파일로 s3 업로드 성공
    codedeploy group 생성 성공
    deploy 생성 성공
    EC2퍼블릭 IP로 인터넷 연결 성공

     

    요약

    develop 브랜치에 push를 하면, 기존에 생성된 ec2와 여러가지 리소스들을 전부 지워주고, 다시 생성한다음, 스프링 앱을 배포해준다.

    다음에는 ec2 2개를 올리고, ELB를 앞에 달아서, 로드밸런싱이 잘 되는지 알아보겠다.

    그러기 위해서는 spring 코드를 변경해야하므로, 새롭게 레포지토리를 파서 포스팅하겠습니다.

     

    보완할 점

    다운타임이 너무 길다. 없애보자.

Designed by Tistory.