Secrets Manager 이용해서 환경변수 적용하기(IAM 정책, Spring Boot 코드 수정)
지난 포스팅에서 ECS 태스크에서 Secrets Manager에 접근할 수 없어서 태스크 정의가 생성되지도 않았다. 이번 포스팅에서 IAM 정책을 추가해 주고 에러를 해결해 보자.
1. IAM 정책 연결해 주기
ECS 태스크가 Secrets Manager에 접근할 수 있도록 ecsTaskExecutionRole 역할에 권한을 부여해야 한다.
1. IAM > 역할 화면에 들어가서 내게 필요한 ecsTaskExecutionRole을 검색한다.
2. 역할 이름을 클릭해서 들어가면 나에게 필요한 'SecretsManagerReadWrite' 권한이 없다.
- 현재 ecsTaskExecutionRole에 연결된 권한 정책은 ECS Task 실행 권한밖에 없다.
3. 우측에 [권한 추가 > 정책 연결]을 클릭한다.
4. 기타 권한 정책 부분에 'SecretsManagerReadWrite' 정책을 체크하고 [권한 추가] 버튼을 클릭한다.
- 이 권한을 추가해 주면 ECS Task 가 Secrets Manager에 접근할 수 있다.
5. 그럼 ecsTaskExecutionRole 역할에 SecretsManagerReadWrite 권한이 추가된 모습을 볼 수 있다.
6. 다시 태스크 정의 화면으로 돌아와서 '태스크 역할' 부분을 새로고침하고 다시 선택하고 생성해 봤다.
7. 그래도 생성이 안 되는 오류가 난다.
8. 다시 보니 "태스크 역할" 이 아니라 [작업 실행 IAM 역할 > 작업 실행 역할]에서 ecsTaskExecutionRole을 선택해야 했던 것이다.
9. 작업 실행 역할에 ecsTaskExecutionRole을 선택하고 태스크 정의를 생성하니 잘 생성된다.
2. Spring Boot 어플리케이션 코드에 환경 변수 수정
1. application.yml 파일을 수정한다.
- {} 안에 들어가는 변수명은 secrets manager에서 key값으로 설정한 이름을 넣어주면 된다.
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: {url}
username: {username}
password: {password}
3. 클러스터에 새로 정의한 태스크 정의 적용하기
1. 이제 실행 중인 클러스터에서 서비스 상세화면으로 이동한다.
2. 우측에 [서비스 업데이트]를 클릭한다.
3. 업데이트 화면에서 "패밀리"를 방금 생성한 태스크로 선택해 준다.
4. 그리고 페이지 하단에 [업데이트]를 클릭한다
5. 그럼 재배포가 이루어지는데 실패했다,,
- 아래 오류 메시지를 보면 Spring Boot가 실행되는 시점에 {url}을 읽어오지 못해서 생기는 에러였다.
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
※ 그런데 지금 재배포가 실패했는데도 DNS로 접속해 보면 정상 작동한다. 배포에서 실패했으면 서버가 전부 꺼져야 하지 않나? 싶은데 계속 정상 작동하는 이유가 궁금하다면 아래 포스팅을 참고하면 된다.
4. 태스크 정의 환경 변수 적용 테스트
1. 위에서 생긴 에러를 해결하기 전에 일단 태스크에서 환경 설정이 ECS에서 배포할 때 제대로 적용이 되는지 확인하기 위해 환경 변수 설정할 때 "Value"로 선택하고 Secrets Manager의 ARN을 넣는 게 아니라 실제 값을 넣어줬다.
- username : 마스터 아이디
- password : 마스터 암호
- url : jdbc:postgresql://rds 엔드포인트:포트/데이터베이스명
2. 그리고 Spring Boot 코드도 수정해줘야 했다.
- 환경 변수를 사용하여 Spring Boot 애플리케이션의 application.yml 설정을 구성할 때, 실제 환경 변수의 값을 참조하려면 다음과 같이 ${} 구문을 사용해야 한다는 걸 발견했다.
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: ${url}
username: ${username}
password: ${password}
3. 그랬더니 정상 배포되었다.
4. 그럼 이제 ECS 태스크 정의에서 환경 변수 적용이 잘 된다는 것까지는 확인을 했다. 이제 Secrets Manager에서 Value값을 가져와서 세팅해 주는 걸 찾아보자.
5. 태스크 정의에서 Secrets Manager 환경 변수 설정
1. 일단 환경 설정에서 Secrets manager의 값을 참조하는 두 가지 방법이 있다.
첫 번째는 secret의 ARN 지정이다.
- 비밀의 전체 ARN을 valueFrom 키와 함께 지정한다.
- 예를 들어, arn:aws:secretsmanager:region:account-id:secret:secret-name-abc123 이런 형식을 따른다.
두 번째는 secret key 참조다.
- 비밀 내의 특정 값을 참조하려면, ARN 뒤에 콜론(:)을 추가하고 키 이름을 명시하면 된다.
- 예를 들어, arn:aws:secretsmanager:region:account-id:secret:secret-name-abc123:key::
2. Secret key 참조를 더 자세히 살펴보자.
- 예를 들어, secret-name이라는 이름의 secret이 있고 그 안에 다음과 같은 JSON 객체가 저장되어 있다고 가정해 보자.
{
"url": "jdbc:postgresql://database-url:5432/database-name",
"username": "your-username",
"password": "your-password"
}
- 그리고 이 secret의 보안 암호 ARN이 arn:aws:secretsmanager:region:account-id:secret:secret-name-abCDe 라고 가정하자.
3. 그럼 ECS 태스크 정의 내에서 이 secret을 참조하는 방법은 다음과 같다.
- 주의! ARN을 지정할 때, secret의 고유 식별자 (예: abDCe)를 포함해야 한다.
{
"name": "url",
"valueFrom": "arn:aws:secretsmanager:region:account-id:secret:secret-name-abCDe:url::"
},
{
"name": "username",
"valueFrom": "arn:aws:secretsmanager:region:account-id:secret:secret-name-abCDe:username::"
},
{
"name": "password",
"valueFrom": "arn:aws:secretsmanager:region:account-id:secret:secret-name-abCDe:password::"
}
4. 위 방법처럼 Task 정의에서 환경 변수를 설정할 때 아래와 같이 작성하고 배포를 했다.
5. 그럼 아래와 같이 정상 작동하는 로그를 볼 수 있다!!
6. 마무리
AWS ECS와 Secret Manager를 연동하는 과정이 처음엔 간단해 보였다.
환경 변수를 설정하고 키 값을 사용하기만 하면 될 줄 알았는데 이게 Spring Boot 코드, ECS의 Task 정의, 그리고 CodePipeline까지 모두 연결되어 있어서, 이를 해결하고 확인하는 데 예상보다 많은 시간이 걸렸다.
개발 환경에서는 IntelliJ의 Tomcat 설정을 통해 환경 변수를 쉽게 적용했었다. 하지만 실제 운영 환경으로 넘어가면서 Tomcat 설정에서 환경 변수를 적용하는 방법을 사용할 수 없게되었다. 코드에 환경 변수를 노출시키지 않으면서 안전하게 관리하는 방법을 찾아야 했는데, 이번에 AWS Secrets Manager를 사용하여 Spring 애플리케이션이 실행될 때 환경 변수를 설정하는 방법을 알게 되어서 기분이 좋다.
이번 기회로 외부에서 환경 변수를 주입하는 방법을 한가지 더 알게 되어서 좋다.
ECS와 RDS 연동하기 (3) - Secrets Manager 이용해서 환경변수 적용하기
'AWS' 카테고리의 다른 글
[AWS] ECS, ALB - 동적 포트 매핑 활성화와 DNS 접속 (1) | 2023.11.05 |
---|---|
[AWS] ECS 배포 실패해도 서버가 다운 안되는 이유 - ECS 서비스 롤링 업데이트 방식 (1) | 2023.11.04 |
[AWS] ECS와 RDS 연동하기 (3) - Secrets Manager 이용해서 환경변수 적용하기 (0) | 2023.11.03 |
[AWS] ECS와 RDS 연동하기 (2) - SpringBoot와 PostgreSQL 연동하기 (0) | 2023.11.03 |
[AWS] ECS와 RDS 연동하기 (1) - PostgreSQL 생성하기 (3) | 2023.11.03 |