공지사항 📌

마지막 업데이트 날짜: 2026-04-07

공통 변경사항

보안 권고 사항에 따라, 진단 계정 등록 시 CSP사에서 자체적으로 발급받은 엑세스 키 사용을 중지하고 최소 권한만을 갖는 서비스 계정 생성 후 워크로드 인증 절차를 따를 것을 권고드립니다.

  • CSP별 진단 계정 등록 방법
    • AWS: Access Key + Secret Key -> IAM Role ARN 등록 (IRSA 인증) - 기존과 동일
    • GCP: Service Account Key File 업로드 -> Credential Configuration File 업로드 (Workload Identity Federation 구성)
    • Azure: Client Secret Key 미사용 (Workload Identity Federation 구성)

또한 진단 계정 등록 시 아래와 같이 인증 방식을 선택(택1)하도록 변경되었으며, 계정 진단 시 선택한 인증 방식으로만 진행됩니다.

Guide-Account-Authentication-1

미사용 엑세스 키는 추후 삭제될 예정이며, 기간은 별도 공지드리겠습니다.

감사합니다.


Azure 진단 계정 등록 (Cloud Shell)

개요

이 가이드는 Azure Cloud Shell 또는 Azure CLI를 사용하여 CQI 진단을 위한 Azure Workload Identity Federation을 설정하는 방법을 단계별로 안내합니다.

1. 사전 요구사항

1-1. CQI 서비스 제공 정보

다음 정보는 CQI 서비스에서 제공하는 고정 값입니다:

항목 값
EKS OIDC Issuer URL https://oidc.eks.ap-northeast-2.amazonaws.com/id/78FAD92A5614D6C424B1A577DC6B99F1
EKS Namespace cqi-prod-app-ns
EKS Service Account cqi-prod-app-sa

위 정보는 Federated Credential 설정 시 그대로 사용하세요.


1-2. 필요한 권한

  • Azure:
    • Azure AD에서 애플리케이션 생성 권한
    • Subscription에서 RBAC 역할 할당 권한 (예: Owner, User Access Administrator)

1-3. 필요한 정보

아래 정보를 미리 수집해두세요:

  • Azure Subscription ID

1-4. Azure CLI 설정

Azure Cloud Shell 또는 로컬 환경에서 Azure CLI를 사용합니다.

# Azure CLI 버전 확인
az --version

# Azure 로그인 (로컬 환경인 경우)
az login

# 구독 설정
az account set --subscription "<Subscription ID>"

# 현재 구독 확인
az account show --output table

2. Azure AD 애플리케이션 등록

CQI 서비스가 Azure 리소스에 접근할 수 있도록 Azure AD에 애플리케이션 신원을 등록합니다. 이 단계에서 생성되는 Application (client) ID와 Directory (tenant) ID가 CQI 진단 계정 등록에 사용됩니다.

2-1. 변수 설정

# 변수 설정 (환경에 맞게 수정)
APP_NAME="CQI-Workload-Identity"

2-2. 애플리케이션 등록

# 애플리케이션 (Single Tenant)
az ad app create \
  --display-name "$APP_NAME" \
  --sign-in-audience AzureADMyOrg

출력 예시:

{
  "appId": "8339577f-971b-4d85-a206-c6c7eb654fcf",
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "displayName": "CQI-Workload-Identity",
  ...
}

2-3. 필수 정보 기록

# Application (client) ID 조회
APP_ID=$(az ad app list --display-name "$APP_NAME" --query "[0].appId" --output tsv)
echo "Application (client) ID: $APP_ID"

# Directory (tenant) ID 조회
TENANT_ID=$(az account show --query "tenantId" --output tsv)
echo "Directory (tenant) ID: $TENANT_ID"
항목 예시 용도
Application (client) ID 8339577f-971b-4d85-a206-c6c7eb654fcf CQI 계정 등록에 사용
Directory (tenant) ID c5cb8008-8404-4eb7-99d2-c12f067410c1 CQI 계정 등록에 사용

