キーワードで検索

今日を知り、明日を変えるシステム運用メディア

Ansible Vaultで機密情報を暗号化、Playbookで活用する方法 | DBやAWSキーを安全に管理

Ansible Vaultで機密情報を暗号化、Playbookで活用する方法 | DBやAWSキーを安全に管理

ITシステムを運用する中で、データベース接続情報やAWSキーなどの機密情報を管理することは重要です。しかし、これらを誤って公開してしまうと、セキュリティリスクが発生します。

本記事では、Red Hatが開発したオープンソースのIT自動化ツール「Ansible(アンシブル)」に組み込まれた暗号化機能「Ansible Vault」を使って機密情報を暗号化し、Playbookでセキュアに活用する方法を詳しく解説します。

Ansible Vaultとは?

Ansible Vaultは、Playbook内で使用する変数やファイルを暗号化して安全に管理するための機能です。通常、Playbookではデータベース接続情報やAPIキーなどの情報を利用しますが、それをそのままの形で記載すると、誰でも簡単に見られてしまい、セキュリティ上のリスクが高くなります。

Ansible Vaultを活用すると、これらの機密情報をAES256で暗号化でき、暗号化された状態のまま利用できるため、Gitリポジトリやチームでの共有時にも安全です。また、暗号化や復号化だけでなく、暗号化されたファイルの編集やパスワード変更も可能です。

Ansible Vaultの基本コマンドを解説

Ansible Vaultを利用すると、Ansibleで利用する機密情報(パスワード、APIキー、データベース接続情報など)を安全に管理できます。Ansible Vaultの基本的な5つのコマンドについて解説します。

ファイルの暗号化

機密情報を含むファイルを暗号化するには、次のコマンドを使用します。

ansible-vault encrypt secrets.yml
  1. 暗号化したいファイル(例: secrets.yml)を作成します。

secrets.yml

secret_key: “my_secret_password”
db_password: “mypassword123”
  1. ansible-vault encrypt コマンドを実行します。
  2. パスワード入力を求められるため、設定します。復号時にも同じパスワードを使用します。
  3. 暗号化が成功すると、以下のようにファイルの中身が見えなくなります。

暗号化後のファイルの中身

$ANSIBLE_VAULT;1.1;AES256
6139656639393064623563643461316533346539316666656439383438373962…

暗号化されたファイルの復号化

ansible-vault decrypt secrets.yml
  1. ansible-vault decrypt <ファイル名> を実行します。
  2. 暗号化時に設定したパスワードを入力します。
  3. 正しいパスワードを入力すると、元の平文に戻ります。

暗号化ファイルの編集

ansible-vault edit secrets.yml
  1. コマンドを実行すると、ファイルが復号され、エディタが開きます。
  2. 編集後に保存して閉じると、自動で再暗号化されます。

 Vault(暗号化ファイル)のパスワードを変更

暗号化ファイルのパスワードを変更 するには、次のコマンドを使用します。

ansible-vault rekey secrets.yml
  1. コマンドを実行すると、現在のVaultパスワードを入力 するよう求められます。
  2. 続いて、新しいパスワードを設定します。
  3. 成功すると、新しいパスワードでのみ復号化できるようになります。

複数ファイルをまとめて暗号化・復号化

ディレクトリ内の全ファイルを暗号化

find ./secrets -type f -exec ansible-vault encrypt {} \;

複数ファイルを一括復号化

find ./secrets -type f -exec ansible-vault decrypt {} \;

ディレクトリ内の複数ファイルをまとめて暗号化する場合、find と組み合わせて実行できます。これにより、環境ごとに異なる暗号化ファイルの管理や、暗号化したいファイルが増えた際の手間を削減できます。

【実践】Playbookで暗号化ファイルを使用する

Ansible Vaultを使用してデータベース接続情報やAWSキーを安全に管理するに、まずは、Ansibleが使用できる状態にする必要があります。

検証環境の構築

TerraformでAWS環境をセットアップし、Ansible Vaultを活用できる準備を整えます。

ディレクトリ構造

OpsToday-Ansible-Vault/         # Terraform設定ファイル(AWS環境の構築)
  ├─ main.tf                  # メインのTerraformコード
  ├─ outputs.tf               # 出力情報(EC2のIPアドレスなど)
  ├─ userdata_controller.sh   # コントロールノードの初期設定スクリプト
  ├─ userdata_db.sh           # ターゲットノード(DBサーバー)の初期設定スクリプト

Terraformを使い、以下のコードでAWS環境を自動構築します。

main.tf

# AWSプロバイダーの設定
provider “aws” {
  region = “ap-northeast-1” # 東京リージョン
}

# IAMユーザーの作成(AWSキー用)
resource “aws_iam_user” “ansible_user” {
  name = “ansible-user”
}

