Skip to content

[IAM 기반의 배포 및 분산 환경 조성]

SEUNGUN CHAE edited this page Aug 26, 2024 · 3 revisions

Background

  • 팀 어썸오렌지는 배포 환경에서 사용되는 민감한 환경변수를 AWS System Manager의 Parameter Store에 보관하고, 프로젝트 빌드 시 관련 명령어를 실행해 변수를 가져와 사용할 수 있도록 했습니다.
  • 기존엔 관련 명령어를 실행하여 .env 파일을 만든 뒤 배포 환경에서 사용할 수 있게 CD 파이프라인을 구축했으나, 이 경우 Parameter Store 내역 갱신 시 변경사항을 배포 환경에서 수동으로 반영해야 하는 번거로움이 있었습니다.
  • 이를 해결하기 위해, 최신 버전 기준의 환경변수를 가져와 사용할 수 있도록 CD 파이프라인을 수정하였고, 이를 통해 Self-hosted Runner 기반으로 배포 환경에서 미리 설정해둔 accessKey를 통해 AWS Parameter Store에 접근하도록 설정했습니다.
      - name: Run Updated Docker Container
        run: sudo docker run -t --env-file ~/.env -d --name orange -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/orange
        run: sudo docker run -t -d --name orange -p 8080:8080 \
          --env SERVER_SECRET=$(aws ssm get-parameter --name ${{ secrets.SSM_PARAMETER_NAME }} --with-decryption --region ${{ secrets.SSM_PARAMETER_REGION }} --query "Parameter.Value" --output text) \
          ${{ secrets.DOCKERHUB_USERNAME }}/orange
  • 그러나, 이러한 접근 방식은 두 가지 문제가 있었습니다.
  1. AWS accessKey가 서버 인스턴스 안에 저장되므로 유출될 위험이 존재합니다.
  2. 오토 스케일링으로 여러 인스턴스가 동시에 운영될 경우 모든 인스턴스에 accessKey를 설정해주어야 환경변수를 얻어올 수 있기에 확장성이 떨어집니다.
  • AWS accessKey를 EC2 인스턴스 안에서 직접 설정하는 것이 문제의 원인이라고 진단하였고, AWS의 IAM을 통해 이러한 문제를 해결하고자 했습니다.

IAM이란?

  • AWS에서 제공하는 리소스 접근 제어 관리 서비스입니다.
  • 특정 권한을 가진 사용자 및 그룹을 생성하고 접근 권한을 세밀하게 제어할 수 있다는 강점이 있습니다.
  • 팀 어썸오렌지는 IAM이 제공하는 역할 기반 접근 제어(RBAC)를 통해 당면한 문제를 해결할 수 있다고 생각했습니다.

IAM Role 도입

image image
  • IAM에서 Parameter store 접근을 위해 AmazonSSMReadOnlyAccess 권한을 가진 Role을 생성하고, 이를 Springboot 서버를 실행하는 EC2 인스턴스에 할당했습니다.
  • 이제 IAM Role을 통해 accessKey 없이도 환경변수를 가져와 민감한 작업을 수행할 수 있게 되었습니다. 실제로 CD 파이프라인 모니터링 결과 정상적으로 동작하는 것을 확인했습니다.

분산 환경에서의 빌드 실패 문제

  • 현재 IAM Role을 통해 EC2 인스턴스에 환경변수를 가져올 수 있게 만들었지만, 오토스케일링을 통해 태어난 인스턴스들은 서버 빌드를 위해 필요한 추가 의존성이 없다는 것을 깨달았습니다.
version: '3.8'

services:
  spring_server:
    image: ${DOCKERHUB_USERNAME}/orange
    container_name: orange
    env_file:
      - ../.env
    ports:
      - "8080:8080"
    volumes:
      - /var/log/spring-boot:/var/log/spring-boot
    environment:
      - TZ=Asia/Seoul
    networks:
      - my_custom_network

  promtail:
    image: grafana/promtail
    container_name: promtail
    env_file:
      - ../.env
    ports:
      - "9080:9080"
    volumes:
      - ./promtail-config.yml:/promtail-config.yml
      - /var/log/spring-boot:/var/log/spring-boot
    command:
      - -config.file=/promtail-config.yml
      - -config.expand-env=true 
    environment:
      - TZ=Asia/Seoul
    networks:
      - my_custom_network