참고: 이 두 값은 공개 정보이므로 안전하게 공유 가능합니다. Secret이 아닙니다.


2-4. Service Principal 생성

애플리케이션에 연결된 Service Principal을 생성합니다.

# Service Principal 생성
az ad sp create --id $APP_ID

3. Federated Credentials 추가

이 단계에서 CQI 서비스(AWS EKS)가 Azure AD App을 인증할 수 있도록 신뢰 관계를 설정합니다.

3-1. 변수 설정

# CQI 서비스 제공 정보 (고정 값)
EKS_OIDC_ISSUER="https://oidc.eks.ap-northeast-2.amazonaws.com/id/78FAD92A5614D6C424B1A577DC6B99F1"
EKS_NAMESPACE="cqi-prod-app-ns"
EKS_SERVICE_ACCOUNT="cqi-prod-app-sa"
CREDENTIAL_NAME="cqi-eks-federation"

3-2. Federated Credential JSON 생성

# Federated Credential 설정 파일 생성
cat > federated-credential.json << EOF
{
  "name": "$CREDENTIAL_NAME",
  "issuer": "$EKS_OIDC_ISSUER",
  "subject": "system:serviceaccount:$EKS_NAMESPACE:$EKS_SERVICE_ACCOUNT",
  "audiences": ["api://AzureADTokenExchange"],
  "description": "Federated credential for EKS workload identity"
}
EOF
필드 값 설명
name cqi-eks-federation Federated Credential 식별 이름
issuer CQI EKS OIDC Issuer URL CQI EKS 클러스터의 OIDC 발급자 URL (고정 값)
subject system:serviceaccount:cqi-prod-app-ns:cqi-prod-app-sa 신뢰할 Kubernetes Service Account (고정 값)
audiences api://AzureADTokenExchange Azure AD 토큰 교환 대상 (고정 값)
description Federated credential for EKS workload identity 설명 (선택 사항)

3-3. Federated Credential 추가

# Application Object ID 조회
APP_OBJECT_ID=$(az ad app list --display-name "$APP_NAME" --query "[0].id" --output tsv)

# Federated Credential 추가
az ad app federated-credential create \
  --id $APP_OBJECT_ID \
  --parameters federated-credential.json

출력 예시:

{
  "audiences": ["api://AzureADTokenExchange"],
  "description": "Federated credential for EKS workload identity",
  "id": "12345678-1234-1234-1234-123456789012",
  "issuer": "https://oidc.eks.ap-northeast-2.amazonaws.com/id/78FAD92A5614D6C424B1A577DC6B99F1",
  "name": "cqi-eks-federation",
  "subject": "system:serviceaccount:cqi-prod-app-ns:cqi-prod-app-sa"
}

3-4. Federated Credential 확인

# 등록된 Federated Credential 목록 확인
az ad app federated-credential list --id $APP_OBJECT_ID --output table

4. Azure RBAC 역할 할당

애플리케이션에 Azure 리소스에 접근할 수 있는 권한을 부여합니다.

참고: 필요한 역할

CQI 서비스가 호출하는 Azure API에 따라 다음 역할이 필요합니다:

Azure API 필요 역할 Scope
Security Assessment API Security Reader Subscription
Advisor API Reader Subscription
Cognitive Services API Reader Subscription

권장: Reader 역할 하나만 Subscription 레벨에 할당하면 모든 API 호출 가능

4-1. 역할 할당

# 변수 설정
SUBSCRIPTION_ID=$(az account show --query "id" --output tsv)

# Reader 역할 할당
az role assignment create \
  --role "Reader" \
  --assignee $APP_ID \
  --scope /subscriptions/$SUBSCRIPTION_ID

# Security Reader 역할 할당 (Security Assessment API 사용 시)
az role assignment create \
  --role "Security Reader" \
  --assignee $APP_ID \
  --scope /subscriptions/$SUBSCRIPTION_ID

