2026.01.20

Ansible × GitLab CI/CDで実現するIaC パイプライン構築ガイド

野町 篤志
株式会社エーピーコミュニケーションズ iTOC事業部 ビジネスディベロップメント部 Automation Collabo Team
このエントリーをはてなブックマークに追加

1. なぜ今、Ansible × GitLab CI/CDなのか

1-1. インフラ自動化の進化と課題

「手動でサーバー設定するのはもう限界...」そう感じたことはありませんか?

サーバーが数台ならまだしも、十数台、数十台となってくると、手動での構築・設定は時間がかかるだけでなく、設定ミスのリスクも高まります。さらに、誰がいつどんな設定をしたのか追跡するのも一苦労です。

そこで登場するのがInfrastructure as Code (IaC)です。インフラの構成をコードで管理することで、以下のようなメリットが得られます。

  • 再現性の担保: 同じコードを実行すれば、同じ環境が構築可能
  • 変更履歴の追跡: Gitで管理すれば、誰がいつ何を変更したか一目瞭然
  • レビュープロセスの導入: コードレビューでインフラ変更の品質を向上
  • 自動化による効率化: 手作業を減らし、ヒューマンエラーを防止

ただし、IaCツールを導入しただけでは不十分です。「いつ、どのタイミングで実行するのか」「誰が承認するのか」といった運用フローまで考える必要があります。

1-2. Ansibleの強み

IaCツールは数多く存在しますが、その中でもAnsibleが人気な理由はシンプルさにあります。

Ansibleの主な特徴

  • エージェントレス: 対象サーバーに専用エージェントをインストール不要。SSH接続さえできればOK
  • YAML形式: 人間が読みやすいYAML形式で記述可能
  • 豊富なモジュール: パッケージ管理、ファイル操作、サービス管理など、標準で多くの機能を提供
  • 冪等性: 何度実行しても同じ結果になる(既に設定済みなら変更しない)

例えば、Nginxをインストールして起動するPlaybookは以下の通りです。

- name: Install and start Nginx
  hosts: webservers
  become: yes
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present
    
    - name: Start Nginx service
      service:
        name: nginx
        state: started
        enabled: yes

ご覧の通り、何をしているのか直感的に理解できますよね。

1-3. GitLab CI/CDとの相乗効果

Ansibleでインフラをコード化したら、次は「どう運用するか」です。ここでGitLab CI/CDが力を発揮します。

GitLab CI/CDを使うメリット

  • 自動実行: コードをpushするだけでパイプラインが自動起動
  • 環境分離: 開発・ステージング・本番環境ごとにパイプラインを定義可能
  • 承認フロー: 本番環境への適用前に手動承認を挟める
  • 実行履歴: いつ誰がどのコードを実行したか、すべて記録される

つまり、Ansibleで「何をするか」を定義し、GitLab CI/CDで「いつ、どう実行するか」を制御するというわけです。

この組み合わせにより、インフラ変更が「コードのpush → 自動テスト → レビュー → 承認 → 本番適用」という開発者にとって馴染みのあるフローで管理できるようになります。

2. Ansible × GitLab 連携の基本的な仕組み

2-1. パイプライン実行フロー

まず、全体の流れを理解しましょう。Ansible × GitLab CI/CDの典型的なフローは以下のようになります。

1. 開発者がPlaybookを編集・コミット
   ↓
2. GitLabにpush
   ↓
3. GitLab CI/CDがパイプラインを自動起動
   ↓
4. GitLab Runnerが.gitlab-ci.ymlを読み込む
   ↓
5. Runnerがansible-playbookコマンドを実行
   ↓
6. Ansibleが対象サーバーに接続して設定を適用
   ↓
7. 結果をGitLabのパイプライン画面で確認

このフローの中で重要なのがGitLab Runnerです。Runnerは実際にジョブを実行するワーカーで、Ansibleがインストールされた環境を用意する必要があります。

Runnerの実行環境として一般的な選択肢

  • Docker Executor: Dockerコンテナ内でジョブを実行(軽量で使いやすい)
  • Shell Executor: Runner自体のシェル環境で直接実行(シンプル)
  • Kubernetes Executor: Kubernetesクラスタ上で実行(スケーラブル)

初めての場合は、Docker Executorを使うのがおすすめです。Ansibleがプリインストールされたイメージを使えば、環境構築が簡単です。

2-2. GitLab CI/CD YAML定義

GitLab CI/CDでは、.gitlab-ci.ymlファイルでパイプラインを定義します。以下は基本的な構成です。

stages:
  - validate
  - deploy

# Ansibleが入ったDockerイメージを使用
image: willhallonline/ansible:latest

# Playbookの文法チェック
validate:
  stage: validate
  script:
    - ansible-playbook --syntax-check playbook.yml
  only:
    - branches

# 開発環境へのデプロイ
deploy_dev:
  stage: deploy
  script:
    - ansible-playbook -i inventory/dev playbook.yml
  only:
    - develop
  environment:
    name: development

