SSM Parameter Store
- 구성과 암호를 위한 보안 스토리지
중앙 집중화
- KMS 서비스를 이용해 구성을 암호화할지 선택 가능
- 서버리스이며 확장성과 내구성, SDK 사용에 용이하다.
- 매개변수를 업데이트할 때 구성과 암호의 버전을 추적 가능
- IAM을 통해 보안이 제공
- 특정한 경우 Amazon EventBridge로 알림을 받을 수 있다.
- CloudFormation과 통합 가능
CloudFormation이 Parameter Store의 매개변수를 스택의 입력 매개변수로 활용 할 수 있다는 뜻

- 애플리케이션과 SSM이 있을 때 평문 구성을 저장할 때
- EC2 인스턴스 역할 같은 애플리케이션 IAM 권한이 확인될 것이다.
아니면 암호화된 구성이 있다 해보면
- SSM가 KMS로 구성을 암호화한다.
- KMS 서비스가 암호화/복호화에 사용된다는 뜻이다.
* 암호화/복호화를 수행하려면 애플리케이션이 기본 KMS 키에 액세스 할 수 있어야한다.
SSM Parameter Store 계층
- 계층 구조가 있는 Parameter Store에 매개변수를 저장할 수 있다.
- '/my-department/'를 경로로 정의하면 하위에
- /other-department/
- 이런 식으로 원하는 방식으로 매개변수를 구조화할 수 있다.

- 만약 Dev Lambda 함수라는 애플리케이션을 사용한다면 'my-app/' 내 'dev/'의 'db-url'과'db-password'에 액세스를 허용하는 IAM 역할을 할 것이다.
- 여러 IAM 정책과 일부 환경변수 때문에 Prod Lambda 함수를 사용한다면 다른 경로에 있는 'prod/'의 'db-url'과'db-password'에도 액세스할 수 있다.
- 구조화를 통해 IAM 정책을 간소화해 애플리케이션이 '/my-department/' 혹은 'my-app/' 전체 경로에 또는 'my-app/', '/my-department/' 환경의 특정 경로에만 액세스할 수 있도록 한다.
- 또한 화면에 보이는 레퍼런스를 사용해 Parameter Store로 Secrets Manater의 암호에 액세스할 수도 있다.
ex: /aws/reference/secretsmanager/secret_ID_in_Secrets_Manager
- AWS에서 발행하는 퍼블릭 매개변수도 사용할 수 있다.
예를 들어 특정 리전에서 Linux 2의 최신 AMI를 찾으려 할 때 Parameter Store에서 API 호출을 대신해 쓸 수 있다.
ex: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2(public)
표준 및 고급 매개변수 계층
- Systems Manager 두 가지 매개변수 티어

- 주요 차이점
- 용량
표준: 4KB
고급: 8KB
- 매개변수 정책 적용 여부
표준: X
고급: O
- 비용
표준: FREE
고급: 월 0.05$
매개변수 정책(고급 매개변수)
- 매개변수 정책을 통해 만료 기한을 뜻하는 TTL를 매개변수에 할당할 수 있다.
사용자가 비밀번호 등의 민감한 정보를 업데이트 또는 삭제하도록 강제할 수 있음.
- 한 번에 여러 정책을 할당할 수 있다.

- 매개변수를 삭제하는 만료 정책(왼쪽)
이 타임스탬프에서는 이 매개변수를 반드시 삭제해야 한다.
- EventBridge와 통합(중간)
EventBridge와 통합 함으로써 EventBridge에서 알림을 받을 수 있게 된다.
이 예시는 매개변수가 만료되기 15일 전에 EventBridge 알림을 받게 된다.
TTL로 매개변수가 삭제되기 전에 업데이트할 수 있을 만큼 여유가 충분하다.
- 매개변수를 변경하고 싶을 때(오른쪽)
EventBridge는 변경이 없다는 알림도 제공하므로
20일 동안 매개변수에 업데이트가 없으면 알림을 받게 한다.
SSM 매개변수 실습(CLI 이용)
AWS Systems Manager > 왼쪽 바 [파라미터 스토어]
-> 작동 방식
1. 새로운 매개변수를 생성
2. 매개변수의 유형과 값을 명시
3. 코드의 명령 내에서 그 매개변수를 참조