4-2. 역할 할당 확인

# 할당된 역할 확인
az role assignment list \
  --assignee $APP_ID \
  --subscription $SUBSCRIPTION_ID \
  --output table

출력 예시:

Principal                             Role             Scope
------------------------------------  ---------------  ----------------------------------------
8339577f-971b-4d85-a206-c6c7eb654fcf  Reader           /subscriptions/12345678-1234-...
8339577f-971b-4d85-a206-c6c7eb654fcf  Security Reader  /subscriptions/12345678-1234-...

5. 클라우드용 Microsoft Defender Security Benchmark 활성화

MCSB는 Azure 리소스들에 대해 223개의 보안 권고 항목을 정의한 기본 정책 세트입니다. 진단 시 Azure Recommender 항목을 수집하기 위해 Microsoft Cloud Security Benchmark (MCSB)를 활성화합니다.

참고 MCSB 활성화는 Azure CLI로 지원되지 않습니다. Azure Portal에서 진행해 주세요.

→ Azure Portal 가이드 - 5. 클라우드용 Microsoft Defender Security Benchmark 활성화 참조


6. PSRule 사전 준비

6-1. Cloud Shell 준비

➡ Azure Portal에 접속한 뒤, 상단 메뉴에서 Cloud Shell 아이콘을 클릭합니다.

azure-psrule-guide-0

➡ Cloud Shell이 기본값인 Bash 모드로 열리면, 상단 드롭다운에서 "다음으로 전환: PowerShell" 을 클릭하여 PowerShell 모드로 전환합니다.

Cloud Shell이 Bash 모드일 경우 Install-Module 명령어를 인식하지 못합니다. 자세한 내용은 알려진 경고 메시지를 참조하세요.

azure-psrule-guide-00

6-2. PSRule 모듈 설치

➡ PSRule 코어 모듈을 먼저 설치합니다.

Install-Module PSRule -Scope CurrentUser;

➡ Untrusted repository 경고가 표시되면 A (Yes to All)를 입력합니다.

azure-psrule-guide-1

➡ PSRule.Rules.Azure 모듈을 설치합니다.

Install-Module -Name 'PSRule.Rules.Azure' -Scope CurrentUser;

➡ 동일하게 A (Yes to All)를 입력하여 설치를 완료합니다.

azure-psrule-guide-3

➡ 아래 명령어로 규칙이 정상적으로 로드되는지 확인합니다. Count 값이 0보다 크면 설치가 완료된 것입니다.

Get-PSRule -Module 'PSRule.Rules.Azure' | Measure-Object
azure-psrule-guide-2

6-3. 구독 정보 확인

➡ 아래 명령어로 현재 연결된 Azure 구독 정보를 확인합니다.

Get-AzContext

➡ 출력된 SubscriptionName, SubscriptionId를 확인하여 올바른 구독에 연결되어 있는지 검증합니다.

azure-psrule-guide-4

➡ 진단할 구독이 아닌 다른 구독으로 연결되어 있다면, 아래 명령어로 구독을 전환합니다.

Set-AzContext -SubscriptionId "<SubscriptionId>"

6-4. 추출용 폴더 생성 및 데이터 추출

➡ 데이터를 저장할 폴더를 생성합니다.

New-Item -ItemType Directory -Force -Path "$HOME/psrule-export"

-Force 옵션으로 폴더가 이미 있어도 오류 없이 진행됩니다. (재실행 시에도 그대로 사용 가능)

➡ 아래 명령어로 Azure 리소스 데이터를 추출합니다.

Export-AzRuleData -OutputPath "$HOME/psrule-export";

실행 중 WARNING: Failed to get ... 메시지가 출력될 수 있으나 무시하고 진행해도 됩니다. 자세한 내용은 PowerShell 사용 시 주의사항을 참조하세요.

azure-psrule-guide-5

