
Microsoft DP-300 기반 Azure SQL Database 인증 및 권한 관리 실습 정리
Azure SQL Database에서 Microsoft Entra ID 기반 인증과 사용자·역할·권한 관리를 실습한다.
AdventureWorks 환경의 보안을 담당하는 DBA 역할로, Azure SQL Database에 Microsoft Entra ID 기반 인증을 구성하고 최소 권한 원칙(Least Privilege)을 적용한다.
EXECUTE AS USER를 이용한 권한 테스트기존 Azure AD(Azure Active Directory)의 새로운 이름이다.
Azure SQL Database의 인증 백엔드로 사용할 수 있으며 MFA, 조건부 액세스 등을 적용할 수 있다.
Azure SQL Logical Server 단위로 지정되는 관리자 계정이다.
해당 사용자는 서버 내 데이터베이스에 대한 최고 수준 권한을 가진다.
Master DB 로그인 없이 특정 데이터베이스 내부에서만 인증되는 사용자이다.
CREATE USER [username] WITH PASSWORD = 'password';
이 방식은 데이터베이스 이동성을 높인다.
권한을 묶어서 관리하기 위한 역할(Role)이다.
CREATE ROLE RoleName;
ALTER ROLE RoleName ADD MEMBER UserName;
현재 세션의 실행 컨텍스트를 특정 사용자로 변경하여 권한을 테스트한다.
EXECUTE AS USER = 'UserName'
원래 권한으로 돌아갈 때는 다음을 사용한다.
REVERT;
AdventureWorksLT 샘플 DB 생성 시:
AdventureWorksLT선택하여 생성한다.
구성되지 않음 클릭이 과정을 통해 해당 계정이 Azure SQL Server의 Entra Admin이 된다.
Azure Portal → SQL Server → Overview 에서 서버 이름 복사
예시:
myserver.database.windows.net
SSMS에서:
Connect → Database Engine
Server name 입력
Authentication:
Microsoft Entra MFAAzure Active Directory - Universal with MFA선택
처음 접속 시 클라이언트 IP를 방화벽에 추가해야 할 수 있다.
SSMS가 자동으로 추가 기능을 제공하기도 한다.
AdventureWorksLT 데이터베이스에서 새 쿼리를 생성한다.
CREATE USER [DP300User1] WITH PASSWORD = 'Azur3Pa$$';
GO
CREATE USER [DP300User2] WITH PASSWORD = 'Azur3Pa$$';
GO
이 사용자들은 AdventureWorksLT 데이터베이스 범위(scope) 안에서만 동작한다.
CREATE ROLE [SalesReader];
GO
ALTER ROLE [SalesReader] ADD MEMBER [DP300User1];
GO
ALTER ROLE [SalesReader] ADD MEMBER [DP300User2];
GO
CREATE OR ALTER PROCEDURE SalesLT.DemoProc
AS
SELECT
P.Name,
SUM(SOD.LineTotal) AS TotalSales,
SOH.OrderDate
FROM SalesLT.Product P
INNER JOIN SalesLT.SalesOrderDetail SOD
ON SOD.ProductID = P.ProductID
INNER JOIN SalesLT.SalesOrderHeader SOH
ON SOH.SalesOrderID = SOD.SalesOrderID
GROUP BY P.Name, SOH.OrderDate
ORDER BY TotalSales DESC
GO
이 프로시저는 상품별 매출 데이터를 조회한다.
EXECUTE AS USER = 'DP300User1'
EXECUTE SalesLT.DemoProc
실행 시 권한 오류가 발생한다.
The EXECUTE permission was denied on the object 'DemoProc'
왜냐하면 SalesReader 역할에는 아직 아무 권한도 없기 때문이다.
REVERT;
GRANT EXECUTE ON SCHEMA::SalesLT TO [SalesReader];
GO
REVERT
GRANT EXECUTE
EXECUTE AS USER = 'DP300User1'
EXECUTE SalesLT.DemoProc
이번에는 정상적으로 결과가 반환된다.
이번 실습에서 가장 중요한 개념이다.
DP300User1에게는 다음 테이블에 대한 SELECT 권한이 없다.
그런데도 Stored Procedure는 정상 동작했다.
이유는 SQL Server의 Ownership Chain(소유권 체인) 때문이다.
SQL Server는 Stored Procedure 실행 시:
즉:
사용자
→ 프로시저 실행 권한 검사
→ 내부 테이블 권한 검사 생략
→ 실행 성공
다음 객체들의 owner가 모두 dbo이다.
따라서 Ownership Chain이 끊기지 않는다.
Ownership Chain은 운영 환경에서 매우 많이 사용된다.
대표 패턴:
사용자에게 테이블 직접 권한은 주지 않음
↓
Stored Procedure 실행만 허용
↓
프로시저 내부에서 데이터 접근
이 방식의 장점:
권한이 강력한 만큼 위험성도 존재한다.
특히:
운영 환경 권장 사항:
WITH EXECUTE AS OWNER 사용다음 항목이 모두 성공하면 실습 완료이다.
실습 종료 후 삭제 가능:
DROP USER DP300User1;
DROP USER DP300User2;
DROP ROLE SalesReader;
운영 환경에서는 Entra Admin을 개인 계정보다는 보안 그룹 기반으로 관리하는 것이 일반적이다.
Azure SQL Database에서 Microsoft Defender for SQL을 활성화하고, 데이터 분류(Data Discovery & Classification), 취약성 평가(VA), Threat Detection, Auditing, Dynamic Data Masking까지 실습한다.
발견 → 경고 → 추적 → 보호
Azure SQL Database의 보안 기능이다.
주요 기능:
등을 제공한다.
DB 내부 컬럼을 스캔하여:
같은 민감 데이터를 자동 식별하고 분류(Label)를 부여한다.
보안 취약점을 자동 분석하는 기능이다.
예시:
등을 탐지한다.
데이터베이스 내부 이벤트를 기록하는 기능이다.
저장 위치:
등으로 전송 가능하다.
실제 데이터를 변경하지 않고:
조회 결과만 가려서 표시
하는 기능이다.
예시:
test@example.com
↓
tXXX@XXXX.com
경로:
SQL Server
→ Security
→ Microsoft Defender for Cloud
이후:
사용(Enable)
클릭
Configure 진입 후:
MICROSOFT DEFENDER FOR SQL = ON
상태인지 확인한다.
경로:
AdventureWorksLT
→ Security
→ Data Discovery & Classification
포털에서 다음 메시지가 표시된다.
15개의 열에서 민감 정보 발견
이후:
를 실행한다.
총:
이 자동 분류된다.
보안 취약점을 자동 스캔한다.
예시:
등을 탐지한다.
실제 보안 알림 흐름을 테스트한다.
Defender for Cloud 설정에서:
후 저장한다.
SSMS에서:
잘못된 비밀번호로 4~5회 로그인
시도
EXEC sp_executesql
N'SELECT * FROM sys.databases WHERE name = ''anything'' OR 1=1';
GO
또는:
DECLARE @sql NVARCHAR(MAX) =
N'SELECT * FROM sys.tables WHERE name LIKE ''%'' OR 1=1';
EXEC (@sql);
이후 Defender for Cloud의:
Security alerts
에서 알림을 확인한다.
예시:
분류 정보는:
sys.sensitivity_classifications
에 저장된다.
SELECT
SCHEMA_NAME(o.schema_id) AS [schema],
o.name AS [table],
c.name AS [column],
sc.label,
sc.information_type,
sc.rank_desc
FROM sys.sensitivity_classifications sc
INNER JOIN sys.objects o
ON sc.major_id = o.object_id
INNER JOIN sys.columns c
ON sc.major_id = c.object_id
AND sc.minor_id = c.column_id
ORDER BY [schema], [table], [column];
ADD SENSITIVITY CLASSIFICATION TO
SalesLT.Customer.MiddleName
WITH (
LABEL = 'Confidential',
LABEL_ID = '332211aa-bbcc-ddee-ff00-112233445566',
INFORMATION_TYPE = 'Name',
INFORMATION_TYPE_ID = '5b56518b-5a91-490b-9300-983344497a82',
RANK = MEDIUM
);
기존:
15개 컬럼
↓
추가 후:
16개 컬럼
으로 증가한다.
민감 데이터 접근 이력을 추적한다.
경로:
AdventureWorksLT
→ Auditing
→ Enable Azure SQL Auditing
이후:
를 수행한다.
SELECT TOP 10
EmailAddress,
FirstName,
LastName
FROM SalesLT.Customer;
GO
AzureDiagnostics
| where Category == "SQLSecurityAuditEvents"
| take 10
감사 로그 내부에:
data_sensitivity_information_s
필드가 자동 포함된다.
즉:
누가 민감 데이터를 조회했는가
를 추적할 수 있다.
민감 데이터를 일반 사용자에게 숨긴다.
ALTER TABLE SalesLT.Customer
ALTER COLUMN EmailAddress
ADD MASKED WITH (FUNCTION = 'email()');
GO
ALTER TABLE SalesLT.Customer
ALTER COLUMN Phone
ADD MASKED WITH (
FUNCTION = 'partial(0,"XXX-XXX-",4)'
);
GO
EXECUTE AS USER = 'DP300User1';
SELECT TOP 5
FirstName,
LastName,
EmailAddress,
Phone
FROM SalesLT.Customer;
REVERT;
일반 사용자는:
aXXX@XXXX.com
XXX-XXX-1234
형태로 보인다.
GRANT UNMASK TO DP300User1;
EXECUTE AS USER = 'DP300User1';
SELECT TOP 5
EmailAddress,
Phone
FROM SalesLT.Customer;
REVERT;
이번에는 실제 원본 데이터가 보인다.
REVOKE UNMASK FROM DP300User1;
ALTER TABLE SalesLT.Customer
ALTER COLUMN EmailAddress DROP MASKED;
ALTER TABLE SalesLT.Customer
ALTER COLUMN Phone DROP MASKED;
DDM은:
표시값만 가리는 기능
이다.
즉:
하다.
다음 조합으로 다층 방어를 구성한다.
Classification
→ DDM
→ TDE / Always Encrypted
→ RLS(Row-Level Security)
다음 항목이 모두 성공하면 실습 완료이다.
실습 종료 후:
등을 수행할 수 있다.
이번 실습에서는 Azure SQL Database 보안 기능 전반을 실습했다.
Defender 활성화
→ 민감 데이터 발견
→ Threat Detection
→ 감사 로그 수집
→ Dynamic Data Masking 보호
발견 → 탐지 → 감사 → 보호
Azure Monitor를 활용하여 Azure SQL Database의 CPU 사용률을 모니터링하고, 평균 CPU 사용량이 80%를 초과할 경우 이메일 알림을 전송하는 Alert Rule을 구성한다.
AdventureWorksLT 데이터베이스의 평균 CPU 사용률이 80%를 초과하면 자동으로 이메일 경고를 전송하도록 Azure Monitor Alert를 구성한다.
이번 실습에서는:
까지 수행한다.
Azure 리소스의 메트릭 또는 로그를 주기적으로 평가하여:
조건 충족 시 자동 작업(Action) 실행
하는 기능이다.
구성 요소:
으로 이루어진다.
Azure SQL Database의 평균 CPU 사용률 메트릭이다.
기본적으로:
1분 단위 집계
가 사용된다.
메트릭 집계 방식이다.
대표 유형:
이번 실습에서는:
Average
를 사용한다.
경고 발생 시 수행할 작업 묶음이다.
예시:
등을 연결할 수 있다.
경로:
AdventureWorksLT
→ Monitoring
→ Alerts
이후:
+ Create alert rule
선택
CPU percentage
선택
다음과 같이 설정한다.
| 항목 | 값 |
|---|---|
| Threshold Type | Static |
| Aggregation Type | Average |
| Operator | Greater than |
| Threshold Value | 80 |
즉:
평균 CPU 사용률 > 80%
조건이 되면 경고가 발생한다.
Alert Rule 생성 화면에서:
Actions
→ Create action group
선택
| 항목 | 값 |
|---|---|
| Action group name | emailgroup |
| Display name | emailgroup |
입력 후:
Next: Notifications
선택
다음과 같이 입력한다.
| 항목 | 값 |
|---|---|
| Notification type | Email/SMS message/Push/Voice |
| Name | DemoLab |
이후 이메일 주소 입력
Review + create
→ Create
를 눌러 Alert Rule과 Action Group을 생성한다.
구성이 완료되면:
You've been added to an Azure Monitor action group
형태의 이메일을 수신할 수 있다.
이후 실제 CPU 사용량이 80%를 초과하면 Azure Monitor Alert 메일이 전송된다.
실습 문서에서는 CPU 부하를 강제로 발생시키기 위한 쿼리를 제공한다.
SELECT
COUNT(*) AS TotalCount,
SUM(CAST(ABS(CHECKSUM(NEWID())) AS FLOAT)) AS RandomSum
FROM SalesLT.SalesOrderDetail a
CROSS JOIN SalesLT.SalesOrderDetail b
CROSS JOIN SalesLT.SalesOrderDetail c
WHERE
SQRT(POWER(a.UnitPrice, 2) + POWER(b.UnitPrice, 2)) > 100
AND a.OrderQty * b.OrderQty * c.OrderQty > 0;
이 쿼리는:
를 동시에 수행한다.
특히:
N × N × N
형태의 카테시안 곱이 발생하므로 CPU 부하가 매우 커진다.
DECLARE @StartTime DATETIME = GETDATE();
DECLARE @EndTime DATETIME = DATEADD(SECOND, 60, @StartTime);
DECLARE @Dummy FLOAT;
WHILE GETDATE() < @EndTime
BEGIN
SET @Dummy =
SQRT(PI() * RAND()) * POWER(RAND(), 2);
END;
약 1분 동안 지속적으로 CPU를 사용한다.
특징:
으로 인해 CPU 사용률을 강제로 상승시킨다.
다음 항목이 모두 성공하면 실습 완료이다.
경고 평가 주기이다.
예시:
주기를 사용할 수 있다.
짧을수록 민감하지만 비용과 false positive가 증가한다.
CPU > 80%
처럼 고정값 사용
Azure가 과거 패턴을 학습하여 자동 임계값을 계산한다.
트래픽 변동성이 큰 시스템에서는 Dynamic Threshold가 false positive를 줄여준다.
운영 환경에서는 보통:
| Severity | 용도 |
|---|---|
| Sev0 | 장애 수준 |
| Sev1 | 긴급 |
| Sev2 | 일반 경고 |
형태로 Action Group을 분리해 관리한다.
예시:
cpu-sev0-email
cpu-sev1-teams
cpu-sev2-monitoring
같은 형태로 표준화한다.
실습 종료 후 비용 절약을 위해:
를 수행할 수 있다.
이번 실습에서는 Azure SQL Database의 CPU 사용률을 기준으로 Azure Monitor Alert를 구성했다.
핵심 흐름은 다음과 같다.
CPU percentage 메트릭 선택
→ 임계값 설정
→ Action Group 생성
→ 이메일 알림 연결
→ 실제 CPU 부하 테스트
Azure Monitor Alert는 단순 이메일 기능이 아니라:
등 Azure 운영 전반의 핵심 기능으로 활용된다.
Azure 아키텍처를 단순 서비스 나열이 아니라 프레임워크 기반으로 설계하는 방법을 다룬 세미나 자료 정리
핵심 주제는 CAF(Cloud Adoption Framework), WAF(Well-Architected Framework), 그리고 Azure Reference Architecture이다.
프레임워크 기반으로 아키텍처를 평가하고 설계하는 사고방식
세미나에서는 클라우드 아키텍처 사고방식이 온프렘과 근본적으로 다르다고 설명한다.
장애가 안 나도록 비싸게 설계
장애는 반드시 발생한다고 가정
따라서:
기반으로 설계한다.
온프렘은:
CapEx
중심
클라우드는:
OpEx
중심이다.
즉:
자체가 비용 설계가 된다.
온프렘:
방화벽 중심
Azure:
Zero Trust
즉:
가 핵심 기준이 된다.
이번 세미나의 핵심이다.
CAF는:
회사가 클라우드를 어떻게 도입하는가
를 다룬다.
구성 단계:
즉:
회사 전체의 클라우드 여정
을 정의한다.
WAF는:
이 시스템 하나를 어떻게 잘 만들 것인가
를 평가한다.
즉:
각 워크로드마다 적용된다.
Azure WAF는 총 6개 관점으로 시스템을 평가한다.
| 기둥 | 핵심 질문 |
|---|---|
| Reliability | 장애가 나도 돌아가는가 |
| Security | 신원·데이터를 어떻게 보호하는가 |
| Cost Optimization | 필요한 만큼만 쓰는가 |
| Operational Excellence | 변경·관측이 자동화되어 있는가 |
| Performance Efficiency | 부하 변화에 맞게 확장되는가 |
| Sustainability | 자원·탄소를 줄이고 있는가 |
프레임워크 없이 설계하면:
반대로 프레임워크를 사용하면:
해진다.
세미나에서 가장 강조하는 부분이다.
모든 기둥을 동시에 완벽하게 만족하는 아키텍처는 없다
예시:
| 충돌 | 이유 |
|---|---|
| 신뢰성 ↔ 비용 | 멀티리전은 비쌈 |
| 보안 ↔ 성능 | Private Endpoint는 홉 증가 |
| 성능 ↔ 비용 | Premium SKU 비용 증가 |
| 운영 ↔ 성능 | 관측 시스템 자체 부하 |
즉:
좋은 아키텍처란
어떤 기둥을 왜 양보했는지 설명할 수 있는 아키텍처
이다.
Front Door
→ App Service
→ Azure SQL
보조 구성:
구조:
Bronze
→ Silver
→ Gold
흐름:
Event Hubs
→ ADLS Gen2
→ Databricks
→ Synapse
→ Power BI
원본 보존
정제·검증
비즈니스 집계
Container Apps
→ Azure OpenAI
→ AI Search
→ Cosmos DB
보조 서비스:
| 서비스 | 특징 |
|---|---|
| AI Search | 하이브리드 검색 |
| Cosmos DB | 글로벌 분산 |
| PostgreSQL + pgvector | 비용 효율 |
| 워크로드 | 주요 우선순위 |
|---|---|
| 표준 웹앱 | 신뢰성·보안 |
| 데이터 파이프라인 | 비용·성능 |
| AI 추론(RAG) | 보안·운영 |
| 워크로드 | 위험 |
|---|---|
| 웹앱 | DR 미검증 |
| 데이터 | 데이터 품질 |
| AI | 프롬프트 주입·비용 폭주 |
세미나 마지막에는 자신의 시스템을 WAF 기준으로 평가한다.
| 기둥 | 체크 항목 |
|---|---|
| 신뢰성 | DR / AZ / RPO / RTO |
| 보안 | Managed Identity / Key Vault |
| 비용 | Reservation / 자동 종료 |
| 운영 | IaC / 중앙 로그 |
| 성능 | 캐시 / Autoscale |
| 지속가능성 | Right-sizing |
이번 세미나의 핵심 메시지는 다음 한 문장으로 정리된다.
좋은 아키텍처는
완벽한 아키텍처가 아니라,
어떤 기둥을 왜 양보했는지 설명할 수 있는 아키텍처
그리고 WAF는:
서비스를 외우기 위한 프레임워크가 아니라,
좋은 질문을 하기 위한 프레임워크
이다.