- 위 매개변수를 여러개 생성하고, 이 매개변수에 액세스하려면 CLI를 사용한다.
# AWS CLI
aws ssm get-parameters --names /my-app/dev/db-url
// db-password 같이 SecureString 타입은 뒤에 --with-decryption을 붙여주자(단, KMS에 액세스하지 못하는 계정은 접근할 수 없음)
aws ssm get-parameters --names /my-app/dev/db-password --with-decryption
# 해당 경로의 모든 매개변수 쿼리하기
aws ssm get-parameters-by-path help
aws ssm get-parameters-by-path /my-app/dev/
# my-app에서 매개변수를 반복적으로 가져오기
aws ssm get-parameters-by-path /my-app/ --recursive
SSM 매개변수 실습(Lambda,SDK 사용)
람다 함수에 CloudWatch 로그에 쓰기 권리를 제공해 SSM 파라미터 스토어에 읽기 및 쓰기 하기
### 람다를 사용해 SSM 매개변수 활용
# AWS Lambda 콘솔
Create function >
이름: hello-world-SSM
럼타임: Pyhtion 3.12
권한: IAM 실행 규칙 생성(기본 Lambda 권한이 있는 새로운 역할 생성 체크)
생성
=============================
import json
import boto3
ssm=boto.client('ssm', region_name='ap-northeast-2')
def lambda_handler(event, context):
db_url= ssm.get_parameters(Names=["/my-app/dev/db-url"])
print(db_url)
db_password= ssm.get_parameters(Names=["/my-app/dev/db-password"])
print(db_password)
return "worked"
=============================
> 테스트 클릭 (실패)
=> GetParameter 작업 호출 시 AccessDenied Exception
=> labmda_basic_execution_ssm은 ssm:GetParameters를 실행할 권한이 없음
=> iam 역할을 추가해야 한다.
# iam 역할 추가하기
iam > 역할 > 아까 만든 ssm 역할 > 권한 > 권한 추가 > 인라인 정책 생성 >
서비스: systems manager > 읽기: [v] GetParameters, GetParametersByPath > 리소스 항목: 특정, ARN 추가 클릭 > 리전: 모든 리전, 계정: 모든 계정, 명확한 파라미터이름: my-app/* > 추가
> 이름 설정 후 생성
다시 람다를 실행(실패) -> 바로 적용이 안되는 경우도 있음
5분정도 기다렸다 시도
실행 -> 성공
### db-url은 값이 나오지만 db-password는 SecretString이라 암호화되어있다.
# 복호화 작업
=============================
import json
import boto3
ssm=boto.client('ssm', region_name='ap-northeast-2')
def lambda_handler(event, context):
db_url= ssm.get_parameters(Names=["/my-app/dev/db-url"])
print(db_url)
db_password= ssm.get_parameters(Names=["/my-app/dev/db-password"], **WithDecryption=True**)
print(db_password)
return "worked"
=============================
다시 람다 실행 (실패)
=> AccessDeniedException
=> 고객 마스터 키를 사용할 수 없기 떄문에 복호화 불가능
=> IAM 역할에 KMS 액세스를 부여해야 한다.
비밀번호를 보고 싶다면 IAM에 역할 추가
# 역할 추가
IAM > 역할 > 아까 그거 > 수정 > 인라인 정책 >
서비스: KMS, 쓰기: Decrypt, 리소스: 특정, ARN 추가 > 리전: 모든 리전, 계정: 모든 계정, Key id: kms키 id 넣고 > 추가
이제 람다를 다시 실행하면 값을 볼 수 있다.
### dev와 prod 파라미터가 있을 떄 변경 요령
# 람다 > 환경변수 탭 > 키: DEV_OR_PROD, 값: dev
=============================
import json
import boto3
import os
ssm=boto.client('ssm', region_name='ap-northeast-2')
dev_or_prod=os.environ['DEV_OR_PROD']
def lambda_handler(event, context):
db_url= ssm.get_parameters(Names=["/my-app/" + dev_or_prod + "/db-url"])
print(db_url)
db_password= ssm.get_parameters(Names=["/my-app/" + dev_or_prod + "/db-password"], **WithDecryption=True**)
print(db_password)
return "worked"
=============================
prod로 변경하고 싶다면 환경 변수에서 하나만 변경하면 됌
AWS Secrets Manager
- 암호를 저장하는 최신 서비스
SSM Parameter Stroe와는 다른 서비스이다.
- Secrets Manager는 x일마다 강제로 암호를 교체하는 기능이 있다.
=> 암호 관리를 더 효율적으로 할 수 있음.
- AWS Secrets Manager로 교체할 암호를 강제 생성 및 자동화할 수 있다.
이를 위해 새 암호를 생성할 Lambda 함수를 정의해야 한다.
- AWS가 제공하는 다양한 서비스와 잘 통합됨
ex: RDS, MySQL, PostgreSQL, Aurora, AWS 외 여러 서비스와 DB에 즉시 통합 가능.
DB에 접근하기 위한 사용자 이름과 비밀번호가 AWS Secrets Manager에 바로 저장되고 교체도 가능하다.
- 암호는 KMS 서비스를 통해 암호화된다.
- RDS와 Aurora의 통합 또는 암호에 대한 내용 = AWS Secrets Manager
AWS Secrets Manager - 다중 리전 암호
- 다중 리전에 암호를 복제 가능
Secrets Manager가 기본 암호와 동기화된 읽기 전용 복제본을 유지하는 개념

- 두 리전이 있으면 기본 리전에 암호를 하나 만들면 다른 리전에 동일한 암호가 복제됨.
- 이렇게 하는 이유
- 기본 리전에 문제가 발생하면 암호 복제본을 독립 실행형 암호로 승격할 수 있다.
- 여러 리전에 암호가 복제되어 다중 리전 앱을 구축하고 재해 복구 전략을 짤 수 있음.
EX: 한 리전에서 다음 리전으로 복제되는 RDS DB가 있다면 동일한 암호로 동일한 RDS DB에 액세스 가능하다.
AWS Secrets Manager 실습(x)
- 수명 주기동안 암호를 쉽게 교체, 관리, 검색할 수 있음.
- 암호 저장 측면에서 SSM과 유사하지만 교체,관리, DB와의 통합도 지원한다.
MySQL, PostgreSQL, Aurora, RDS 등
- 30 일 무료 체험판
암호 당 월 0.4또는10,000API호출당0.05
AWS Certificate Manager(ACM)

- ACM은 TLS 인증서를 AWS에서 프로비저닝, 관리 및 배포한다.
- ACM은 퍼블릭, 프라이빗 TLS 인증서를 모두 지원
퍼블릭 TLS 인증서 = FREE
- 인증서 자동 갱신 기능 제공
- 여러 AWS 서비스와 통합되어 있다.
- ELB에 TLS인증서 불러오기
- CloudFront 배포
- API Gateway의 모든 API에서 불러오기
- 단, EC2 인스턴스에는 ACM 을 불러올 수 없다.
퍼블릭 인증서일 경우 추출이 불가능하다.
즉, ACM을 통해 EC2 인스턴스에 대한 퍼블릭 인증서를 생성할 수 없음.
ACM- 퍼블릭 인증서 요청 과정
- 인증서에 포함할 도메인 이름을 나열
ex: salestore.com과 같은 전체 주소 도메인 이름(FQDN)도 될 수 있고,
*.com과 같은 와일드카드 도메인도 가능
+ 도메인 수에 제한이 없다.
- 유효성 검증 방법: DNS 검증과 이메일 검증 중 선택
- 자동화를 목적으로 SSL 인증서를 자동 갱신하려면 DNS 검증을 쓰는게 낫다
- 이메일 검증은 ACM이 도메인에 등록된 연락처로 이메일을 보내 해당 인증서를 요청했는지 여부를 확인
- DNS 검증은 DNS 구성에서 CNAME 레코드를 생성해 도메인 소유권을 증명해야 한다.
ex: Route 53이 있다면 ACM과 자동으로 통합해 이 작업을 수행해준다.
- 몇 시간 후 유효성 검증이 완료되면 인증서가 발행
- 이 퍼블릭 인증서도 자동 갱신 목록에 추가된다.
- ACM에서 스스로 생성된 모든 인증서를 만료 60일 전에 자동으로 갱신해 준다.
ACM - 퍼블릭 인증서 가져오기
- ACM 외부에서 가져오는 인증서는 자동 갱신이 불가능하다.
ACM 서비스가 만료 45일 전부터 메일 만료 이벤트를 EventBridge 서비스에 전송해준다.

- AWS Config를 사용하는 방법
acm-certificate-expiration-check라는 관리형 규칙으로
만료된 인증서를 확인하는 규칙으로 일수를 조정해 EventBridge로 알림 받기
ACM - ALB와 통합되는 방법

- 백엔드에 ASG이 있는 ALB와 ACM으로 프로비저닝 및 유지관리되는 TLS 인증서가 있다 생각해보자
- ALB에서는 HTTP에서 HTTPS로의 리디렉션 규칙을 설정할 수 있음.
- 사용자가 HTTP 프로토콜에서 ALB에 액세스할 때 ALB는 HTTPS로 리디렉션하는 요청을 반환 한다.
- 그 후 사용자는 HTTPS 프로토콜에서 ALB에 액세스하고, 이는 ACM에서 나오는 TLS 인증서를 사용한다.
- 요청이 HTTPS 프로토콜을 통과하면 ASG로 바로 전달된다.
ACM - API Gateway와 통합되는 방법