➡ $HOME/psrule-export 경로에 구독 ID를 이름으로 하는 .json 파일이 생성되었는지 확인합니다.

Get-ChildItem "$HOME/psrule-export"
azure-psrule-guide-6

$HOME은 Cloud Shell 사용자 홈 디렉터리(예: /home/<사용자명>)를 가리킵니다. 실제 절대경로는 $HOME 명령어로 확인할 수 있으며, 이후 단계에서 $HOME 대신 절대경로를 사용해도 됩니다.


6-5. 데이터 분석 및 결과 파일 다운로드

➡ 분석 전, 추출 폴더로 이동하여 추출 파일(.json)이 있는지 다시 확인합니다.

Set-Location "$HOME/psrule-export"; Get-ChildItem *.json

파일이 조회되지 않거나 Cannot find path ... 오류가 발생하는 경우

Cloud Shell 세션이 도중에 끊겼다가(유휴 시간 초과, 브라우저 새로고침 등) 다시 연결되면, 스토리지 구성에 따라 이전 세션의 파일과 설치한 모듈이 남아 있지 않을 수 있습니다. 이 경우 6-2. PSRule 모듈 설치부터 다시 진행한 뒤, 6-4에서 데이터를 재추출하세요.

➡ 아래 명령어로 추출된 데이터를 PSRule로 분석하고 결과를 JSON 파일로 저장합니다.

Assert-PSRule -Module 'PSRule.Rules.Azure' -InputPath "$HOME/psrule-export" -OutputFormat Json -OutputPath "$HOME/psrule-result.json" -WarningAction SilentlyContinue
azure-psrule-guide-7

➡ 실행이 완료되면 처리된 규칙 수와 결과 파일 경로가 출력됩니다. Output written to the following file 메시지가 표시되면 정상입니다.

Assert-PSRule: One or more rules reported failure. 메시지는 규칙 위반이 발견된 경우 출력되는 정상 메시지입니다. 자세한 내용은 데이터 분석 시 (Assert-PSRule)를 참조하세요.

azure-psrule-guide-8

➡ Cloud Shell 상단 툴바에서 "파일 관리" 버튼을 클릭하고 "다운로드" 를 선택합니다.

azure-psrule-guide-9

➡ 다운로드 경로 입력창에 결과 파일의 전체 경로(앞 부분은 고정)를 입력하고 "다운로드" 버튼을 클릭합니다.

psrule-result.json
azure-psrule-guide-10

➡ 브라우저 하단에 다운로드 알림이 표시되면 파일명을 클릭하여 다운로드합니다.

azure-psrule-guide-11

7. 설정 검증

Azure 설정이 완료되었습니다. 이제 설정을 검증해봅시다.

7-1. Azure CLI에서 확인

# 애플리케이션 정보 확인
echo "=== 애플리케이션 정보 ==="
echo "Application (client) ID: $APP_ID"
echo "Directory (tenant) ID: $TENANT_ID"
echo "App Name: $APP_NAME"

# 페더레이션 자격 증명 확인
echo ""
echo "=== Federated Credentials ==="
az ad app federated-credential list --id $APP_OBJECT_ID --query "[].{Name:name, Issuer:issuer, Subject:subject}" --output table

# 역할 할당 확인
echo ""
echo "=== Role Assignments ==="
az role assignment list --assignee $APP_ID --output table

7-2. 정보 정리

다음 정보를 CQI 계정 등록에 사용합니다:

# Azure Federated Identity 정보
Tenant ID: <생성된 Tenant ID>
Client ID: <생성된 Client ID>
Subscription ID: <Subscription ID>

Client Secret 없음: Federated Identity는 Client Secret이 필요하지 않습니다!


CQI 진단 계정 등록