# 本番環境へのデプロイ(手動承認必要)
deploy_prod:
  stage: deploy
  script:
    - ansible-playbook -i inventory/prod playbook.yml
  only:
    - main
  when: manual
  environment:
    name: production

ポイント解説

  • stages: パイプラインのステージを定義。上から順に実行される
  • image: 使用するDockerイメージを指定
  • script: 実際に実行するコマンド
  • only: どのブランチで実行するかを制限
  • when: manual: 手動トリガーが必要(本番環境で重要)
  • environment: デプロイ先の環境名(GitLabの環境管理機能と連携)

これにより、developブランチへのpushは自動的に開発環境に反映され、mainブランチへのマージは手動承認後に本番環境に反映されるという運用が実現できます。

2-3. Ansible Playbookの管理戦略

Playbookをどう管理するかは、プロジェクトの規模によって変わってきます。

小規模プロジェクト(サーバー数台程度)

project/
├── .gitlab-ci.yml
├── inventory
│   ├── dev
│   └── prod
├── playbook.yml
└── roles/
    └── nginx/
        ├── tasks/
        └── templates/

シンプルな構成で十分です。Playbookは1つか数個にまとめます。

中〜大規模プロジェクト(複数サービス、多数のサーバー)

project/
├── .gitlab-ci.yml
├── inventories/
│   ├── dev/
│   │   ├── hosts
│   │   └── group_vars/
│   └── prod/
│       ├── hosts
│       └── group_vars/
├── playbooks/
│   ├── webserver.yml
│   ├── database.yml
│   └── monitoring.yml
└── roles/
    ├── common/
    ├── nginx/
    ├── mysql/
    └── prometheus/

役割ごとにPlaybookを分割し、rolesで再利用可能なコンポーネント化を図ります。

管理のコツ

  • 環境変数は分離: group_varshost_varsで環境ごとの差分を管理
  • 機密情報はAnsible Vault: パスワードなどはVaultで暗号化
  • 冪等性を意識: 何度実行しても安全なPlaybookを書く
  • 小さく始める: 最初から完璧を目指さず、段階的に改善していく

3. 実装

それでは実際に手を動かしてみましょう。ここでは、テストサーバーへのNginxインストールを自動化する例を通じて、基本的な実装の流れを見ていきます。

3-1. 環境構築

前提条件

  • GitLabのアカウントとプロジェクトがある
  • GitLab Runnerが登録済み(DockerまたはShell Executor)
  • 対象サーバーにSSH接続できる

Step 1: GitLab Runnerのセットアップ

まだRunnerを登録していない場合は、以下の手順で登録します。

# Runnerのインストール(Ubuntu/Debianの例)
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get install gitlab-runner

# Runnerの登録
sudo gitlab-runner register

登録時に聞かれる内容

  • GitLab URL: https://gitlab.com/ または自社GitLabのURL
  • Registration token: GitLabプロジェクトの Settings > CI/CD > Runners から取得
  • Executor: docker を選択
  • Default Docker image: willhallonline/ansible:latest

Step 2: プロジェクトのディレクトリ構成

mkdir ansible-nginx-demo
cd ansible-nginx-demo
git init

以下のファイル構成を作成します。

ansible-nginx-demo/
├── .gitlab-ci.yml
├── inventory
│   └── hosts
├── playbook.yml
└── README.md

3-2. シンプルな実装例

Step 3: インベントリファイルの作成

inventory/hosts ファイルを作成

[webservers]
web1 ansible_host=192.168.1.10 ansible_user=ubuntu
web2 ansible_host=192.168.1.11 ansible_user=ubuntu

[webservers:vars]
ansible_python_interpreter=/usr/bin/python3

対象サーバーのIPアドレスとユーザー名を実際の環境に合わせて変更してください。

Step 4: Playbookの作成

playbook.yml ファイルを作成

---
- name: Install and configure Nginx
  hosts: webservers
  become: yes
  
  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600
    
    - name: Install Nginx
      apt:
        name: nginx
        state: present
    
    - name: Ensure Nginx is started and enabled
      service:
        name: nginx
        state: started
        enabled: yes
    
    - name: Create custom index.html
      copy:
        content: |
          <html>
          <head><title>Deployed by Ansible + GitLab CI/CD</title></head>
          <body>
            <h1>Hello from {{ inventory_hostname }}!</h1>
            <p>This server was configured automatically.</p>
          </body>
          </html>
        dest: /var/www/html/index.html
        owner: www-data
        group: www-data
        mode: '0644'
    
    - name: Allow HTTP traffic through firewall
      ufw:
        rule: allow
        port: '80'
        proto: tcp
      when: ansible_facts['os_family'] == "Debian"

このPlaybookは以下を実行します。

  1. aptキャッシュを更新
  2. Nginxをインストール
  3. Nginxサービスを起動し、自動起動を有効化
  4. カスタムindex.htmlを配置
  5. ファイアウォールでHTTP通信を許可

Step 5: GitLab CI/CD定義の作成