# IAMユーザーのアクセスキー作成
resource “aws_iam_access_key” “ansible_user_key” {
  user = aws_iam_user.ansible_user.name
}

# VPCの作成
resource “aws_vpc” “main” {
  cidr_block = “10.0.0.0/16”
  tags = { Name = “main-vpc” }
}

# サブネットの作成
resource “aws_subnet” “main” {
  vpc_id     = aws_vpc.main.id
  cidr_block = “10.0.1.0/24”
}

# インターネットゲートウェイの作成
resource “aws_internet_gateway” “main” {
  vpc_id = aws_vpc.main.id
}

# ルートテーブルの作成
resource “aws_route_table” “main” {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = “0.0.0.0/0”
    gateway_id = aws_internet_gateway.main.id
  }
}

# ルートテーブルをサブネットに関連付け
resource “aws_route_table_association” “main” {
  subnet_id      = aws_subnet.main.id
  route_table_id = aws_route_table.main.id
}

# **コントロールノード用のセキュリティグループ**
resource “aws_security_group” “controller_sg” {
  vpc_id = aws_vpc.main.id

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = “tcp”
    cidr_blocks = [“0.0.0.0/0”] # SSH許可(本番では制限推奨)
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = “-1”
    cidr_blocks = [“0.0.0.0/0”] # 全通信許可
  }

  tags = { Name = “controller-sg” }
}

# **データベース用のセキュリティグループ**
resource “aws_security_group” “db_sg” {
  vpc_id = aws_vpc.main.id

  # コントロールノード(controller_sg)からの MySQL アクセスを許可
  ingress {
    from_port   = 3306
    to_port     = 3306
    protocol    = “tcp”
    security_groups = [aws_security_group.controller_sg.id]
  }

  # コントロールノード(controller_sg)からの SSH アクセスを許可  ingress {    from_port   = 22    to_port     = 22    protocol    = “tcp”    security_groups = [aws_security_group.controller_sg.id]  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = “-1”
    cidr_blocks = [“0.0.0.0/0”] # 全通信許可
  }

  tags = { Name = “db-sg” }
}

# SSHキーペアの作成
resource “aws_key_pair” “default” {
  key_name   = “my-key”
  public_key = file(“~/.ssh/id_rsa.pub”)
}

# **EC2(コントロールノード)の作成**
resource “aws_instance” “controller” {
  ami           = “ami-075cc63e37ba74823”
  instance_type = “t2.micro”
  key_name      = aws_key_pair.default.key_name
  subnet_id     = aws_subnet.main.id
  vpc_security_group_ids = [aws_security_group.controller_sg.id]

  associate_public_ip_address = true
  user_data = file(“userdata_controller.sh”)

  tags = { Name = “controller-node” }
}

# **EC2(ターゲットノード / DBサーバー)の作成**
resource “aws_instance” “target” {
  ami           = “ami-075cc63e37ba74823”
  instance_type = “t2.micro”
  key_name      = aws_key_pair.default.key_name
  subnet_id     = aws_subnet.main.id
  vpc_security_group_ids = [aws_security_group.db_sg.id]

  associate_public_ip_address = true
  user_data = file(“userdata_db.sh”)

  tags = { Name = “target-node” }
}

# **出力変数**
output “controller_ip” {
  value = aws_instance.controller.public_ip
}

output “target_ip” {
  value = aws_instance.target.private_ip
}

output “aws_access_key” {
  value     = aws_iam_access_key.ansible_user_key.id
  sensitive = true
}

output “aws_secret_key” {
  value     = aws_iam_access_key.ansible_user_key.secret
  sensitive = true
}

userdata_controller.sh

#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras enable ansible2
sudo yum install -y ansible mysql

userdata_db.sh

#!/bin/bash
# MySQL (MariaDB) をインストール
sudo yum clean metadata
sudo yum install -y mariadb-server

# MariaDB  を起動
sudo systemctl enable mariadb
sudo systemctl start mariadb

# MySQL 初期設定
sudo mysql -e “CREATE DATABASE my_database;”
sudo mysql -e “CREATE USER ‘admin’@’%’ IDENTIFIED BY ‘SuperSecretPass’;”
sudo mysql -e “GRANT ALL PRIVILEGES ON my_database.* TO ‘admin’@’%’;”
sudo mysql -e “FLUSH PRIVILEGES;”

# MySQL を外部接続可能に
if grep -q “^bind-address” /etc/my.cnf; then
    sudo sed -i ‘s/^bind-address/#bind-address/’ /etc/my.cnf
    sudo systemctl restart mariadb
fi

Terraform実行後に得られる出力情報(例)

コントロールノードからターゲットノードへの自動構築準備