networks:
  my_custom_network:
    driver: bridge
  • 팀 어썸오렌지의 백엔드 서버는 Dockerhub에서 image로 관리하는 springboot와, 로그 수집을 위한 promtail을 docker-compose로 빌드하고 있습니다. 이 과정에서 Parameter Store에 보관된 환경 변수를 사용합니다.
image

image

  • 새 인스턴스의 환경 설정을 위해 docker, docker-compose 등이 설치된 EC2 인스턴스를 AMI로 만들어 시작 템플릿에 연결하고, 이를 오토스케일링 그룹에지정했습니다.

image

  • 앞서 만들어둔 IAM Role을 시작 템플릿 설정에 추가한다면 이 템플릿을 활용한 새로운 인스턴스가 태어날 때 설정한 Role이 자동으로 설정됩니다.

  • 한편, 시작 템플릿 기반 인스턴스들이 S3에 있는 빌드 관련 파일에 접근하고 실행할 수 있도록 IAM Role에 AmazonS3FullAccess 권한을 추가하고, 시작 템플릿의 user data에 스크립트를 추가해주었습니다.

# Retrieve environment variables from SSM Parameter Store
sudo aws ssm get-parameter --name ${Parameter Name} --with-decryption --region ap-northeast-2 --query "Parameter.Value" --output text > /home/ubuntu/.env

# Download the docker-compose.yml and promtail-config.yml from S3
aws s3 cp s3://${S3 Bucket Name}/docker-compose.yml /home/ubuntu/docker-compose.yml
aws s3 cp s3://${S3 Bucket Name)/promtail-config.yml /home/ubuntu/promtail-config.yml

# Update Docker image
sudo docker pull ${Dockerhub Name}/orange

# Navigate to the directory containing the docker-compose.yml file
cd /home/ubuntu/

# Run Docker Compose
sudo docker-compose up -d

# Clear Old images
sudo docker image prune -f

이를 통해 오토스케일링으로 생성되는 인스턴스들이 시작 템플릿에 부여된 IAM Role을 통해 필요한 의존성을 가져와 서버를 문제 없이 빌드할 수 있게 되었습니다.

결론

  • IAM Role을 바탕으로 한 접근 제어를 통해, 인스턴스별 accessKey 등록 없이도 서비스 운영에 필수적인 작업을 수행할 수 있게 되었습니다.
  • 분산 환경 관리에서도 IAM Role을 활용하여 인스턴스가 서버 빌드를 위해 필요로 하는 외부 접근을 안전하게 처리할 수 있게 되었습니다.
  • Grafana & Prometheus 기반의 모니터링용 EC2에도 오토스케일링 그룹의 인스턴스들이 생성하는 로그와 서버 메트릭을 수집할 수 있는 IAM Role 및 Policy를 할당하여 온전한 분산 환경에서의 지표 관리를 실현했습니다.

개선점

  • IAM Role의 권한이 Full Access로 설정된 부분이 일부 있습니다. 정말 필요한 권한 위주로만 정밀한 Role 설정을 통해 권한 관련 잠재적인 보안 문제를 예방할 수 있을 것입니다.
  • 현재 S3에 docker-compose.yml과 promtail-config.yml을 보관하고 있는데, 이 구조를 앞으로도 유지한다면 원활한 관리를 위해 CI 파이프라인에 버전 관리를 추가해야 합니다.
  • 나아가 CD 파이프라인을 개선해 오토스케일링 그룹 전체에 실시간 배포를 가능하게 하면 더욱 안정적인 서비스 운영이 가능합니다. 이를 위해 CodeDeploy 등의 추가적인 도구를 검토할 수 있습니다.