CDK와 Pulumi로 IaC를 시작하는 개발자라면 주목! 과도한 추상화가 오히려 복잡성을 키우는 함정을 면접과 실무 관점에서 파헤치고, 현명한 도입 전략을 알아봅니다.
안녕하세요, 예비 개발자 여러분! 클라우드 인프라 자동화, 이른바 IaC(Infrastructure as Code)는 요즘 개발 트렌드에서 빼놓을 수 없는 핵심 역량 중 하나죠. 특히 AWS CDK나 Pulumi처럼 코드로 인프라를 정의하고 관리하는 도구들은 개발자들에게 익숙한 프로그래밍 언어로 인프라를 다룰 수 있게 해준다는 점에서 정말 매력적인데요.
하지만, 이 매력적인 도구들을 잘못 사용하면 오히려 독이 될 수 있다는 사실, 알고 계셨나요? 특히 "재사용성"이라는 달콤한 유혹에 빠져 과도하게 추상화를 시도하다가, 결국 복잡성이라는 함정에 빠지는 경우가 생각보다 많거든요. 오늘은 CDK와 Pulumi의 과도한 추상화가 어떻게 안티패턴이 되는지, 그리고 이런 함정을 피해서 면접과 실무에서 스마트하게 어필할 수 있는 방법은 무엇인지 함께 이야기해보려 합니다.
취업이나 이직을 준비하는 여러분이라면, 이 글을 통해 IaC 도구에 대한 깊이 있는 이해를 얻고, 단순히 "할 수 있다"를 넘어 "잘 할 수 있다"를 보여줄 수 있는 통찰력을 키울 수 있을 거예요. 자, 그럼 시작해볼까요?
📑 목차
- 1. IaC, 왜 알아야 하나요?: 인프라 자동화의 기본 이해
- 2. CDK와 Pulumi, 매력적인 추상화의 세계
- 2.1. 익숙한 프로그래밍 언어의 힘
- 2.2. 고수준(High-Level) 추상화 구조
- 3. 🚨 너무 깊은 추상화, 함정에 빠지다: 안티패턴의 시작
- 3.1. 투명성 상실 (Loss of Transparency)
- 3.2. 디버깅 및 문제 해결의 어려움
- 3.3. 버전 관리 및 의존성 복잡성
- 3.4. 러닝 커브 증가 및 온보딩 난이도 상승
- 4. 흔한 실수들: "재사용성"이라는 이름의 덫
- 4.1. 모든 것을 감추려는 욕망: 블랙박스 컴포넌트
- 4.2. 클라우드 서비스의 본질을 너무 많이 가리기
- 4.3. "일단 만들고 보자"식의 과도한 재사용성 강박
- 5. 면접과 실무에서 어필하는 현명한 접근법
- 5.1. 추상화는 '점진적으로', '필요할 때'
- 5.2. 추상화의 '탈출구(Escape Hatch)' 이해 및 활용
- 5.3. 클라우드 서비스의 기본 이해를 바탕으로
- 5.4. 가독성과 유지보수성을 최우선으로
- 6. 결론: 균형 잡힌 추상화, 똑똑한 개발자의 선택
Image by merlinlightpainting on Pixabay
1. IaC, 왜 알아야 하나요?: 인프라 자동화의 기본 이해
먼저, IaC가 왜 중요한지부터 짚고 넘어갈게요. 과거에는 서버를 만들고 네트워크를 구성하는 일이 수동 작업의 연속이었죠. 클릭하고, 설정하고, 또 클릭하고… 이런 방식은 시간이 오래 걸릴 뿐만 아니라, 사람의 실수로 인한 오류가 발생하기 쉬웠고, 환경마다 설정이 달라지는 '환경 불일치' 문제도 자주 겪었습니다. 개발자라면 이런 문제들에 공감하실 거예요.
IaC는 이러한 문제들을 해결하기 위해 인프라를 코드로 정의하고 관리하는 방법론이에요. 코드로 인프라를 정의하면 다음과 같은 장점들을 얻을 수 있습니다:
- 일관성 확보: 코드는 항상 동일한 결과를 만들어내니, 개발 환경, 스테이징 환경, 운영 환경이 모두 동일하게 구성될 수 있습니다.
- 빠른 배포 및 복구: 인프라를 빠르게 생성하고 변경하며, 문제가 생겼을 때도 코드를 통해 신속하게 복구할 수 있습니다.
- 버전 관리: 코드는 Git 같은 버전 관리 시스템으로 관리할 수 있으니, 인프라 변경 이력을 추적하고 언제든 이전 상태로 되돌릴 수 있습니다.
- 협업 용이성: 팀원들이 코드를 통해 인프라를 이해하고 함께 작업할 수 있습니다.
이런 장점들 때문에 클라우드 시대의 모든 기업들이 IaC를 도입하고 있고요. CDK나 Pulumi는 이 IaC를 구현하는 대표적인 도구들 중 하나인데요. 특히 Python, TypeScript, Go, Java 같은 익숙한 프로그래밍 언어로 인프라를 다룰 수 있게 해준다는 점에서 많은 개발자들의 사랑을 받고 있죠.
2. CDK와 Pulumi, 매력적인 추상화의 세계
CDK와 Pulumi는 "추상화"를 통해 개발자 경험을 혁신했다고 평가받는 도구들이에요. 이들이 제공하는 추상화는 크게 두 가지 방식으로 볼 수 있습니다.
2.1. 익숙한 프로그래밍 언어의 힘
기존의 대표적인 IaC 도구인 Terraform은 HCL(HashiCorp Configuration Language)이라는 자체 언어를 사용하고, AWS CloudFormation은 YAML이나 JSON을 사용하죠. 이 언어들은 인프라 정의에 특화되어 있지만, 일반적인 프로그래밍 로직을 구현하기에는 다소 제약이 많습니다. 예를 들어, 조건문이나 반복문을 복잡하게 사용하거나, 모듈화된 코드를 작성하기가 쉽지 않거든요.
반면, CDK와 Pulumi는 범용 프로그래밍 언어를 사용합니다. 여러분이 잘 아는 TypeScript, Python 등으로 코드를 작성하면, 이 코드가 내부적으로 CloudFormation 템플릿(CDK의 경우)이나 Pulumi 자체의 인프라 정의(Pulumi의 경우)로 변환되어 클라우드에 배포되는 방식이죠. 덕분에 개발자들은:
- 기존 프로그래밍 스킬 활용: 새로운 언어를 배울 필요 없이 바로 인프라 코드를 작성할 수 있습니다.
- 강력한 로직 구현: 조건문, 반복문, 함수, 클래스 등 프로그래밍 언어의 모든 기능을 활용하여 복잡한 인프라 로직을 유연하게 구현할 수 있습니다.
- 테스트 용이성: 일반 코드처럼 단위 테스트, 통합 테스트를 작성하여 인프라 코드의 안정성을 높일 수 있습니다.
2.2. 고수준(High-Level) 추상화 구조
CDK와 Pulumi는 단순한 '언어 바인딩'을 넘어, 고수준의 추상화된 컴포넌트(Constructs in CDK, Components in Pulumi)를 제공합니다. 예를 들어, AWS S3 버킷 하나를 만들 때 CloudFormation이나 Terraform에서는 여러 속성을 일일이 지정해야 하죠. 하지만 CDK에서는 new s3.Bucket(this, 'MyBucket'); 한 줄이면 기본적인 버킷이 생성됩니다. 이 한 줄 뒤에는 보안, 로깅 등 모범 사례를 따르는 여러 설정이 자동으로 포함될 수 있거든요.
이러한 고수준 추상화 덕분에 개발자들은:
- 생산성 향상: 적은 코드로 더 많은 인프라를 구성할 수 있습니다.
- 모범 사례 내재화: 클라우드 공급자의 모범 사례(예: 보안 설정, 로깅 활성화)가 기본적으로 적용된 컴포넌트를 사용할 수 있습니다.
- 재사용성 증대: 특정 서비스 패턴(예: 웹서버 + DB + 로드밸런서)을 하나의 추상화된 컴포넌트로 만들어 여러 프로젝트에서 재사용할 수 있습니다.
이것만 보면 정말 꿈의 도구처럼 들리죠? 하지만 바로 이 "재사용성"과 "고수준 추상화"가 때로는 양날의 검이 될 수 있습니다.
3. 🚨 너무 깊은 추상화, 함정에 빠지다: 안티패턴의 시작
CDK와 Pulumi의 강력한 추상화 기능은 잘 쓰면 약이 되지만, 잘못 쓰면 독이 됩니다. 특히 '재사용성을 극대화하겠다!'는 좋은 의도로 시작했지만, 결과적으로는 인프라를 더 복잡하게 만드는 과도한 추상화(Over-abstraction)는 대표적인 안티패턴 중 하나예요.
과도한 추상화의 함정에 빠지면 어떤 문제들이 생길까요?
3.1. 투명성 상실 (Loss of Transparency)
추상화의 본질은 내부 구현을 숨기는 것이죠. 하지만 너무 많은 것을 숨기면, 실제 클라우드 리소스가 어떻게 구성되는지 파악하기 어려워집니다. 예를 들어, MySuperMegaAppConstruct라는 컴포넌트를 만들었는데, 이 안에 EC2, RDS, VPC, 로드밸런서, 심지어 모니터링 설정까지 다 들어있다고 가정해 보세요.
// 예시: 너무 복잡하게 추상화된 CDK Construct
class MySuperMegaAppConstruct extends cdk.Construct {
constructor(scope: cdk.Construct, id: string, props: MySuperMegaAppProps) {
super(scope, id);
// VPC 생성 및 서브넷 구성 (내부적으로 수많은 네트워크 설정 포함)
const vpc = new MyAbstractVpc(this, 'MyVpc', props.vpcConfig);
// EC2 인스턴스, Auto Scaling Group, 로드밸런서 구성 (내부적으로 복잡한 보안 그룹, 사용자 데이터 스크립트 포함)
const webService = new MyAbstractWebService(this, 'WebService', {
vpc: vpc,
instanceType: props.instanceType,
minInstances: props.minInstances
});
// RDS 데이터베이스 생성 (내부적으로 다양한 DB 파라미터 그룹, 백업 설정 포함)
new MyAbstractDatabase(this, 'Database', {
vpc: vpc,
dbType: props.dbType
});
// 모니터링 및 알림 설정 (CloudWatch 대시보드, SNS 알림 등)
new MyAbstractMonitoring(this, 'Monitoring', {
targetService: webService
});
// ... 그 외 수많은 숨겨진 로직
}
}
// 실제 사용 코드 (겉으로는 간단해 보이지만, 내부적으로는 블랙박스)
new MySuperMegaAppConstruct(stack, 'MyApplication', {
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM),
minInstances: 2,
dbType: rds.DatabaseInstanceEngine.POSTGRES,
// ... 등등 수십 개의 설정이 필요할 수도
});
이 컴포넌트를 사용하는 사람은 내부에서 어떤 일이 일어나는지, 어떤 리소스가 생성되는지 한눈에 파악하기 어렵습니다. 면접관이 "이 코드를 배포하면 어떤 리소스들이 생성될까요?"라고 물었을 때, 여러분이 답하기 어렵다면 이미 투명성을 잃은 거죠.
3.2. 디버깅 및 문제 해결의 어려움
투명성이 떨어지면 디버깅은 지옥이 됩니다. 특정 리소스에서 문제가 발생했을 때, 추상화된 코드와 실제 클라우드 리소스 간의 매핑을 찾아내기가 매우 어렵거든요. 예를 들어, S3 버킷의 CORS 설정에 문제가 생겼는데, 이 버킷이 MySharedStorageConstruct 안에 숨겨져 있다면, 어디서 설정을 찾아야 할지 헤맬 수밖에 없습니다. 실제 클라우드 서비스의 콘솔이나 로그를 봐도, 어떤 코드 때문에 이런 현상이 발생했는지 역추적하는 데 엄청난 시간이 소요되죠.
3.3. 버전 관리 및 의존성 복잡성
과도하게 추상화된 컴포넌트는 마치 거대한 라이브러리처럼 동작합니다. 이 컴포넌트가 업데이트될 때마다, 이를 사용하는 모든 프로젝트에 영향을 미치게 되죠. 작은 변경 사항 하나가 예상치 못한 사이드 이펙트를 일으킬 수도 있고, 하위 호환성을 유지하기 위한 노력이 과도해질 수 있습니다. 마치 하나의 거대한 모노리틱 애플리케이션처럼요.
3.4. 러닝 커브 증가 및 온보딩 난이도 상승
새로운 팀원이 온보딩할 때, 클라우드 공급자의 기본 서비스(AWS S3, EC2 등)를 이해하는 것 외에, 팀에서 자체적으로 만든 복잡한 추상화 레이어를 또 이해해야 합니다. 이는 학습 곡선을 가파르게 만들고, 생산성을 저해하는 요인이 됩니다. "이 컴포넌트 안에는 어떤 로직이 숨겨져 있는 거지?"라는 질문에 답하기 위해 수많은 코드를 뒤져봐야 한다면, 이미 비효율적인 상황이죠.
Image by doradesigning on Pixabay
4. 흔한 실수들: "재사용성"이라는 이름의 덫
과도한 추상화는 대개 "재사용성"을 극대화하려는 좋은 의도에서 시작됩니다. 하지만 그 과정에서 몇 가지 흔한 실수를 저지르게 되는데요. 면접에서 이런 실수를 꿰뚫어보고 현명한 대안을 제시할 수 있다면, 여러분의 역량을 훨씬 더 효과적으로 어필할 수 있을 거예요.
4.1. 모든 것을 감추려는 욕망: 블랙박스 컴포넌트
가장 흔한 실수 중 하나는 '모든 것을 감추고' 하나의 컴포넌트로 모든 기능을 처리하려는 시도입니다. 마치 "이 컴포넌트만 쓰면 웹 서비스가 뚝딱!" 하고 만들어지는 마법의 상자를 만들고 싶어 하는 거죠. 하지만 현실의 인프라는 환경마다, 서비스마다 미묘하게 다른 요구사항을 가집니다. 이런 요구사항을 모두 수용하려다 보면, 컴포넌트의 설정(Props)은 기하급수적으로 늘어나고, 내부 로직은 복잡해지며, 결국 어떤 환경에도 완벽하게 맞지 않는 제너럴한 블랙박스가 되어버립니다.
예를 들어, S3 버킷 하나를 만드는데, 웹 호스팅용, 로그 저장용, 백업용 등 모든 옵션을 하나의 컴포넌트에 때려 넣는다면, 사용하는 사람은 필요한 옵션을 찾기 위해 수많은 Props를 뒤져봐야 할 겁니다.
4.2. 클라우드 서비스의 본질을 너무 많이 가리기
CDK나 Pulumi는 클라우드 공급자의 원시 리소스(CloudFormation 리소스, AWS API) 위에 추상화 레이어를 덧씌우는 방식이에요. 그런데 이 추상화가 클라우드 서비스의 핵심 개념 자체를 너무 많이 가려버리면 문제가 생깁니다. 예를 들어, VPC의 서브넷 구성이나 보안 그룹의 작동 방식 등 클라우드 서비스의 기본적인 메커니즘을 컴포넌트가 완전히 숨겨버리면, 개발자는 클라우드에 대한 이해 없이 '마법의 컴포넌트'만 사용하게 됩니다.
이런 경우, 문제가 발생했을 때 클라우드 서비스 콘솔을 보고도 원인을 파악하지 못하거나, 커스텀 요구사항에 대응하지 못하는 상황에 직면하게 되죠. 면접관은 여러분이 CDK/Pulumi를 아는 것을 넘어, 그 밑단의 클라우드 서비스를 얼마나 이해하고 있는지 궁금해할 수 있습니다.
4.3. "일단 만들고 보자"식의 과도한 재사용성 강박
코드 재사용은 좋은 목표지만, 적절한 시점에 이루어져야 합니다. 인프라 코드를 작성할 때, 아직 패턴이 명확히 드러나지 않았는데도 "나중에 분명히 쓸 거야!"라는 생각으로 미리 복잡한 추상화 컴포넌트를 만드는 경우가 있습니다. 이는 시간 낭비일 뿐만 아니라, 실제로 재사용되지 않거나, 재사용되더라도 매번 수정이 필요한 '불완전한' 컴포넌트를 양산하게 됩니다.
YAGNI (You Ain't Gonna Need It) 원칙은 소프트웨어 개발뿐만 아니라 IaC에서도 중요해요. '필요할 때' 추상화하고, '반복되는 패턴'이 명확해질 때 모듈화하는 것이 현명합니다.
Image by doradesigning on Pixabay
5. 면접과 실무에서 어필하는 현명한 접근법
그렇다면 우리는 CDK와 Pulumi를 어떻게 사용해야 할까요? 면접과 실무에서 여러분의 역량을 빛낼 수 있는 현명한 접근법을 알려드릴게요.
5.1. 추상화는 '점진적으로', '필요할 때'
가장 중요한 원칙은 추상화를 점진적으로, 그리고 필요할 때만 하는 것입니다. 처음부터 모든 것을 추상화하려 하지 마세요. 일단 가장 기본적인 형태로 인프라를 구성하고, 동일한 패턴이 두세 번 이상 반복될 때 비로소 추상화를 고려하는 것이 좋습니다.
예를 들어, 처음에는 S3 버킷을 직접 생성하고, 그 다음 프로젝트에서도 동일한 설정의 S3 버킷이 필요하다면 그때서야 '우리 팀의 표준 S3 버킷' 컴포넌트를 만드는 식이죠. 이렇게 하면 불필요한 추상화로 인한 복잡성을 피하고, 실제 필요한 재사용성을 확보할 수 있습니다.
| 좋은 추상화 | 나쁜 추상화 |
|---|---|
| 목표: 특정 도메인/팀의 반복 패턴 간소화 | 목표: 모든 것을 포괄하는 범용 컴포넌트 생성 |
| 시점: 반복되는 패턴이 명확해진 후 | 시점: 초기 단계부터 과도한 예측으로 시작 |
| 특징: 내부 동작이 예측 가능하고, 필요시 오버라이드 가능 | 특징: 내부가 블랙박스이고, 커스텀이 어려움 |
| 결과: 생산성 향상, 유지보수 용이 | 결과: 복잡성 증가, 디버깅 난이도 상승 |
5.2. 추상화의 '탈출구(Escape Hatch)' 이해 및 활용
CDK와 Pulumi는 고수준 추상화를 제공하면서도, 필요할 경우 하위 수준의 리소스에 직접 접근할 수 있는 '탈출구(Escape Hatch)'를 제공합니다. 예를 들어, CDK에서는 특정 Construct가 생성하는 CloudFormation 리소스에 직접 접근하여 속성을 변경할 수 있거든요.
// CDK에서 L2 Construct (고수준 추상화) 사용
const bucket = new s3.Bucket(this, 'MyBucket');
// Escape Hatch를 사용하여 하위 CloudFormation 리소스에 접근 및 직접 수정
const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;
cfnBucket.versioningConfiguration = {
status: 'Enabled' // 기본 Construct에 없는 속성이나 미세 조정
};
이러한 탈출구를 잘 알고 활용하는 것은 매우 중요합니다. 이는 여러분이 추상화의 편리함과 하위 레벨 제어의 유연성 사이에서 균형을 잡을 수 있는 능력을 가졌다는 것을 보여주는 증거가 됩니다. 면접에서 "CDK/Pulumi로 모든 것을 해결할 수 없을 때 어떻게 대처할 건가요?"라는 질문에 대한 훌륭한 답변이 될 수 있죠.
5.3. 클라우드 서비스의 기본 이해를 바탕으로
아무리 좋은 IaC 도구를 사용하더라도, 그 밑에서 돌아가는 클라우드 서비스 자체에 대한 깊은 이해는 필수적입니다. CDK로 S3 버킷을 만든다고 해서 S3 버킷의 작동 방식, 보안 모델, 비용 구조를 몰라도 되는 것은 아니거든요.
CDK나 Pulumi는 '도구'일 뿐, '목표'가 아닙니다. 이 도구들을 통해 어떤 클라우드 리소스를 만들고, 그 리소스들이 어떻게 상호작용하는지 명확히 이해해야 합니다. 면접에서 "CDK를 사용하시는데, CloudFormation에 대해서는 얼마나 알고 계신가요?" 같은 질문을 받을 수 있어요. 이때 여러분이 추상화된 코드 뒤에 숨겨진 실제 인프라를 이해하고 있다는 것을 보여줄 수 있어야 합니다.
5.4. 가독성과 유지보수성을 최우선으로
결국 인프라 코드도 소프트웨어 코드와 마찬가지로 가독성과 유지보수성이 가장 중요합니다. 아무리 재사용성이 높다고 해도, 다른 사람이 이해하기 어렵거나, 변경하기 어려운 코드는 좋은 코드가 아니거든요.
- 명확한 이름 짓기: 컴포넌트 이름, 변수 이름 등을 명확하게 지어 어떤 역할을 하는지 쉽게 알 수 있게 합니다.
- 적절한 주석: 복잡한 로직이나 비즈니스 규칙이 적용된 부분에는 주석을 달아 설명합니다.
- 작고 응집력 있는 컴포넌트: 하나의 컴포넌트가 너무 많은 역할을 하지 않도록, 작고 특정 기능에만 집중하는 형태로 만듭니다.
이러한 원칙들은 면접에서 "좋은 코드란 무엇이라고 생각하나요?" 또는 "유지보수하기 좋은 인프라 코드를 위해 어떤 노력을 하시나요?" 같은 질문에 답할 때 여러분의 깊이 있는 사고를 보여줄 수 있는 포인트가 될 겁니다.
6. 결론: 균형 잡힌 추상화, 똑똑한 개발자의 선택
CDK와 Pulumi는 분명 클라우드 인프라 관리에 혁신을 가져다준 강력한 도구들입니다. 하지만 모든 강력한 도구가 그렇듯이, 어떻게 사용하느냐에 따라 그 결과는 천차만별이죠. 과도한 추상화는 재사용성이라는 달콤한 환상 뒤에 복잡성, 투명성 상실, 디버깅 지옥이라는 함정을 숨기고 있습니다.
주니어 개발자로서 IaC 도구를 다룰 때는 단순히 '문법'을 아는 것을 넘어, '어떻게 하면 인프라를 효율적이고 안정적으로 관리할 수 있을까?'라는 본질적인 질문에 답할 수 있어야 합니다. 이를 위해서는 추상화의 장점은 취하되, 그 한계와 부작용을 명확히 이해하고, 균형 잡힌 시각으로 접근하는 것이 중요해요.
면접에서 "CDK/Pulumi를 사용해본 경험이 있습니다"라고 말하는 것도 좋지만, "CDK/Pulumi의 강력한 추상화 기능이 때로는 과도한 복잡성을 야기할 수 있다고 생각합니다. 저는 이런 문제를 해결하기 위해 [점진적 추상화], [탈출구 활용], [클라우드 서비스 기본 이해]와 같은 방식으로 접근하여, 실제 비즈니스에 도움이 되는 가독성 높고 유지보수 가능한 인프라 코드를 작성하고자 합니다"라고 말할 수 있다면, 여러분은 이미 한 단계 높은 수준의 개발자로 인정받을 수 있을 거예요.
추상화는 목적이 아니라, 더 나은 개발을 위한 '수단'입니다. 이 점을 항상 기억하고 현명하게 IaC 도구들을 활용하시길 바랍니다!
오늘 다룬 내용에 대해 궁금한 점이나 여러분의 경험이 있다면 댓글로 공유해주세요. 함께 배우고 성장하는 기회가 되었으면 좋겠습니다!
📌 함께 읽으면 좋은 글
- [클라우드 인프라] 클라우드 런, 배치와 지속 실행 워크로드에 현명한 선택일까?
- [클라우드 인프라] 클라우드 환경 DNS, 복잡한 트래픽 연결 왜 팀의 핵심 고민이 될까?
- [게임 개발] 게임 핵 방지, 클라이언트와 서버 검증 중 어떤 솔루션을 선택해야 할까?
이 글이 도움이 되셨다면 공감(♥)과 댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.
'클라우드 인프라' 카테고리의 다른 글
| 내 MySQL 백엔드, AWS Aurora Serverless V2와 Pulumi로 어떻게 마이그레이션할까? (0) | 2026.07.16 |
|---|---|
| 메인프레임 JCL vs 클라우드 네이티브 워크플로우: 현대화를 위한 전환 전략 (0) | 2026.07.15 |
| 클라우드 환경 DNS, 복잡한 트래픽 연결 왜 팀의 핵심 고민이 될까? (0) | 2026.07.12 |
| 클라우드 런, 배치와 지속 실행 워크로드에 현명한 선택일까? (0) | 2026.07.12 |
| AWS VPC Flow Logs, 당신이 모르는 치명적 함정: 네트워크 가시성 확보의 본질적 접근법 (1) | 2026.07.09 |