본문 바로가기
Coding/DevOps

AWS SecretManager를 이용한 도커 환경변수 적용 방법

by Hide­ 2019. 2. 26.
반응형

목적

ECS에 도커 컨테이너를 배포할 때 AWS Secret Manager를 통해 환경변수를 관리하는 방법에 대해 기술한다.


IAM으로 권한 주기

기본적으로 awscli를 통해 접근하려면 credential관련한 설정이 필요하다.

하지만 도커 컨테이너를 빌드할 때 해당 자료를 같이 넘겨주면 의미가 없으므로 IAM을 통해 권한을 설정해줘야 한다.

해당 방법을 사용하면 특별한 crendential 설정이 필요없이 awscli를 통해 접근이 가능하다.

먼저 IAM - 역할로 들어가서 역할 만들기를 누른다.

우리는 ECS 관련한 역할을 만들것이므로 AWS서비스 - EC2를 선택하고 다음을 누른다.


SecretManagerReadWrite를 선택하고 다음을 누른다.

태그 추가는 그냥 넘어간다.

역할 이름에 원하는 이름을 적고 역할 만들기를 누른다.

이제 ecs-cli로 ECS를 띄울 때 Role부분에 우리가 만든 Role의 이름을 명시해주면 해당 역할을 사용할 수 있다.


Secret Manager 생성하기

Secret Manager로 들어가서 새 암호 저장을 누른다.


우리는 데이터베이스 용도로 사용하는것이 아닌 단순 Key:Value형태의 값이 필요하므로 다른 유형의 보안 암호를 선택한다.

아래쪽에 키/밸류를 입력하고 다음을 누른다.


암호의 이름을 입력하고 다음을 누른다.


당장은 자동 교체를 사용하지 않을 것이므로 자동 교체 비활성화에 체크하고 다음을 누른다.


아래로 내려보면 언어별 샘플 코드가 있다.

해당 코드를 복사하고 저장을 누른다.

복사한 샘플 코드를 원하는 장소에 저장한다. (나는 secret_manager.py로 저장함)

추가적으로 복사한 샘플 코드에서 수정해줄 사항이 있다.


# Use this code snippet in your app.
# If you need more information about configurations or implementing the sample code, visit the AWS docs:
# https://aws.amazon.com/developers/getting-started/python/

import boto3
import base64
from botocore.exceptions import ClientError
import ast
import os


def get_secret():
secret_name = "you_have_to_fill_this"
region_name = "ap-northeast-2"

# Create a Secrets Manager client
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name=region_name
)
# In this sample we only handle the specific exceptions for the 'GetSecretValue' API.
# See https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
# We rethrow the exception by default.

try:
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
except ClientError as e:
if e.response['Error']['Code'] == 'DecryptionFailureException':
# Secrets Manager can't decrypt the protected secret text using the provided KMS key.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'InternalServiceErrorException':
# An error occurred on the server side.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'InvalidParameterException':
# You provided an invalid value for a parameter.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'InvalidRequestException':
# You provided a parameter value that is not valid for the current state of the resource.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'ResourceNotFoundException':
# We can't find the resource that you asked for.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
else:
# Decrypts secret using the associated KMS CMK.
# Depending on whether the secret is a string or binary, one of these fields will be populated.
if 'SecretString' in get_secret_value_response:
secret = get_secret_value_response['SecretString']
return ast.literal_eval(secret)
else:
decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
return ast.literal_eval(decoded_binary_secret)


if __name__ == '__main__':
env = get_secret()
if env:
for key, value in env.items():
os.system('echo "export {}={}" >> ~/.bashrc'.format(key, value))

바로 return ast.literal_eval(secret) 부분이다.

그냥 리턴을 하면 String형태로 오므로 Dictionary로 변환해서 return해줘야 나중에 키/밸류로 쉽게 접근할 수 있다.

그리고 가장 아래라인에서 key/value에 맞게 .bashrc에 추가해줬다.

나중에 이 부분을 source커맨드를 통해 bash reload 시켜서 환경변수를 적용해줄 예정이다.

적용 자동화

기존에 작성된 supervisor를 실행시키는 .sh파일의 내용은 아래와 같다.


#!/bin/bash
service supervisor stop
service supervisor start


여기에서 아래처럼 수정한다.


#!/bin/bash
python3 /home/config/secret_manager.py
source ~/.bashrc
service supervisor stop
service supervisor start


Secret Manager에서 값을 불러오는 파일을 실행하고 .bashrc파일을 reload시켜줌으로써 환경변수를 적용시킬 수 있다.

ECS-CLI 명령어 옵션 추가

기존에 ECS에 배포 시 아래와 같은 명령어를 사용했다.


aws ecs create-cluster --cluster-name 클러스터이름

ecs-cli configure --cluster 클러스터이름 --region ap-northeast-2 --default-launch-type EC2 --config-name 클러스터이름

ecs-cli configure profile --access-key 액세스키 --secret-key 시크릿키 --profile-name 클러스터이름

ecs-cli up --keypair 키페어이름 --capability-iam --size 2 --instance-type t2.micro --cluster-config 클러스터이름 --force

ecs-cli compose -f ecs-docker-compose.yml up --create-log-groups --cluster-config 클러스터이름


우리가 문서 초반에 생성한 Role을 적용시켜줘야 하므로 --capability-iam 부분을 --instance-role 역할이름 으로 수정해주면 된다.


ecs-cli up --keypair 키페어이름 --capability-iam --size 2 --instance-type t2.micro --cluster-config 클러스터이름 --force

ecs-cli up --keypair 키페어이름 --instance-role ECS_ROLE이름 --size 2 --instance-type t2.micro --cluster-config 클러스터이름 --force

로 교체


환경 별 환경변수 관리 방법(배포/개발/테스트)

배포 : 모든 환경변수를 위에 나와있는 Secret Manager를 통해 관리한다.

개발 : 개발 환경에서는 별다른 민감한 정보가 포함되어있지 않으므로 Secret Manager를 사용하지 않으며, 사용이 필요한 환경변수는 env폴더에 있는 .env파일을 통해 관리한다.

테스트 : 모든 환경변수를 Bitbucket Repository variable에 정의하고 사용한다.