위에서 수집한 정보를 CQI 서비스에 등록합니다.

  1. CQI에 로그인
  2. 진단 계정 목록(Account List) 페이지로 이동
  3. 진단 계정 추가(Add Account) 버튼 클릭
  4. CSP로 Azure 선택
  5. 인증 방식에서 Workload Identity Federation 선택
  6. 다음 정보 입력:
    • Tenant ID: 생성된 Tenant ID
    • Client ID: 생성된 Client ID
    • Subscription ID: Subscription ID
  7. 필요한 정보 입력 후 등록
진단 계정 등록

참고: 트러블슈팅

문제 1: "AADSTS70021: No matching federated identity record found"

원인: Federated Credential의 Subject가 실제 EKS Service Account Token과 일치하지 않음

해결:

  1. Federated Credential의 Subject 확인:
    az ad app federated-credential list --id $APP_OBJECT_ID --query "[].subject" --output tsv
    
  2. Subject가 정확히 다음 값인지 확인:
    system:serviceaccount:cqi-prod-app-ns:cqi-prod-app-sa
    

문제 2: "AADSTS50107: The requested federation realm object does not exist"

원인: Cluster issuer URL이 잘못됨

해결:

  1. Federated Credential의 Issuer 확인:
    az ad app federated-credential list --id $APP_OBJECT_ID --query "[].issuer" --output tsv
    
  2. Issuer가 정확히 다음 값인지 확인:
    https://oidc.eks.ap-northeast-2.amazonaws.com/id/78FAD92A5614D6C424B1A577DC6B99F1
    

문제 3: "AADSTS700016: Application with identifier was not found"

원인: Client ID가 잘못되었거나 애플리케이션이 삭제됨

해결:

  1. 애플리케이션 존재 여부 확인:
    az ad app list --display-name "$APP_NAME" --output table
    
  2. Application (client) ID 재확인:
    az ad app list --display-name "$APP_NAME" --query "[0].appId" --output tsv
    
  3. 올바른 Tenant에서 작업하고 있는지 확인:
    az account show --query "{Tenant:tenantId, Subscription:name}" --output table
    

문제 4: Token exchange는 성공하지만 Azure API 호출 실패

원인: RBAC 역할이 할당되지 않았거나 부족함

해결:

  1. 역할 할당 확인:
    az role assignment list --assignee $APP_ID --output table
    
  2. 필요한 역할이 할당되었는지 확인
  3. 역할이 Subscription 레벨에 할당되었는지 확인 (Resource Group 레벨이 아님)

참고: PSRule

알려진 경고 메시지

데이터 추출 시 (Export-AzRuleData)

Export-AzRuleData 실행 중 아래 경고 메시지가 출력될 수 있습니다. 모두 WARNING 수준이며 JSON 파일 생성에는 영향을 주지 않습니다.

경고 유형 에러 코드 발생 조건 조치
UnsupportedApiVersion status=400 PSRule 모듈이 Microsoft.Security/DefenderForStorageSettings 조회 시 구버전 preview API(2022-12-01-preview) 사용 무시 가능. PSRule 모듈 업데이트 시 해결 예정
MethodNotAllowedInPricingTier status=400 API Management 리소스가 StandardV2 요금제인 경우 portalsettings API 조회 불가 무시 가능. 해당 요금제의 알려진 제한 사항
Our services aren't available right now status=503 Azure Resource Manager 일시 장애로 roleAssignments 조회 실패 재실행 권장. 일시적 장애로 재시도 시 정상 처리
Object reference not set to an instance of an object — 503 응답을 PSRule 내부에서 파싱하다 발생하는 null 참조 예외 재실행 권장. 503 에러 해소 시 함께 해결됨

데이터 분석 시 (Assert-PSRule)

메시지 의미 조치
Assert-PSRule: One or more rules reported failure. Azure 리소스 중 PSRule 규칙을 위반한 항목이 있음. 정상 종료 메시지 무시 가능. 결과 파일이 생성되었으면 정상
OperationStopped: Index was outside the bounds of the array. 특정 리소스 타입 처리 중 발생하는 PSRule 내부 버그 재실행 권장. -WarningAction SilentlyContinue 옵션 추가 시 결과 파일 생성 가능

