<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Terraform on J2eff's Garage</title><link>https://blog.j2eff.me/tags/terraform/</link><description>Recent content in Terraform on J2eff's Garage</description><generator>Hugo -- gohugo.io</generator><language>ko-KR</language><lastBuildDate>Sun, 17 Aug 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.j2eff.me/tags/terraform/index.xml" rel="self" type="application/rss+xml"/><item><title>Packer로 Ubuntu 22.04 QCOW2 베이스 이미지 만들기</title><link>https://blog.j2eff.me/p/packer%EB%A1%9C-ubuntu-22.04-qcow2-%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A7%8C%EB%93%A4%EA%B8%B0/</link><pubDate>Sun, 17 Aug 2025 00:00:00 +0000</pubDate><guid>https://blog.j2eff.me/p/packer%EB%A1%9C-ubuntu-22.04-qcow2-%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A7%8C%EB%93%A4%EA%B8%B0/</guid><description>&lt;p&gt;로컬에 데이터센터를 만들려면 맨 아래층부터 시작해야 한다. 그 시작이 VM이다. 그런데 우분투를 매번 ISO로 깔면 유저 만들고, 디스크 나누고, 패키지 설치하는 데만 20–30분이 든다. 실습 환경을 열 번 갈아엎으면 그 시간도 열 배가 된다.&lt;/p&gt;
&lt;p&gt;이 글에서는 &lt;a class="link" href="https://github.com/j2eff-we/lab-infra" target="_blank" rel="noopener"
 &gt;lab-infra&lt;/a&gt; 프로젝트로 로컬 KVM 기반 VM 실습 환경을 자동으로 구성한다. Packer로 Ubuntu 22.04 기반 이미지를 한 번 빌드해두고, 이후 libvirt + Terraform으로 몇 초 만에 VM을 찍어내는 것이 목표다. 이 편은 그 첫 단계 — &lt;strong&gt;베이스 이미지 만들기&lt;/strong&gt;다.&lt;/p&gt;