.gitlab-ci.yml ファイルを作成

image: willhallonline/ansible:latest

stages:
  - validate
  - deploy

before_script:
  # SSH秘密鍵の設定
  - mkdir -p ~/.ssh
  - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
  - chmod 600 ~/.ssh/id_rsa
  - ssh-keyscan -H $TARGET_HOST >> ~/.ssh/known_hosts

# 文法チェック
syntax-check:
  stage: validate
  script:
    - ansible-playbook --syntax-check playbook.yml
  only:
    - branches

# Dry run(実際には変更を適用しない)
dry-run:
  stage: validate
  script:
    - ansible-playbook -i inventory/hosts playbook.yml --check
  only:
    - merge_requests
  allow_failure: true

# デプロイ実行
deploy:
  stage: deploy
  script:
    - ansible-playbook -i inventory/hosts playbook.yml
  only:
    - main
  environment:
    name: production
  when: manual

Step 6: 実行と検証

まず、ローカル環境で文法チェックをしてみましょう。

ansible-playbook --syntax-check playbook.yml

問題なければ、GitLabにpushします。

git add .
git commit -m "Initial commit: Nginx deployment with Ansible"
git remote add origin <your-gitlab-project-url>
git push -u origin main

GitLabのCI/CD > Pipelinesページを開くと、パイプラインが実行されているのが確認できます。

  • syntax-checkジョブが自動実行される
  • deployジョブは手動実行("Play"ボタンをクリック)

デプロイが成功したら、ブラウザで対象サーバーのIPアドレスにアクセスして、カスタムページが表示されることを確認しましょう!

3-3. 認証情報管理

最後に、重要なセキュリティ対策について。SSH秘密鍵やパスワードなどの機密情報は、絶対にコードにハードコードしてはいけません。

Step 7: GitLab CI/CD変数の設定

GitLabプロジェクトの Settings > CI/CD > Variables で以下の変数を登録

SSH_PRIVATE_KEY

  • Type: File
  • Value: 対象サーバーにアクセスできる秘密鍵の内容をペースト
  • Protect variable: ✓
  • Mask variable: ✓

TARGET_HOST

  • Type: Variable
  • Value: 対象サーバーのIPアドレスまたはホスト名
  • Protect variable: ✓
  • Mask variable: ✓

その他の機密情報の管理方法

  1. Ansible Vault - Playbook内の機密情報を暗号化
# vault用のパスワードファイルを作成
echo "my-vault-password" > vault_password.txt
chmod 600 vault_password.txt

# 機密情報を暗号化
ansible-vault encrypt_string 'db_password_here' --name 'db_password'

GitLab CI/CD変数にANSIBLE_VAULT_PASSWORDを登録し、パイプラインで使用

script:
  - echo "$ANSIBLE_VAULT_PASSWORD" > vault_pass.txt
  - ansible-playbook -i inventory/hosts playbook.yml --vault-password-file vault_pass.txt
  1. HashiCorp Vault統合 - より本格的なシークレット管理

AnsibleのHashiCorp Vaultプラグインを使えば、実行時に動的にシークレットを取得できます。

セキュリティのベストプラクティス

  • ✅ SSH鍵は必ずGitLab CI/CD変数で管理
  • ✅ 本番環境の変数は"Protect variable"に設定(protectedブランチのみ利用可能)
  • ✅ パスワードやトークンは"Mask variable"に設定(ログに表示されない)
  • ✅ 定期的に認証情報をローテーション
  • ❌ コードに機密情報を直接書かない
  • ❌ パブリックリポジトリに機密情報を含めない

まとめ

Ansible × GitLab CI/CDの組み合わせにより、インフラの変更が以下のような開発者フレンドリーなワークフローで管理できるようになりました。

  1. コードで管理: インフラ構成をYAMLで記述
  2. バージョン管理: Gitで変更履歴を追跡
  3. 自動化: Push後に自動テスト・デプロイ
  4. レビュー: Merge Requestで変更内容を確認
  5. 安全性: 本番適用前に手動承認を挟める

最初は小さく始めて、徐々に適用範囲を広げていくのがおすすめです。まずは単純なサーバー設定から自動化し、慣れてきたら複雑なオーケストレーションにも挑戦してみてください。

Infrastructure as Codeの世界へようこそ!

この記事の著者:野町 篤志

株式会社エーピーコミュニケーションズ iTOC事業部 ビジネスディベロップメント部 Automation Collabo Team

こんにちは。株式会社エーピーコミュニケーションズの野町です。
普段はNWやサーバー等の自動化業務を担当しています。
もし自動化に興味があれば以下のURLからお問い合わせください!
https://www.ap-com.co.jp/network-automation/


DevOps Hubのアカウントをフォローして
更新情報を受け取る

  • Like on Feedly
    follow us in feedly

関連記事

このエントリーをはてなブックマークに追加

お問い合わせ

DevOpsに関することなら
お気軽にご相談ください。

Facebook、TwitterでDevOpsに関する
情報配信を行っています。