PowerShell 사용 시 주의사항

주의사항 설명
Cloud Shell 모드 Cloud Shell이 Bash 모드로 열리면 Install-Module 등 PowerShell 명령어를 인식하지 못합니다. 반드시 PowerShell 모드로 전환 후 진행하세요.
경로 변수 PowerShell에서 경로에 변수를 사용할 때는 큰따옴표(") 를 사용해야 합니다. 작은따옴표(')는 변수를 치환하지 않습니다. (예: "$HOME/..." ✅ / '$HOME/...' ❌)
세션 끊김 세션이 끊긴 뒤 재연결되면 이전에 추출한 파일이나 설치한 모듈이 없을 수 있습니다. Get-ChildItem "$HOME/psrule-export"로 확인 후, 없으면 6-2부터 다시 진행하세요.

참고: 전체 스크립트 (One-Shot)

#!/bin/bash
# Azure Workload Identity Federation 설정 스크립트

set -e

# === 변수 설정 ===
APP_NAME="CQI-Workload-Identity"

# CQI 서비스 제공 정보 (고정 값)
EKS_OIDC_ISSUER="https://oidc.eks.ap-northeast-2.amazonaws.com/id/78FAD92A5614D6C424B1A577DC6B99F1"
EKS_NAMESPACE="cqi-prod-app-ns"
EKS_SERVICE_ACCOUNT="cqi-prod-app-sa"
CREDENTIAL_NAME="cqi-eks-federation"

# === 1. 애플리케이션 생성 ===
echo "Creating 애플리케이션..."
az ad app create --display-name "$APP_NAME" --sign-in-audience AzureADMyOrg

# === 2. 필수 정보 조회 ===
APP_ID=$(az ad app list --display-name "$APP_NAME" --query "[0].appId" --output tsv)
APP_OBJECT_ID=$(az ad app list --display-name "$APP_NAME" --query "[0].id" --output tsv)
TENANT_ID=$(az account show --query "tenantId" --output tsv)
SUBSCRIPTION_ID=$(az account show --query "id" --output tsv)

echo "Application (client) ID: $APP_ID"
echo "Directory (tenant) ID: $TENANT_ID"

# === 3. Service Principal 생성 ===
echo "Creating Service Principal..."
az ad sp create --id $APP_ID

# === 4. Federated Credential 추가 ===
echo "Adding Federated Credential..."
cat > federated-credential.json << EOF
{
  "name": "$CREDENTIAL_NAME",
  "issuer": "$EKS_OIDC_ISSUER",
  "subject": "system:serviceaccount:$EKS_NAMESPACE:$EKS_SERVICE_ACCOUNT",
  "audiences": ["api://AzureADTokenExchange"]
}
EOF
az ad app federated-credential create --id $APP_OBJECT_ID --parameters federated-credential.json
rm -f federated-credential.json

# === 5. RBAC 역할 할당 ===
echo "Assigning RBAC roles..."
az role assignment create --role "Reader" --assignee $APP_ID --scope /subscriptions/$SUBSCRIPTION_ID
az role assignment create --role "Security Reader" --assignee $APP_ID --scope /subscriptions/$SUBSCRIPTION_ID

# === 7. 설정 확인 ===
echo ""
echo "=== 설정 완료 ==="
echo "Application (client) ID: $APP_ID"
echo "Directory (tenant) ID: $TENANT_ID"
echo "Subscription ID: $SUBSCRIPTION_ID"
echo ""
echo "Federated Credentials:"
az ad app federated-credential list --id $APP_OBJECT_ID --output table
echo ""
echo "Role Assignments:"
az role assignment list --assignee $APP_ID --output table

참조


문서 버전: 1.2 최종 수정일: 2026-04-07 담당자: CQI 클라우드AX운영최적화팀(cloud-tech@lgcns.com)