以下のコマンドでコントロールノードにSSH接続します。

ssh -i ~/.ssh/id_rsa ec2-user@<コントロールノードのパブリックIP>

ターゲットノードにSSH接続を可能にするため、秘密鍵を転送します。

scp -i ~/.ssh/id_rsa ~/.ssh/id_rsa ec2-user@<コントロールノードのパブリックIP>:~/.ssh/id_rsa

転送後に秘密鍵の権限を変更します。

chmod 600 ~/.ssh/id_rsa

以上でコントロールノードからターゲットノードに対してSSH接続が可能になります。

インベントリファイルの作成

ターゲットノードを管理するため、コントロールノードにインベントリを設定 します。

コントロールノードのディレクトリ構造

ansible_project/
├── inventory.ini                  # インベントリ(ターゲットノードの定義)

├── vars/                        # 変数ファイル(Ansible Vaultで暗号化する機密情報を管理)
│   ├── secrets.yml              # AWSキー・DB情報を格納する変数ファイル(Ansible Vaultで暗号化)

├── playbooks/                   # Playbookを格納するディレクトリ
│   ├── deploy.yml               # AWSキー設定やDB操作を行うメインのPlaybook

インベントリファイルを作成します。

touch inventory.ini

inventory.ini ファイルに以下の内容を記載します

[target]
<対象ノードのプライベートIP> ansible_user=ec2-user ansible_ssh_private_key_file=~/.ssh/id_rsa

SSH接続やインベントリファイルの作成に関する内容は、下記の記事で詳しく解説しています。手順や概要に不安がある方は参考にしてください。

内部リンク:001-00022

Ansibleをコントロールノードにインストールする手順と自動構築の基本操作を徹底解説 | AWS上で実践してみた

データベース接続情報の管理

Ansible Vault を活用することで、データベースの接続情報(ホスト・ユーザー名・パスワードなど)を安全に管理 しながら、Ansible Playbook でMariaDB などのデータベースの設定を自動化できます。

まず、データベース接続情報を含む変数ファイル secrets.yml を作成し、Ansible Vault で暗号化します。

変数ファイルの作成:secrets.yml

cd ansible-project/vars/
vi secrets.yml

内容:secrets.yml

db_host: “10.0.1.246”  # Terraform の出力(ターゲットノードのIP)
db_user: “admin”
db_password: “SuperSecretPass”
db_name: “my_database”

ファイルの暗号化

ansible-vault encrypt secrets.yml

実行後、secrets.ymlの内容は暗号化され、直接閲覧できなくなります。編集する場合はansible-vault edit secrets.ymlを使用してください。

暗号化された secrets.yml を参照し、MariaDB の設定を行う Playbook setup_db.yml を作成します。

Playbook の作成 :setup_db.yml

cd ansible-project/playbooks/
vi setup_db.yml

内容:setup_db.yml


– hosts: targets
  become: yes
  vars_files:
    – /home/ec2-user/ansible-project/vars/secrets.yml

  tasks:
    – name: PyMySQL をインストール(pip経由)
      pip:
        name: PyMySQL
        executable: pip3
        state: present

    – name: MariaDB のデータベースを作成
      mysql_db:
        name: “{{ db_name }}”
        state: present
        login_user: “{{ db_user }}”
        login_password: “{{ db_password }}”
        login_host: “127.0.0.1”
      ignore_errors: yes

    – name: MariaDB ユーザーの権限を設定
      mysql_user:
        name: “{{ db_user }}”
        password: “{{ db_password }}”
        priv: “{{ db_name }}.*:ALL PRIVILEGES”
        host: “%”
        state: present
        login_user: “{{ db_user }}”
        login_password: “{{ db_password }}”
        login_host: “127.0.0.1”
      ignore_errors: yes
        priv: “{{ db_name }}.*:ALL PRIVILEGES”
        host: “%”
        state: present
        login_user: “{{ db_user }}”
        login_password: “{{ db_password }}”
        login_host: “{{ db_host }}”
        login_unix_socket: /var/lib/mysql/mysql.sock
      ignore_errors: yes
  • PyMySQL のインストール: Ansible で MariaDB を管理するために必要
  • データベース my_database の作成
  • admin ユーザーに権限を付与

Playbook の実行コマンド

ansible-playbook playbooks/setup_db.yml –ask-vault-pass

実行時に Ansible Vault のパスワードを入力するよう求められます。成功すると、MySQL のデータベースとユーザーが設定されます。

実行結果を確認するには以下のコマンドを入力します。

mysql -h 10.0.1.246 -u admin -p #ターゲットノードのプライベートIP

ログインに成功

Enter password: ********
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 15
Server version: 5.5.68-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

MariaDB [(none)]>

