4번독수리의 둥지

AWS ECS Task가 Secrets Manager에 저장된 비밀번호를 사용하도록 설정 본문

카테고리 없음

AWS ECS Task가 Secrets Manager에 저장된 비밀번호를 사용하도록 설정

4번독수리 2019. 8. 30. 15:27

AWS ECS를 이용하여 서비스를 개발하고 있는데 기존에는 도커 이미지 안에 DB 비밀번호가 포함되어 있던 상황.

개선을 위해 AWS Secrets Manager를 사용하기로 하였다.

다행히 서비스에 필요한 여러 값들은 환경 변수를 설정하여 덮어쓸 수 있게 구현해 놓았기 때문에, AWS Secrets Manager에 등록해 놓은 비밀번호를 Task의 환경변수로 밀어넣을 계획.

 

1. Secrets Manager에 새 secret을 생성하여 사용할 비밀번호를 등록

  1) AWS콘솔 > Services > Security, Identity, & Compliance > Secrets Manager로 이동, Store a new secret로 들어감

  2) Select secret type : Other type of secrets

    - Specify the key/value pairs to be stored in this secret : Plaintext를 선택하고 설정할 비밀번호를 기입

    - Select the encryption key : DefaultEncryptionKey

    - Next

  3) Store a new secret

    - Secret name : 적절히 입력

    - Next, Next, Store

 

2. 등록한 secret을 사용하도록 ECS Task Definition의 새 Revision을 생성

  1) AWS콘솔 > Services > Compute > ECS > Task Definitions로 이동, 적용하려는 작업정의의 Create new revision로 들어감

  2) Container Definition을 편집, ENVIRONMENT에 1.에서 생성한 Secret을 기입

    - Key에 사용할 환경변수명을 입력

    - Value에 ValueFrom을  선택

    - Add value에 생성한 secret의 arn을 입력

  3) Update, Create

 

3. ECS 서비스 업데이트

  1) ECS > Clusters로 이동, 생성한 작업정의개정을 적용할 Cluster, Service로 이동하여 Update

  2) Task Definition의 Revision을 방금 생성한 것을 선택 (latest일 것이다)

  3) Next step, Next step, Next step, Update Service

  4) View Service를 클릭하면 서비스 화면으로 돌아간다.

    - Deployments 탭에 업데이트한 최신 Deploy가 PRIMARY로 표시됨

    - Tasks 탭에 새 개정에 의한 Task가 곧 생성되고 이상 없으면 status RUNNING으로 변경됨. Log driver가 awslogs이면 Task 상세보기 화면에서 View logs in CludWatch로 로그 확인.

 

비고

 

1. DB는 RDS를 사용할 예정이었기 때문에 Credentials for RDS database를 써야 하는 것 같았지만

  - 이 type은 선택한 RDS 인스턴스에 접속할 수 있는 credential을 json format으로 자동 생성해 준다는 것 말고는 Other type of secrets와 차이가 없는 것 같고

  - 어차피 여기서 설정한 값은 Task Definition의 Container definition의 Environment Variables로 받을 생각이었고

  - 환경변수로 받는 값들은 plaintext였기 때문에 굳이 json object를 받아 쓰기 위해 코드를 변경할 필요가 없음.

  - RDS type을 쓰면 DB 비밀번호 자동 변경을 하도록 설정할 수 있는 건지?

[수정] RDS type을 쓰도록 수정하고 AWS가 제공하는 샘플 코드를 이용하여 DB 액세스 할 수 있었다.

이 경우 샘플코드의 aws sdk가 ECS 실행환경으로부터 주입된 환경변수 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 이용하여 Secrets Manager로부터 저장한 값을 받아온다.

로컬에서 테스트할 경우 환경변수를 수동으로 세팅해 주면 된다. 해당 값들은 쉘스크립트를 이용해서 얻어올 수 있다.

aws configure get aws_access_key_id

aws configure get aws_secret_access_key

해당 값들은  ~/.aws/credentials 파일에 저장되어 있다.

 

2. Task가 secret을 받아올 수 있는 권한을 가지고 있어야 한다. 이를 위해 Task Role에 SecretManagerReadWrite policy를 추가해 주어야 한다. 그렇지 않으면 오류가 발생하면서 Task가 RUNNING 상태가 되지 못한다.

Fetching secret data from AWS Secrets Manager in region **-*********-*: secret arn:aws:secretsmanager:**-*********-*:*************:secret:****-******: AccessDeniedException: User: arn:aws:sts::*************:assumed-role/********************/********-****-****-****-************ is not authorized to perform: secretsmanager:GetSecretValue on resource: arn:aws:secretsmanager:**-*********-*:************:secret:****-****** status code: 400, request id: ********-****-****-*

3. 서비스 업데이트는 Task Definition 화면에서도 할 수 있지만 서비스 쪽에서 접근하는 게 더 실수할 여지가 적다고 생각한다. 나는 다음다음만 클릭했지만 필요한 추가사항이 있다면 적절히 검토해야 한다.