&lt;h2 id="시리즈-로드맵"&gt;시리즈 로드맵
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;0편: Packer로 base 이미지 생성 (이 글)&lt;/li&gt;
&lt;li&gt;1편: Terraform으로 libvirt provider 설정&lt;/li&gt;
&lt;li&gt;2편: VM 프로비저닝 및 네트워킹 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="왜-packer인가"&gt;왜 Packer인가
&lt;/h2&gt;&lt;p&gt;Packer는 HashiCorp에서 만든 이미지 빌드 도구다. 하나의 구성으로 여러 플랫폼에 동일한 이미지를 자동 생성할 수 있다. 우분투 ISO로 매번 수동 설치하는 대신 &lt;strong&gt;커스텀 이미지&lt;/strong&gt;를 만들어두면, 설치 시간이 줄고 환경이 통일된다. CI/CD·테스트·실험용 VM처럼 같은 환경을 반복해서 띄우는 경우에 특히 유리하다.&lt;/p&gt;
&lt;p&gt;실제로 이런 상황에서 값어치를 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;여러 명이 동일한 실습 환경을 써야 할 때&lt;/li&gt;
&lt;li&gt;서버를 부팅하자마자 곧바로 서비스 테스트가 가능해야 할 때&lt;/li&gt;
&lt;li&gt;CI 파이프라인에서 반복적으로 VM을 생성하는 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="qcow2는-무엇이고-왜-쓰는가"&gt;qcow2는 무엇이고 왜 쓰는가
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;qcow2&lt;/code&gt;는 QEMU/KVM에서 쓰는 가상 디스크 포맷이다. 세 가지 이점이 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;스냅샷을 지원한다.&lt;/li&gt;
&lt;li&gt;sparse·압축으로 디스크 공간을 절약한다.&lt;/li&gt;
&lt;li&gt;VM 간 공유와 배포가 쉽다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="커스텀-이미지를-만드는-이유"&gt;커스텀 이미지를 만드는 이유
&lt;/h2&gt;&lt;p&gt;기본 Ubuntu ISO로 설치하면 부팅 후 유저 생성, 디스크 파티션 설정, 패키지 설치 같은 수동 과정을 거쳐 20–30분이 걸린다. Packer에 cloud-init을 붙이면 유저·hostname·ssh key·커널 설치까지 자동화된 qcow2 이미지를 만들 수 있다. 그러면 같은 환경에서 수초–수분 내에 VM이 뜬다. 초기화 시간이 줄고 반복 작업이 사라지므로, 테스트 자동화(CI/CD, GitHub Actions 등)에도 그대로 이어진다.&lt;/p&gt;
&lt;h2 id="사전-준비"&gt;사전 준비
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Ubuntu 기반 호스트 (예: Ubuntu 22.04 Desktop)&lt;/li&gt;
&lt;li&gt;가상화 지원 CPU (BIOS에서 VT-x/AMD-V 활성화)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;git&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;libvirt&lt;/code&gt;, &lt;code&gt;qemu&lt;/code&gt;, &lt;code&gt;packer&lt;/code&gt;, &lt;code&gt;tfenv&lt;/code&gt; 등은 아래 과정에서 자동으로 설치된다. Terraform 버전은 &lt;code&gt;.terraform-version&lt;/code&gt; 파일을 통해 자동으로 선택된다.&lt;/p&gt;
&lt;h2 id="1단계-초기-설정"&gt;1단계: 초기 설정
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt install -y build-essential curl git sudo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# lab-infra 프로젝트 클론&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/j2eff-we/lab-infra.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; lab-infra/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="2단계-의존성-준비"&gt;2단계: 의존성 준비
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make setup-sudoers &lt;span class="c1"&gt;# 실행 후 로그아웃 → 재접속&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make prepare &lt;span class="c1"&gt;# 실행 후 로그아웃 → 재접속 (libvirt 그룹 적용)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;두 명령 모두 그룹 권한이 새로 붙기 때문에, 실행한 다음 로그아웃 후 다시 접속해야 반영된다.&lt;/p&gt;
&lt;h2 id="3단계-qemu--packer-버전-확인"&gt;3단계: QEMU / Packer 버전 확인
&lt;/h2&gt;&lt;p&gt;환경이 제대로 깔렸는지 빠르게 확인한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;make check
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;예상 출력은 이렇다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Packer version: Packer v1.10.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;QEMU version: QEMU emulator version 8.2.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;출력이 비어 있거나 버전이 안 나오면, &lt;code&gt;make prepare&lt;/code&gt; 이후 터미널을 재시작하거나 로그아웃 후 다시 로그인해야 한다.&lt;/p&gt;
&lt;h2 id="4단계-packer로-이미지-빌드"&gt;4단계: Packer로 이미지 빌드
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; base/packer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;packer init ubuntu.pkr.hcl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;packer build jammy.json
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ubuntu ISO는 자동으로 다운로드된다. 첫 빌드는 ISO 다운로드와 설치로 &lt;strong&gt;약 15–30분&lt;/strong&gt;이 걸린다. 빌드 도중 실패하면 &lt;code&gt;[context canceled]&lt;/code&gt; 에러가 날 수 있는데, 다시 시도하면 된다.&lt;/p&gt;
&lt;p&gt;빌드가 끝나면 결과물 &lt;code&gt;.qcow2&lt;/code&gt; 파일을 확인한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ls -lh base/packer/build-jammy-base/*.qcow2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;성공하면 이런 메시지가 나온다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;-rw-r--r-- 1 user user 1.3G Dec 15 10:30 build-jammy-base/ubuntu-jammy-base.qcow2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="템플릿-구조"&gt;템플릿 구조
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ubuntu.pkr.hcl&lt;/code&gt; — 메인 entrypoint. 실제로 쓸 빌더와 변수 파일을 정의한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jammy.json&lt;/code&gt; — 빌더, 부트 커맨드, 디스크 포맷, ISO 설정을 담는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;http/&lt;/code&gt; — cloud-init 설정이 들어 있고, Packer가 빌드 중 로컬 서버로 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="다음-편"&gt;다음 편
&lt;/h2&gt;&lt;p&gt;베이스 이미지가 생겼으니, 다음 편에서는 이 이미지를 Terraform libvirt provider로 VM에 적용하고 실제로 띄워본다.&lt;/p&gt;</description></item></channel></rss>