AWSキーの管理

Ansible Vault を使用すると、AWSのアクセスキー(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)を暗号化して安全に管理 できます。

Terraform の output コマンドを使用してAWSアクセスキーとシークレットキーを取得し、Ansible Vault で暗号化します。

Terraform で AWS キーを取得

terraform output aws_access_key
terraform output aws_secret_key

出力された情報をAnsible Vault を使ってsecrets.yml を編集し、AWSキーを追加します。

ansible-vault edit ansible-project/vars/secrets.yml

AWSキーを追記したsecrets.yml

aws_access_key: “<出力された情報>”
aws_secret_key: “<出力された情報>”

db_host: “10.0.1.246”  # Terraform の出力(ターゲットノードのIP)
db_user: “admin”
db_password: “SuperSecretPass”
db_name: “my_database”

AWSアクセスキーを環境変数に設定する Ansible Playbook を作成します。

cd ansible-project/playbooks/
vi setup_aws.yml

内容:setup_aws.yml


– hosts: localhost
  vars_files:
    – ../vars/secrets.yml
  tasks:
    – name: AWSキーを環境変数に設定
      lineinfile:
        path: ~/.bashrc
        line: “export AWS_ACCESS_KEY_ID={{ aws_access_key }} && export AWS_SECRET_ACCESS_KEY={{ aws_secret_key }}”
        create: yes

    – name: 環境変数を即時反映
      shell: source ~/.bashrc

この Playbook は secrets.yml を参照し、AWSキーを環境変数に設定します。以下のコマンドでPlaybookを実行します。

ansible-playbook ansible-project/playbooks/setup_aws.yml –ask-vault-pass

実行時に Ansible Vault のパスワードを入力するよう求められます。成功すると、AWS キーが環境変数として設定されます。

環境変数が設定されたか確認するには以下のコマンドを実行します。

echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY

 Terraform で出力したAWSキーが正しく設定されていれば成功です。

Ansible Vault使用時の注意点

Ansible Vault を活用することで、AWS キーやデータベース接続情報などの機密情報を安全に管理できますが、運用上の注意点があります。

暗号化するファイルは最小限にする

すべてを暗号化しようとすると管理やデバッグが難しくなるため、必要最小限に抑えることを心がけましょう。AWSキーなどの機密情報のみを secrets.yml で管理し、その他の設定は通常の vars/ ファイルとして保存するなどの運用が推奨されます。

チームで共有する場合は共有パスワードを活用

パスワードを手入力する方法では管理が煩雑になります。そのため、「共有パスワードファイル」を活用すると便利です。Vault のパスワードを vault_pass.txt に保存し、チームで共有することで自動化が可能になります。

echo “MySuperSecureVaultPassword” > vault_pass.txt

Playbook 実行時に vault_pass.txt を指定すると、手入力が不要です。

ansible-playbook playbooks/deploy.yml –vault-password-file vault_pass.txt

復号化できなくなるリスク

Ansible Vault のパスワードを紛失すると、暗号化されたファイルを復号できなくなり、AWSキーやデータベース接続情報などの機密情報にアクセスできなくなるリスクがあります。そのため、Vaultのパスワードは厳重に管理し、チームで適切に共有できる仕組みを整えることが重要です。

対策として、パスワード管理ツール(Bitwarden、1Password、KeePass など)を活用する、または専用のセキュアなストレージに保存することで紛失を防ぎましょう。

定期的にパスワードを更新

Ansible Vault のパスワードを長期間変更せずに使用すると、パスワード漏洩や内部不正のリスクが高まるため、定期的に更新することが推奨されます。

特に、チームで運用している場合や外部と共有する機会がある場合は、定期的なパスワード変更をルール化することで安全性が向上します。

まとめ

Ansible Vault を活用することで、AWS アクセスキーやデータベース接続情報などの機密情報を安全に管理しながら、Playbook を自動化できます。Terraform を使用した AWS 環境の構築から、Vault を用いた暗号化、MariaDB のセットアップまでの手順を解説しました。

Vault のパスワード管理や定期的な更新も重要なポイントです。セキュリティを強化しつつ、効率的な構成管理を行うために、Ansible Vault を活用した運用を検討しましょう。

現在クラウドエンジニアとして勤務。AWS(SAP、DOP)とAzure(AZ-305)の資格を保有しており、ネットワークやセキュリティに関する業務を主に行っています。

最新情報をお届けします!

最新のITトレンドやセキュリティ対策の情報を、メルマガでいち早く受け取りませんか?ぜひご登録ください

メルマガ登録

最新情報をお届けします!

最新のITトレンドやセキュリティ対策の情報を、メルマガでいち早く受け取りませんか?ぜひご登録ください

メルマガ登録