개발 코드를 작성하다보면 DB 접속 정보 및 AWS access key 등을 코드에 어쩔수 없이 집어 넣게 된다.
중요한 키가 코드에 있을경우 혹시 모를 보안에 위협이 될수 있으니 관련 정보는 코드에 집어넣지 않고 환경변수를 통해 관리해주는게 좋다.
아래는 ECS 사용시 secret manager 을 사용한 키를 관리하는 방법을 기술하였다.
aws secret manager 을 이용하여 중요 키 정보를 관리하는 방법을 알아보도록 하자.
시크릿 매니저 설정 및 ecs 적용은 하단의 자습서를 참고하였다.
자습서 중요 데이터를 사용하여 Secrets Manager 비밀
먼저 중요 키를 관리할 시크릿 매니저를 생성해준다.
콘솔 > 서비스에서 sercet manager 을 선택후 우측 상단의 새 보안 암호 저장
버튼을 클릭해준다.
다른유형의 보안암호 선택시 키=값
의 규칙으로 정보 저장이 가능하다.
ex> AWS_ACCESS_KEY = 123123123123
등의 방식으로 필요한 키 정보를 설정하고 다음버튼을 클릭한다.
PLAYAUTO 2.0 의 경우 보안 암호 이름을 playauto/gmp 로 설정하였다.
입력 값을 넣어주고 다음 버튼을 눌러 보안암호를 생성 해준다.
오... 오타가.....
보안암호가 생성되면 다음과 같이 ARN 정보가 나오는데 요걸 ECS 역할에 추가해주어야 ECS 에서 해당 암호에 접근이 가능하다.
ECS 에서 보안암호에 접근하기 위해서는 작업실행 역할이 있어야 하고 해당 역할에 위의 arn 을 추가해주어야 한다.
ecs 에서 사용하는 역할은 ecsTaskExecutionRole
이므로 해당 역할에 보안암호 arn 을 추가해주도록 한다.
aws 서비스 > iam > 역할 > ecsTaskExecutionRole
( 우린 iam 역할 수정권한이 없으니.. devops 에 요청을... 쿨럭.. )
이제 ECS 작업정의에 해당 역할을 지정해주면 ECS 에서 process.env 로 보안암호에 접근이 가능해진다.
( 빨간색 폰트로 되어있는 부분이 추가되는 항목이다. )
// task definition
{
"family": "backend-server",
"networkMode": "bridge",
"executionRoleArn": "arn:aws:iam::xxxxxxx:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
...
"essential": true,
"memory": 1000,
"mountPoints": [],
"secrets": [
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-2:xxxxx:secret:playaut/gmp-xxxxx",
"name": "SECRET_ENV"
}
]
}
],
"volumes": [],
"placementConstraints": [
{
"type": "memberOf",
"expression": "attribute:ecs.instance-type =~ t2.*"
}
]
}
executionRoleArn 에 작업실행 역할로 ecsTaskExecutionRole
의 arn 을 지정해주고
secrets 안에 앞서 생성햇던 secret manager arn 을 valueFrom 에 넣어주고 어떤 이름으로 호출해줄지 name 에 지정을 해주면 된다.
( name 값은 원하는대로 설정해 주면 된다. )
이렇게 설정이 되면 코드 안에서 process.env.SECRET_ENV 로 sercet manager 에 설정한 보안키를 사용할수 있다.
그럼 ECS 에서 말고 로컬에서는 보안키를 어떻게 사용해야 할까?
방법은 두가지가 있는데 그 중 좀더 편한쪽으로 사용하면 되겠다.
.env 파일을 루트 경로에 만들고 그 안에 환경변수를 셋팅해준다.
// .env example
NAME=rony
PASSWORD=12345
.env 파일은 로컬 용이므로 깃헙에 정보가 올라가지않게 .gitignore 에 추가해주는걸 잊지않도록 하자.
.env 에 설정한 환경변수는 dotenv 패키지를 통해서 사용이 가능한데 사용법은 다음과 같다.
// dotenv 설치
// 로컬환경에서만 사용할것이기 때문에 devDependencies 로 설치한다.
npm install dotenv --save-dev
// 해당 환경변수를 사용할 위치에서 아래와 같이 로컬인경우와 아닌경우를 분기해서 사용한다.
if (['development', 'test'].includes(process.env.NODE_ENV)) {
// dotenv 를 호출하여 config 선언을 해주면 process.env 에 .env 에 설정한 값이 덮어써진다.
require('dotenv').config();
process.env.SECRET_ENV = {
AWS_ACCESS_KEY: process.env.AWS_ACCESS_KEY,
AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY,
PDB_PASSWORD: process.env.PDB_PASSWORD,
SDB_PASSWORD: process.env.SDB_PASSWORD,
JWT_SECRET: process.env.JWT_SECRET,
};
} else {
process.env.SECRET_ENV = JSON.parse(process.env.SECRET_ENV || '{}');
}
추후 관리해야 될 보안키가 추가되는경우
serect manager 에 해당 키를 추가해주고 로컬의 .env 파일에도 해당 값을 추가해서 사용하면 된다.
aws sdk 를 사용해서 보안키를 조회할 수도 있다.
const AWS = require('aws-sdk');
// 보안키가 적용된 리전명 임력
const client = new AWS.SecretsManager({ region: 'ap-northeast-2' });
const secret = await new Promise((resolve) => {
// 보안 암호 이름 입력
client.getSecretValue({ SecretId: 'secretTest' }, (err, data) => {
if (err) {
resolve({});
} else {
resolve(JSON.parse(data.SecretString));
}
});
});
해당 처리는 조회에 로딩시간이 걸리기 떄문에 로딩 시간이 걸려도 괜찮은경우 사용하기 바라며
관련처리를 위해서는 개발자 pc 에 aws configure 설정이 되어있어야 한다.
도커로 실행하는경우에는 PC 의 aws configure 를 인식하지못하기 떄문에
AWS.SecretsManager
의 생성 인자에 엑세스키와 시크릿키를 입력해주어야 한다.