1. 기본 환경 구성
이번 실습은 IAM 사용자 계정을 통해 관리 콘솔에 접근하고 액세스 키를 활용해 awscli 도구를 사용합니다.
해당 작업을 수행하지 않았다면 아래 토글을 확장해 작업을 선행하고 본격적인 실습에 들어갑니다.
IAM 사용자 생성 및 액세스 키 생성
1.1. Terraform을 통한 기본 인프라 배포
Terraform을 통한 기본 인프라 배포에 앞서 SSH 키 페어, IAM User Access Key ID, IAM User Secret Access Key를 미리 확인하고 메모해 둡니다.
Terraform으로 기본 인프라 배포
cd cnasg_class_tf/Section13
Bash
복사
# 실습 코드 경로 진입
export TF_VAR_KeyName=[각자 ssh keypair]
export TF_VAR_NickName=[각자 닉네임]
export TF_VAR_MyIamUserAccessKeyID=[각자 iam 사용자의 access key id]
export TF_VAR_MyIamUserSecretAccessKey=[각자 iam 사용자의 secret access key]
export TF_VAR_SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32
Bash
복사
# Terraform 환경 변수 저장
terraform init
terraform plan
Bash
복사
# Terraform 배포
nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
Bash
복사
Note:
Terraform 배포가 완료되면(약 5분 정도 대기) 정상적으로 자원 생성이 되었는지 확인을 합니다.(cat create.log)
실수로 Terraform 환경 변수를 설정하지 않은 상태에서 nohup으로 실행하면, terraform 에러가 발생해도 프로세스가 종료되지 않고 계속 점유될 수 있습니다.
이 경우 terraform 프로세스를 강제로 종료한 뒤, 환경 변수를 설정하고 다시 실행해야 합니다.
ps aux | grep -i terraform
kill -9 <terraform_PID>
Bash
복사
# terraform 프로세스 강제 종료
1.2. 기본 정보 확인 및 설정
Terraform 배포가 완료 후 출력되는 Outputs 정보에서 lab_admin_ip와 lab_attacker_ip와 cn_portal_ip의 퍼블릭 IP를 확인합니다.
대상 IP로 인스턴스에 SSH로 접속하고 아래 명령어를 통해 정보를 확인합니다.
LAB-ADMIN
기본 정보 확인
echo ${AWS_DEFAULT_REGION}
echo ${ACCOUNT_ID}
Bash
복사
# 변수 확인
aws sts get-caller-identity
Bash
복사
# caller id 확인
Note:
인스턴스가 생성되고 너무 빠르게 접속하면 aws 자격 증명이 완료되지 않을 수 있습니다.
그럴 경우에는 약간의 대기 후 다시 접속해 주세요.
CN-PORTAL & LAB-ATTACKER
aws sts get-caller-identity
Bash
복사
# caller id 확인
Note:
CN-PORTAL과 LAB-ATTACKER는 별도로 등록된 자격 증명이 존재하지 않습니다.
LAB-ADMIN
실습용 인스턴스 프로파일 적용 (for CN-PORTAL)
INSTANCE_ID=$(aws ec2 describe-instances \
--filters "Name=tag:Name,Values=CN-PORTAL" \
--query "Reservations[].Instances[].InstanceId" \
--output text)
echo "export INSTANCE_ID=${INSTANCE_ID}" >> /etc/profile
echo $INSTANCE_ID
Bash
복사
# CN-PORTAL 인스턴스 ID 변수 선언
cat <<EOF > trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
Bash
복사
# 신뢰 정책 파일 생성
cat <<EOF > cn-portal-kms-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowMembershipKMS",
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:DescribeKey",
"kms:Sign",
"kms:Verify"
],
"Resource": "arn:aws:kms:${AWS_DEFAULT_REGION}:${ACCOUNT_ID}:key/*"
}
]
}
EOF
Bash
복사
# kms 권한 파일 생성
aws iam create-policy \
--policy-name CN-PORTAL-KMS-POLICY \
--policy-document file://cn-portal-kms-policy.json
Bash
복사
# IAM Policy 생성 (CN-PORTAL-KMS-POLICY)
aws iam create-role \
--role-name CN-PORTAL-ROLE \
--assume-role-policy-document file://trust-policy.json
Bash
복사
# IAM Role 생성 (CN-PORTAL-ROLE)
aws iam attach-role-policy \
--role-name CN-PORTAL-ROLE \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/CN-PORTAL-KMS-POLICY
Bash
복사
# IAM Role에 KMS & Security Manager 권한 부여
aws iam attach-role-policy \
--role-name CN-PORTAL-ROLE \
--policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
Bash
복사
aws iam create-instance-profile \
--instance-profile-name CN-PORTAL-PROFILE
Bash
복사
# 인스턴스 프로파일 생성 (CN-PORTAL-PROFILE)
aws iam add-role-to-instance-profile \
--instance-profile-name CN-PORTAL-PROFILE \
--role-name CN-PORTAL-ROLE
Bash
복사
# 인스턴스 프로파일에 IAM Role 추가
aws iam get-instance-profile \
--instance-profile-name CN-PORTAL-PROFILE
Bash
복사
# 인스턴스 프로파일 확인
aws ec2 associate-iam-instance-profile \
--instance-id $INSTANCE_ID \
--iam-instance-profile Name=CN-PORTAL-PROFILE
Bash
복사
# CN-PORTAL에 인스턴스 프로파일 적용
aws ec2 describe-iam-instance-profile-associations \
--filters Name=instance-id,Values=$INSTANCE_ID
Bash
복사
# CN-PORTAL에 인스턴스 프로파일 확인
CN-PORTAL
aws sts get-caller-identity
Bash
복사
# caller id 확인
Note:
CN-PORTAL에 인스턴스 프로파일에 의한 자격 증명이 완료됩니다.
1.3. AWS RDS 및 애플리케이션 구성
실습을 위한 기본 환경으로 AWS RDS를 구성하고 웹 애플리케이션도 구동합니다.
LAB-ADMIN
AWS RDS 생성 및 확인
DB_ID=cnasg-db
DB_NAME=membership
DB_USER=cnasg
DB_PASS='Cnasg1234!'
DB_CLASS=db.t3.micro
DB_PORT=3306
echo "export DB_ID=${DB_ID}" >> /etc/profile
echo "export DB_USER=${DB_USER}" >> /etc/profile
echo "export DB_PASS=${DB_PASS}" >> /etc/profile
Bash
복사
# 기본 변수 선언
RDS_SN_GROUP=cnasg-db-subnet-group
echo "export RDS_SN_GROUP=${RDS_SN_GROUP}" >> /etc/profile
PUBLIC_SN_IDS=$(aws ec2 describe-subnets \
--filters \
"Name=vpc-id,Values=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=cnasg-VPC --query 'Vpcs[0].VpcId' --output text)" \
"Name=tag:Name,Values=cnasg-VPC-public-*" \
--query 'Subnets[*].SubnetId' \
--output text)
echo $PUBLIC_SN_IDS
aws rds create-db-subnet-group \
--db-subnet-group-name ${RDS_SN_GROUP} \
--db-subnet-group-description "CNASG RDS Subnet Group" \
--subnet-ids ${PUBLIC_SN_IDS}
Bash
복사
# RDS DB 서브넷 그룹 생성
aws rds describe-db-subnet-groups \
--db-subnet-group-name ${RDS_SN_GROUP} \
--query 'DBSubnetGroups[0].Subnets[*].SubnetIdentifier' \
--output table
Bash
복사
# RDS DB 서브넷 그룹 확인
[관리 콘솔 확인: Aurora and RDS → 서브넷 그룹]
RDS_SG_ID=$(aws ec2 describe-security-groups \
--filters Name=tag:Name,Values=RDS-SG \
--query 'SecurityGroups[0].GroupId' \
--output text)
echo "export RDS_SG_ID=${RDS_SG_ID}" >> /etc/profile
echo "RDS_SG_ID=${RDS_SG_ID}"
Bash
복사
# RDS 보안 그룹 ID - 변수 선언
aws rds create-db-instance \
--db-instance-identifier ${DB_ID} \
--engine mysql \
--engine-version 8.4 \
--db-instance-class ${DB_CLASS} \
--allocated-storage 20 \
--storage-type gp3 \
--master-username ${DB_USER} \
--master-user-password ${DB_PASS} \
--db-name ${DB_NAME} \
--port ${DB_PORT} \
--vpc-security-group-ids ${RDS_SG_ID} \
--db-subnet-group-name ${RDS_SN_GROUP} \
--publicly-accessible \
--backup-retention-period 0 \
--no-multi-az \
--tags Key=Name,Value=CNASG-RDS
Bash
복사
# RDS - MySQL DB 인스턴스 생성
watch -d "aws rds describe-db-instances \
--db-instance-identifier ${DB_ID} \
--query 'DBInstances[0].DBInstanceStatus' \
--output text"
Bash
복사
# RDS - MySQL DB 인스턴스 상태 확인 (모니터링)
RDS DB 인스턴스 생성까지 약 5분 정도의 대기 시간이 필요합니다.
[관리 콘솔 확인: Aurora and RDS → 데이터베이스]
DB 인스턴스의 엔드포인트 확인
aws rds describe-db-instances \
--db-instance-identifier ${DB_ID} \
--query 'DBInstances[0].Endpoint.{Address:Address,Port:Port}' \
--output table
Bash
복사
# DB 인스턴스의 RDS 엔드포인트 확인
DB_ENDPOINT=$(aws rds describe-db-instances \
--db-instance-identifier ${DB_ID} \
--query 'DBInstances[0].Endpoint.Address' \
--output text)
echo "export DB_ENDPOINT=${DB_ENDPOINT}" >> /etc/profile
echo $DB_ENDPOINT
Bash
복사
# RDS 엔드포인트 변수 선언
DB 접근 및 확인
mysql \
-h ${DB_ENDPOINT} \
-P ${DB_PORT} \
-u ${DB_USER} \
-p
Bash
복사
# DB 접근 (Password : Cnasg1234!)
SHOW DATABASES;
Bash
복사
# database 리스트 확인
USE membership;
Bash
복사
# membership database 사용
SHOW TABLES;
Bash
복사
# membership database에 테이블 확인
CREATE TABLE customers (
customer_id VARCHAR(20) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
phone VARCHAR(20) NOT NULL,
rrn VARCHAR(20) NOT NULL,
grade VARCHAR(20) NOT NULL,
point INT NOT NULL
);
Bash
복사
# 실습을 위한 customers 테이블 생성
SHOW TABLES;
DESC customers;
Bash
복사
# 테이블 정보 확인
quit
Bash
복사
# 종료
실습용 데이터 생성
ls *.py
Bash
복사
# 실습용 데이터 생성을 위한 스크립트 확인
cat gen-membership-csv.py
Bash
복사
python3 gen-membership-csv.py
Bash
복사
# 대상 스크립트 실행
cat membership-data.csv
Bash
복사
# 생성된 csv 데이터 확인
head -3 membership-data.csv
Bash
복사
데이터베이스에 데이터 적재
mysql \
--local-infile=1 \
-h ${DB_ENDPOINT} \
-u ${DB_USER} \
-p membership
Bash
복사
# DB 접근 (Password : Cnasg1234!) - LOCAL INFILE 사용 가능
LOAD DATA LOCAL INFILE 'membership-data.csv'
INTO TABLE customers
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(customer_id,name,email,phone,rrn,grade,point);
Bash
복사
# csv 파일 데이터 적재
SELECT * FROM customers LIMIT 10;
Bash
복사
# customers 테이블에 데이터 10개만 확인
SELECT COUNT(*) FROM customers;
Bash
복사
# 전체 건수 확인 (100건)
quit
Bash
복사
# 종료
CN-PORTAL
웹 애플리케이션 구동
cd cn-portal
Bash
복사
# 웹 애플리케이션 파일 확인
ls -al *.py
Bash
복사
DB_ENDPOINT=[[[RDS_ENDPOINT_주소를_입력하세요.]]]
echo "export DB_ENDPOINT=${DB_ENDPOINT}" >> /etc/profile
Bash
복사
# config.env 파일 생성
cat > config.env << EOF
# Database
DB_HOST=${DB_ENDPOINT}
DB_PORT=3306
DB_NAME=membership
DB_USER=cnasg
DB_PASS=Cnasg1234!
# AWS
AWS_REGION=ap-northeast-2
# KMS
KMS_ENCRYPTION=off
KMS_SIGNING=off
KMS_ENC_KEY_ID=
KMS_SIGN_KEY_ID=
# Secrets Manager
SECRET_MODE=off
SECRET_ID=
EOF
cat config.env
Bash
복사
DB_HOST 주소는 LAB-ADMIN에서 변수 값을 호출해서 그 값을 입력합니다.
echo $DB_ENDPOINT
Bash
복사
# LAB-ADMIN에서 DB_ENDPOINT 주소 확인
python3 app.py
Bash
복사
# 웹 애플리케이션 구동
CN-PORTAL의 퍼블릭 IP 주소에 18080 포트로 HTTP 접근을 수행합니다.
http://CN_PORTAL_IP:18080
2. AWS 서비스를 활용한 데이터 보호
이번 실습은 AWS KMS와 Secrets Manager를 활용하여 민감한 데이터를 보호합니다.
2.1. KMS를 통한 데이터 암호화 (대칭키)
AWS KMS 대칭키를 활용하여 개인정보를 암호화하고 안전하게 저장합니다.
데이터 암호화 적용 전
LAB-ATTACKER
DB_ENDPOINT=[[[탈취한_주소_입력]]]
DB_PORT=3306
DB_USER=cnasg
DB_PASS=Cnasg1234!
Bash
복사
# 탈취한 정보를 변수 선언
mysql \
-h ${DB_ENDPOINT} \
-P ${DB_PORT} \
-u ${DB_USER} \
-p${DB_PASS}
Bash
복사
# 탈취한 정보로 DB 접근
SHOW DATABASES;
Bash
복사
# database 리스트 확인
USE membership;
Bash
복사
# membership database 사용
SHOW TABLES;
Bash
복사
# membership database에 테이블 확인
SELECT * FROM customers LIMIT 10;
Bash
복사
# customers 테이블에 데이터 10개만 확인
quit
Bash
복사
# 종료
LAB-ADMIN
KMS 대칭 키 생성
KMS_KEY_ID=$(aws kms create-key \
--description "CNASG Membership Encryption Key" \
--key-usage ENCRYPT_DECRYPT \
--key-spec SYMMETRIC_DEFAULT \
--query KeyMetadata.KeyId \
--output text)
echo "export KMS_KEY_ID=${KMS_KEY_ID}" >> /etc/profile
echo $KMS_KEY_ID
Bash
복사
# KMS 대칭키 생성 및 KEY ID 변수 선언
aws kms create-alias \
--alias-name alias/cnasg-membership-enc \
--target-key-id ${KMS_KEY_ID}
Bash
복사
# KMS 대칭키 Alias 생성
aws kms list-aliases \
--query "Aliases[?AliasName=='alias/cnasg-membership-enc']"
Bash
복사
# Alias 확인
CN-PORTAL
데이터 암호화 적용
cat config.env | grep KMS_ENC
Bash
복사
# config.env 확인
sed -i 's|^KMS_ENC_KEY_ID=.*|KMS_ENC_KEY_ID=alias/cnasg-membership-enc|' config.env
Bash
복사
# KMS_KEY_ID 추가
cat config.env | grep KMS_ENC
Bash
복사
# config.env 확인
python3 apply-kms-encryption.py
Bash
복사
# KMS 암호화 기능을 적용하는 스크립트 실행
apply-kms-encryption.py를 실행하면, config.env에 KMS_ENCRYPTION을 on으로 변경합니다. 이후 개인정보 컬럼은 암호화된 형태로 저장되며, 웹 애플리케이션은 조회 시 자동으로 복호화합니다.
또한, app.py 파일을 중지했다가 다시 실행합니다.
데이터 암호화 적용 후
LAB-ATTACKER
mysql \
-h ${DB_ENDPOINT} \
-P ${DB_PORT} \
-u ${DB_USER} \
-p${DB_PASS} membership
Bash
복사
# 탈취한 정보로 DB 접근
SELECT * FROM customers LIMIT 3;
Bash
복사
# customers 테이블에 데이터 3개만 확인
quit
Bash
복사
# 종료
만약 실습 초기 환경으로 복원하려면 CN-PORTAL에서 다른 스크립트를 실행시키면 됩니다.
python3 rollback-kms-encryption.py
Bash
복사
# CN-PORTAL에서 rollback-kms-encryption.py 실행
2.2. KMS를 통한 디지털 서명 (비대칭키)
AWS KMS 비대칭키를 활용하여 데이터 무결성과 위변조 여부를 검증합니다.
디지털 서명 적용 전
1.
고객 조회
CloudNeta Membership Portal 접속 ⇒ 고객 조회 ⇒ 사용자 ID 입력 ⇒ 조회
2.
상품권 발급
고객 조회 상태 ⇒ 상품권 금액 입력 ⇒ 상품권 발급
3.
상품권 다운로드
상품권 파일 다운로드 (클릭)
4.
상품권 변조
amount 값 수정 ⇒ 저장
5.
상품권 확인
상품권 확인 ⇒ 파일 선택 ⇒ 확인
LAB-ADMIN
KMS 비대칭 키 생성(서명 키)
KMS_SIGN_KEY_ID=$(aws kms create-key \
--description "CNASG Membership Signing Key" \
--key-usage SIGN_VERIFY \
--key-spec RSA_2048 \
--query KeyMetadata.KeyId \
--output text)
echo "export KMS_SIGN_KEY_ID=${KMS_SIGN_KEY_ID}" >> /etc/profile
echo $KMS_SIGN_KEY_ID
Bash
복사
# KMS 비대칭키 생성 및 KEY ID 변수 선언
aws kms create-alias \
--alias-name alias/cnasg-membership-sign \
--target-key-id ${KMS_SIGN_KEY_ID}
Bash
복사
# KMS 비대칭키 Alias 생성
aws kms list-aliases \
--query "Aliases[?AliasName=='alias/cnasg-membership-sign']"
Bash
복사
# Alias 확인
CN-PORTAL
디지털 서명 적용
sed -i 's|^KMS_SIGN_KEY_ID=.*|KMS_SIGN_KEY_ID=alias/cnasg-membership-sign|' config.env
Bash
복사
# KMS_SIGN_KEY_ID 추가
cat config.env | grep KMS_SIGN
Bash
복사
# config.env 확인
python3 apply-kms-signing.py
Bash
복사
# KMS 디지털 서명 기능을 적용하는 스크립트 실행
apply-kms-signing.py를 실행하면, config.env에 KMS_SIGNING을 on으로 변경합니다. 이후 발급되는 상품권에는 디지털 서명이 포함되며, 서명 검증을 통해 위변조 여부를 확인할 수 있습니다.
또한, app.py 파일을 중지했다가 다시 실행합니다.
디지털 서명 적용 후
1.
고객 조회
CloudNeta Membership Portal 접속 ⇒ 고객 조회 ⇒ 사용자 ID 입력 ⇒ 조회
2.
상품권 발급
고객 조회 상태 ⇒ 상품권 금액 입력 ⇒ 상품권 발급
3.
상품권 다운로드
상품권 파일 다운로드 (클릭)
4.
상품권 변조
amount 값 수정 ⇒ 저장
5.
상품권 확인
상품권 확인 ⇒ 파일 선택 ⇒ 확인
만약 실습 초기 환경으로 복원하려면 CN-PORTAL에서 다른 스크립트를 실행시키면 됩니다.
python3 rollback-kms-signing.py
Bash
복사
# CN-PORTAL에서 rollback-kms-signing.py 실행
2.3. Secrets Manager를 통한 보안 정보 관리
데이터베이스 계정 정보를 Secrets Manager로 이전하고 안전하게 관리합니다.
LAB-ADMIN
Secrets Manager에서 Secret 생성
aws secretsmanager create-secret \
--name cnasg-membership-db \
--description "CNASG Membership DB credential" \
--secret-string "{\"username\":\"${DB_USER}\",\"password\":\"${DB_PASS}\"}"
Bash
복사
# Secrets Manager에서 Secret 생성 (DB_USER/DB_PASS)
aws secretsmanager get-secret-value \
--secret-id cnasg-membership-db \
--query SecretString \
--output text
Bash
복사
# Secrets Manager의 Secret 값 확인
CN-PORTAL
Secrets Manager 적용
sed -i 's|^SECRET_ID=.*|SECRET_ID=cnasg-membership-db|' config.env
Bash
복사
# KMS_SIGN_KEY_ID 추가
cat config.env | egrep 'DB|SECRET'
Bash
복사
# config.env 확인
python3 apply-secret-manager.py
Bash
복사
# DB_USER와 DB-PASS를 Secrets Manger에서 관리하도록 변경
cat config.env | egrep 'DB|SECRET'
Bash
복사
# config.env 확인
apply-secret-manager.py를 실행하면, config.env에 DB_USER와 DB_PASS 값을 제거하고 SECRET_MODE를 on으로 변경합니다.
이후 애플리케이션은 Secrets Manager에 저장된 계정 정보를 사용하여 데이터베이스에 접속합니다.
2.4. [번외] RDS 퍼블릭 접근 제한
데이터베이스의 퍼블릭 접근을 제거하여 네트워크 공격 표면을 최소화합니다.
CN-PORTAL / LAB-ATTACKER
퍼블릭 접근 활성화 상태
dig +short $DB_ENDPOINT
Bash
복사
# DB_ENDPOINT 주소 확인
DB_PORT=3306
DB_USER=cnasg
DB_PASS=Cnasg1234!
Bash
복사
# DB 접근을 위한 변수 선언
mysql \
-h ${DB_ENDPOINT} \
-P ${DB_PORT} \
-u ${DB_USER} \
-p${DB_PASS}
Bash
복사
# DB 접근
quit
Bash
복사
# 종료
LAB-ADMIN
퍼블릭 접근 비활성화 설정
aws rds describe-db-instances \
--query "DBInstances[*].[DBInstanceIdentifier,DBInstanceStatus,PubliclyAccessible]" \
--output table
Bash
복사
# DB 식별자 확인
aws rds modify-db-instance \
--db-instance-identifier cnasg-db \
--no-publicly-accessible \
--apply-immediately
Bash
복사
# RDS Public Access 비활성화
watch -d "aws rds describe-db-instances \
--db-instance-identifier cnasg-db \
--query "DBInstances[0].[DBInstanceIdentifier,DBInstanceStatus,PubliclyAccessible]" \
--output table"
Bash
복사
# RDS Public Access 상태 모니터링
CN-PORTAL / LAB-ATTACKER
퍼블릭 접근 비활성화 상태
dig +short $DB_ENDPOINT
Bash
복사
# DB_ENDPOINT 주소 확인
mysql \
-h ${DB_ENDPOINT} \
-P ${DB_PORT} \
-u ${DB_USER} \
-p${DB_PASS}
Bash
복사
# DB 접근
quit
Bash
복사
# 종료
3. 실습 환경 삭제
LAB-ADMIN
인스턴스 프로파일 삭제
ASSOC_ID=$(aws ec2 describe-iam-instance-profile-associations \
--filters Name=instance-id,Values=$INSTANCE_ID \
--query "IamInstanceProfileAssociations[0].AssociationId" \
--output text)
echo $ASSOC_ID
Bash
복사
# 인스턴스 프로파일 Associations ID 변수 선언
aws ec2 disassociate-iam-instance-profile \
--association-id $ASSOC_ID
Bash
복사
# CN-PORTAL의 인스턴스 프로파일 제거
aws iam remove-role-from-instance-profile \
--instance-profile-name CN-PORTAL-PROFILE \
--role-name CN-PORTAL-ROLE
Bash
복사
# 인스턴스 프로파일에 IAM Role 제거
aws iam delete-instance-profile \
--instance-profile-name CN-PORTAL-PROFILE
Bash
복사
# 인스턴스 프로파일 삭제
aws iam detach-role-policy \
--role-name CN-PORTAL-ROLE \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/CN-PORTAL-KMS-POLICY
aws iam detach-role-policy \
--role-name CN-PORTAL-ROLE \
--policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
Bash
복사
# 연결된 정책 제거
aws iam delete-policy \
--policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/CN-PORTAL-KMS-POLICY
Bash
복사
# IAM Policy 삭제
aws iam delete-role \
--role-name CN-PORTAL-ROLE
Bash
복사
# IAM Role 삭제
AWS RDS 삭제
aws rds modify-db-instance \
--db-instance-identifier "${DB_ID}" \
--no-deletion-protection \
--apply-immediately
Bash
복사
# DeletionProtection 해제
aws rds describe-db-instances \
--db-instance-identifier "${DB_ID}" \
--query 'DBInstances[0].{Status:DBInstanceStatus,DeletionProtection:DeletionProtection}' \
--output table
Bash
복사
# DeletionProtection 확인
aws rds delete-db-instance \
--db-instance-identifier "${DB_ID}" \
--skip-final-snapshot \
--delete-automated-backups
Bash
복사
# DB 인스턴스 삭제
watch -d "aws rds describe-db-instances \
--db-instance-identifier ${DB_ID} \
--query 'DBInstances[0].DBInstanceStatus' \
--output text"
Bash
복사
# DB 인스턴스 확인
DB 인스턴스 삭제는 약 2분 정도 대기가 필요합니다.
aws rds delete-db-subnet-group \
--db-subnet-group-name "${RDS_SN_GROUP}"
Bash
복사
# RDS DB 서브넷 그룹 삭제
KMS 암호화 키 삭제(대칭키)
aws kms delete-alias \
--alias-name alias/cnasg-membership-enc
Bash
복사
# Alias 삭제
aws kms schedule-key-deletion \
--key-id $KMS_KEY_ID \
--pending-window-in-days 7
Bash
복사
# KMS 대칭키 삭제 (대기 최소 7일)
KMS 키는 즉시 삭제되지 않으며, 최소 7일의 대기 기간 이후 삭제됩니다.
KMS 서명 키 삭제(비대칭키)
aws kms delete-alias \
--alias-name alias/cnasg-membership-sign
Bash
복사
# Alias 삭제
aws kms schedule-key-deletion \
--key-id $KMS_SIGN_KEY_ID \
--pending-window-in-days 7
Bash
복사
# KMS 비대칭키 삭제 (대기 최소 7일)
Secrets Manager - Secret 삭제
aws secretsmanager delete-secret \
--secret-id cnasg-membership-db \
--force-delete-without-recovery
Bash
복사
# Secrets Manager의 Secret 삭제
Terraform 자원 삭제
nohup sh -c "terraform destroy -auto-approve" > delete.log 2>&1 &
Bash
복사
# terraform 자원 삭제
Note:
Terraform 자원 삭제가 완료되면(약 3분 정도 대기) 정상적으로 자원 삭제가 되었는지 확인을 합니다.(cat delete.log)
여기까지 섹션 13 실습 - 데이터 보호 - AWS KMS & Secrets Manager 를 마칩니다.
수고하셨습니다 :)



