クラウドに頼らないIaC入門〜Vagrant + Linux VMで作る自分だけの実験場〜
1. はじめに
本記事をご覧頂き、ありがとうございます。
クラウド環境を構築するためのガイドとなるべく、作成しました。
筆者はGCPの使用経験がありますが、まずは特定のクラウド環境に依存しない形で構築をすすめます。
今回はVagrantとゲストOSをUbuntuで構築します。
最初に、Vagrantは、開発環境の自動化ツール で、仮想マシン(VM)の作成・管理を簡単にできる特徴があります。
特に、以下の点でメリットがあります:
✅ 環境構築が一瞬 → Vagrantfile
を1つ用意すれば、環境を統一できる
✅ クラウド環境のローカル版が作れる → Terraformと組み合わせると強力
✅ 簡単にコピー&共有できる → チーム開発や副業のテスト環境に最適
今回はVagrantを使ってコマンドラインでCI/CDパイプラインを構築するまでを行います。
テストに使う言語はpythonで、簡単なコードを記述します。
Infrastructure as Code:IaCっと聞くとなんとなく難しいイメージがあるかもしれません。
ですが、要素を分解していくと意外と単純です。
楽しんでいきましょう!
2. 対象読者
クラウド環境でよく使われているCI/CDパイプラインですが、
- 初めて触る
- 聞いたことはある
- 図解付きで解説してほしい
このような方を対象とします。
想定作業時間は2~3時間程度です。
正直、中上級者にとっては冗長に思うかもしれません。
環境構築からやっていくので、一緒に手を動かしなら楽しみましょう!
3. Vagrant の基本的な仕組み
Vagrantは、VirtualBox や KVM, Hyper-V などの仮想化ソフトを管理するラッパー のようなもの。
コマンドを実行するだけで、仮想マシンの作成・削除・変更が可能です。
-
Vagrantfile に環境の定義を記述
※自動的に生成されますが、後ほど設定を追加します。 -
vagrant up
で仮想マシンを起動 -
vagrant ssh
でログイン -
vagrant destroy
で削除可能
4. Vagrant の導入(Ubuntu 20.04 の仮想マシンを作る)
1.** Vagrant のインストール**
Mac/Linux(Homebrew または apt)
brew install vagrant
または:
sudo apt update && sudo apt install -y vagrant
Windows(Chocolatey)
choco install vagrant
コマンドラインでもインストールできそうですが、僕は以下の公式サイトからダウンロードしました。
[公式サイト]
Community→Downroadをクリックすると、以下のページが出てくるので、
OSはWindowsを使っているので、Windows版のi686を選びました。
ダウンロードしたインストーラをクリックするとインストールが開始します。
利用規約にチェックしてインストール開始
しばらく待ちます。
5分ぐらいで完了しました。
2. ** 仮想マシンを作成**
- Vagrantfile を作成
mkdir vagrant-test
cd vagrant-test
vagrant init ubuntu/focal64
これで
Vagrantfile
という設定ファイルが作成される。
- 仮想マシンを起動
vagrant up
色々とログが出力されていますが、
VirtualBox側でもVMが起動していることが分かります。
VirtualBox や Hyper-V で Ubuntu の仮想マシンが起動できた。
- 仮想マシンにログイン
vagrant ssh
ちゃんと接続できましたね!
SSHで仮想マシンに接続できた。
4. Vagrant の利点
機能 | 説明 |
---|---|
環境を簡単に再現 |
Vagrantfile を共有すれば、全員が同じ環境を再現可能 |
仮想マシンのスナップショット管理 |
vagrant snapshot save で状態を保存し、restore で戻せる |
ネットワーク設定が柔軟 |
config.vm.network でポートフォワーディングやIP指定が可能 |
クラウド環境のテスト | AWS/GCPのローカル版を作れる |
Dockerとの連携 |
vagrant up でDockerコンテナを含めた仮想環境を立ち上げ可能 |
5. Vagrant を CI/CD・クラウド学習に活用する
Vagrantを使うと クラウドを使わずにローカルでAWS/GCPのような環境をエミュレート できます。
例えば:
1. Terraform + Vagrant
vagrant up # Ubuntu環境を作成
terraform apply # Terraformで仮想マシンのプロビジョニング
メリット: AWS/GCPにデプロイする前にローカルでテスト可能
2. CI/CD(Jenkins)+ Vagrant
vagrant up
vagrant ssh -c "sudo apt install -y jenkins"
メリット: ローカルでクラウドを使わずにCI/CDを実験できる
続いてpythonで簡単なプログラムを作って、CI/CDパイプラインを構築していきます。
6. Python アプリケーションの作成と VM への展開
1. まずはローカルで Python アプリケーションを作成
まず、ホスト PC 上で簡単な Python アプリケーションを作成します。
# vagrant-test ディレクトリ内に app ディレクトリを作成
mkdir app
cd app
VSCodeを立ち上げます。
# Hello World アプリケーションを作成
def hello():
return "Hello, World!"
if __name__ == "__main__":
print(hello())
簡単な例ですが、動作確認しておきましょう。
テストもしておきます。pytestをインストールしましょう。
pip install pytest
# シンプルなテストを作成
import unittest
from app import hello
class TestHello(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello(), "Hello, World!")
if __name__ == "__main__":
unittest.main()
テストも通過しましたね。
# requirements.txt を作成
pytest==8.3.5
2. Vagrantfile を編集して共有フォルダを設定
Vagrantfile を編集して、作成したアプリケーションが VM 上で利用できるように設定します。
筆者の場合は
user/vagrant-test/Vagrantfile にファイルがあります。
共有フォルダでプロビジョニングのための設定を加えます。
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
# ポート転送設定(必要に応じて)
config.vm.network "forwarded_port", guest: 5000, host: 5000
# 共有フォルダ設定
config.vm.synced_folder "./app", "/home/vagrant/app"
# Python と必要なツールをインストールするプロビジョニング
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python3 python3-pip python3-venv git
# 仮想環境のセットアップ
cd /home/vagrant/app
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
SHELL
end
プロビジョニングとは
プロビジョニングとは
Vagrantにおけるプロビジョニングとは、仮想マシンが起動した後に自動的に実行される環境構築の処理です。今回の記事では、config.vm.provision "shell", inline: <<-SHELL ... SHELL
の部分がこれにあたります。
プロビジョニングの利点は、手動での環境構築作業を自動化できる点です。JavaやPython、Jenkinsなどのインストール、設定ファイルの作成、権限の調整など、通常なら手作業で行う操作をスクリプト化することで、再現性の高い環境を簡単に構築できます。
これにより、「特定の人しか構築できない環境」ではなく、「誰でも同じ手順で作れる環境」が実現します。開発チームでの環境統一や、新メンバーのオンボーディング時間短縮にも大きく貢献するため、Infrastructure as Codeの重要な要素の一つと言えるでしょう。
3. VM の再起動とプロビジョニングの実行
変更した Vagrantfile を適用します。
# vagrant-test ディレクトリに戻る
cd ..
# VM を再起動してプロビジョニングを実行
vagrant reload --provision
結構時間がかかります。
4. VM 上でアプリケーションを実行
vagrant ssh
cd ~/app
ls
python3 app.py # "Hello, World!" と表示されるはず
pytest test_app.py # テストが通るはず
exit
動作に問題はなさそうですね。
VM上でpythonが実行できた。
7. CI/CD パイプラインの構築(Git編)
1. Git リポジトリの初期化(option)
✅今回は簡略化のために下記のパイプライン構築の時点ではgitの設定は外しています。
しかし、本来であればgitでコード管理する場合が多いため、必要な人はセットアップしておいてください。
不要な方はスキップできます。
cd app
git init
__pycache__/
*.py[cod]
*$py.class
venv/
.pytest_cache/
pytest-cache-files-9ruznpyk/
git add .
git commit -m "Initial commit with Hello World app"
2. GitLab CI 設定ファイルの作成
stages:
- test
- deploy
test:
stage: test
image: python:3.9
script:
- pip install -r requirements.txt
- pytest test_app.py
only:
- main
deploy:
stage: deploy
image: python:3.9
script:
- echo "Deploying application..."
- mkdir -p ~/.ssh
- echo "\$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -H \$DEPLOY_SERVER_IP >> ~/.ssh/known_hosts
- scp -r app.py requirements.txt \$DEPLOY_USER@\$DEPLOY_SERVER_IP:/home/\$DEPLOY_USER/app/
- ssh \$DEPLOY_USER@\$DEPLOY_SERVER_IP "cd /home/\$DEPLOY_USER/app && python3 -m venv venv && . venv/bin/activate && pip install -r requirements.txt && python app.py"
only:
- main
git add .gitlab-ci.yml
git commit -m "Add GitLab CI configuration"
8. CI/CD パイプラインの構築(Jenkins編)
1. VM 上に簡易 CI/CD 環境を構築 (Jenkins を使用)
Vagrantfile を更新してJenkinsをインストールします。
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
# ポート転送設定
config.vm.network "forwarded_port", guest: 5000, host: 5000
config.vm.network "forwarded_port", guest: 8080, host: 8080 # Jenkins用
# 共有フォルダ設定
config.vm.synced_folder "./app", "/home/vagrant/app"
# Python と必要なツールをインストールするプロビジョニング
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python3 python3-pip python3-venv git
# Jenkins のインストール
apt-get install -y openjdk-11-jdk
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | apt-key add -
sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
apt-get update
apt-get install -y jenkins
systemctl start jenkins
systemctl enable jenkins
# 初期パスワードを表示
echo "Jenkins initial admin password:"
cat /var/lib/jenkins/secrets/initialAdminPassword
# Python 環境のセットアップ
cd /home/vagrant/app
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
SHELL
end
2. Vagrantfileを更新して適用
#appにいる場合は
cd ..
vagrant reload --provision
ちゃんと完了しましたね。
3. Jenkins の設定
- ブラウザで
http://localhost:8080
にアクセス
# 既存のリポジトリ設定を削除
sudo rm /etc/apt/sources.list.d/jenkins.list
sudo rm /usr/share/keyrings/jenkins-keyring.gpg 2>/dev/null || true
# 新しい方法でキーを追加
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins.io.key > /dev/null
echo "deb [signed-by=/usr/share/keyrings/jenkins.io.key] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
# パッケージリストを更新
sudo apt update
# Jenkinsをインストール
sudo apt install -y jenkins
うまくいったと思ったらJenkisがこけています。
vagrant sshでVMに繋がった状態なので、ログを見てみます。
期待するJavaのバージョンと違ったみたいですね。
~
~
#中略
Mar 15 01:35:37 ubuntu-focal jenkins[7364]: Running with Java 11 from /usr/lib/jvm/java-11-openjdk-amd64, which is older than the minimum required version (Java 17).
Mar 15 01:35:37 ubuntu-focal jenkins[7364]: Supported Java versions are: [17, 21]
Javaを入れなおしてみます。
# Java 17をインストール
sudo apt update
sudo apt install -y openjdk-17-jdk
# Jenkinsが使用するJavaバージョンを設定
sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java
# Jenkinsを再起動
sudo systemctl restart jenkins
今度はちゃんとlocalhost:8000でアクセス出来ていますね!
3. 表示されたJenkinsの初期パスワードを入力(VM内の /var/lib/jenkins/secrets/initialAdminPassword
にあります)
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
4. 推奨プラグインをインストール
しばらく待ちます。
5. 管理者アカウントを作成
※プラグインインストールが終わったら勝手に遷移していました。
6. Jenkinsインスタンスを作成します。
これでJenkinsが使えるようになりました
7. 新しいパイプラインジョブを作成
- 「新規ジョブ作成」→「パイプライン」を選択
- 以下のようなパイプラインスクリプトを設定:
pipeline {
agent any
stages {
stage('Setup') {
steps {
sh 'cp -r /home/vagrant/app/* .'
}
}
stage('Install') {
steps {
sh 'python3 -m venv venv || true'
sh '. venv/bin/activate && pip install -r requirements.txt'
}
}
stage('Test') {
steps {
sh '. venv/bin/activate && pytest test_app.py'
}
}
stage('Deploy') {
steps {
sh 'mkdir -p /home/vagrant/deploy'
sh 'cp app.py requirements.txt /home/vagrant/deploy/'
sh 'cd /home/vagrant/deploy && python3 -m venv venv || true'
sh 'cd /home/vagrant/deploy && . venv/bin/activate && pip install -r requirements.txt'
sh 'cd /home/vagrant/deploy && . venv/bin/activate && python app.py'
}
}
}
}
Jenkins-pipelineの構造
Jenkins-pipelineの構造は意外とシンプルです。
stage('Setup'), stage('Install') のようにstageというsteps {}にまとめたコマンドをさらにまとめて、sategeに分割して実行します。
dockerfileでcpで依存関係をコピーしたり、pip installするのに似ていますね。
Configure→パイプラインをクリックして、上記のコードを貼り付け、Saveを押します。
パイプラインの作成が完了しました。
ビルド実行をクリックしてしばらく待ちます。
失敗してしまいましたね。
ビルドに失敗したので、実行に必要なJavaインストール、各権限を付与->パイプラインをビルドします。
-
権限の問題
# Jenkinsユーザーに必要なディレクトリへの権限を付与 sudo chown -R jenkins:jenkins /home/vagrant/app sudo mkdir -p /home/vagrant/deploy sudo chown -R jenkins:jenkins /home/vagrant/deploy
-
Pythonやpipの問題
# JenkinsユーザーがPythonとpipを使えるようにする sudo -u jenkins python3 --version sudo -u jenkins pip3 --version
これらの設定が完了したら、Jenkinsパイプラインを再度実行してみてください。
また、app.pyやtest_app.pyなどのファイルが確実に存在することも確認しておくと良いでしょう:
ls -la /home/vagrant/app
9. 最終的なVagrantfile
今回実施した内容を反映したvagrantfileを載せておきます。
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
# ポート転送設定
config.vm.network "forwarded_port", guest: 5000, host: 5000 # Pythonアプリ用
config.vm.network "forwarded_port", guest: 8080, host: 8080 # Jenkins用
# 共有フォルダ設定
config.vm.synced_folder "./app", "/home/vagrant/app"
# プロビジョニングスクリプト
config.vm.provision "shell", inline: <<-SHELL
# システムの更新
apt-get update
apt-get upgrade -y
# 必要なパッケージをインストール
apt-get install -y git curl wget
# Python環境のセットアップ
apt-get install -y python3 python3-pip python3-venv
# Java 17のインストール
apt-get install -y software-properties-common
add-apt-repository -y ppa:openjdk-r/ppa
apt-get update
apt-get install -y openjdk-17-jdk
update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java
# Jenkinsのインストール
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | tee /usr/share/keyrings/jenkins.io.key > /dev/null
echo "deb [signed-by=/usr/share/keyrings/jenkins.io.key] https://pkg.jenkins.io/debian-stable binary/" | tee /etc/apt/sources.list.d/jenkins.list > /dev/null
apt-get update
apt-get install -y jenkins
systemctl start jenkins
systemctl enable jenkins
# Pythonアプリの初期セットアップ
mkdir -p /home/vagrant/app
cd /home/vagrant/app
# アプリケーションフォルダが空の場合、サンプルアプリを作成
if [ ! -f app.py ]; then
echo 'def hello():
return "Hello, World!"
if __name__ == "__main__":
print(hello())' > app.py
echo 'import unittest
from app import hello
class TestHello(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello(), "Hello, World!")
if __name__ == "__main__":
unittest.main()' > test_app.py
echo 'pytest==7.4.0' > requirements.txt
fi
# Python仮想環境のセットアップ
python3 -m venv venv || true
. venv/bin/activate
pip install -r requirements.txt
# デプロイ用ディレクトリの作成
mkdir -p /home/vagrant/deploy
# Jenkins用の権限設定
chown -R jenkins:jenkins /home/vagrant/app
chown -R jenkins:jenkins /home/vagrant/deploy
# Jenkins内でpythonコマンドを実行できるようにするための設定
usermod -a -G vagrant jenkins
chmod 755 /home/vagrant
# Jenkinsユーザーが一時ディレクトリを作成できるようにする
mkdir -p /var/lib/jenkins/workspace
chown -R jenkins:jenkins /var/lib/jenkins/workspace
# Jenkins初期パスワードを表示
echo "Jenkins initial admin password:"
cat /var/lib/jenkins/secrets/initialAdminPassword
SHELL
end
これで、ローカル PC で Python アプリを作成し、Vagrant で仮想環境を構築し、その中で CI/CD パイプラインを構築するところまでの流れが完成します。
このフローのポイント:
- アプリケーションとテストコードはホストマシンで作成
- 共有フォルダを通じて VM に同期
- VM 上で Jenkins を使って CI/CD を実行
- すべてがオフラインで完結するため、外部サービスに依存せず実験可能
これを「自分だけの実験場」として活用することで、クラウドと同様の CI/CD の概念を学べます。また、この基盤をベースに、次のステップでよりリッチなアプリケーションや複雑な環境へと発展させることができます。
10. さいごに
Jenkinsのパイプラインは、確かに見た目は複雑に見えますが、本質的には「実行したい一連のコマンドをステージごとに整理して順番に実行する」だけのものです。
簡単に言うと:
- ステージ(stage): 「Checkout」「Build」「Test」「Deploy」など、論理的な作業単位
- ステップ(steps): 各ステージ内で実行する具体的なコマンド(主にシェルコマンド)
例えば、手動でやるなら:
# チェックアウト
git clone リポジトリURL
# インストール
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# テスト
pytest test_app.py
# デプロイ
mkdir -p deploy
cp app.py requirements.txt deploy/
cd deploy
python app.py
これをJenkinsパイプラインで表現すると、単にこれらのコマンドを整理して記述しているだけです。CI/CDツールの多くは、このような単純な考え方をベースにしています。
11. まとめ
本記事では、クラウドに頼らずにVagrantとJenkinsを使って独自の実験環境を構築する方法を紹介しました。この「自分だけの実験場」の強みは、
✅コストがかからない
✅ネットワーク環境に依存しない
✅何度でも失敗と再構築を繰り返せる
などの点にあります。
CI/CDパイプラインの本質は「一連のコマンドをステージごとに整理して順番に実行する」というシンプルな考え方です。この基本を理解すれば、GitHub ActionsやGitLab CIなど他のツールにも応用できます。
今回構築した環境は入門レベルですが、さらにコンテナ化、Kubernetes、複雑なアプリケーションへと発展させることも可能です。まずは小さく始めて、徐々に複雑な環境へと挑戦していくことで、クラウドネイティブな技術スタックを効率よく学べるでしょう。
またこのような記事が読みたい方は、
✓評価
✓保存
✓フォロー
をよろしくお願いします!
皆様のコメント💬が励みになります。
何か聞きたいこと/ツッコミ、なんでもOKです。
また、Xでも技術の話をつぶやいているので、フォローよろしくお願いします。
それはまた、次回の記事でお会いできるのを楽しみにしております。
ではまた!!
Discussion