Docker + Ansible + EC2っぽいコンテナ で手軽にAWS開発環境を構築する
Dockerを使用して、Ansible と EC2の両方を操作できる環境を構築し、わざわざAWSを用意しなくても手元でインフラの開発ができる環境を構築します。
DockerやAnsible、EC2については、ここでは特に詳しい説明は書きません。これらの単語がわからない方はググってください。
構築環境
Docker for Windowsを使って、Docker上に Ansible と Amazon EC2 のコンテナを動作させます。Dockerが使える環境であればMacなどでも動作させることは可能かと思います。Docker for Windowsは各自でインストールしてください。インストール方法に関しては本記事では言及しません。
ファイル構成
ファイルの構成は以下です。
ansible-test ┬ amznlinux2 ┬ Dockerfile
│ └ id_rsa.pub (公開鍵)
│
├ ansible ┬ Dockerfile
│ ├ id_rsa (秘密鍵)
│ └ data ┬ ansible.cfg
│ ├ hosts
│ ├ playbook.yml
│ └ src (適当にファイルやフォルダを入れておく)
│
└ docker-compose.yml
AWSのコンテナへは公開鍵暗号方式で接続するので、公開鍵と秘密鍵を事前に用意しておく必要があります。当方は、gitbashを使用し公開鍵、秘密鍵のキーペアを作成しました。各自で事前に用意してください。参考:SSH 公開鍵の作成
キーペアを作成したら、上記の通り該当のフォルダへ配置してください。
AWS EC2コンテナのDockerfile
SSH 接続できる Amazon Linux 2 の Docker イメージを作成してシステム構築してみる
上記の記事を参考に(すみません、丸パクリです…)作成します。
FROM amazonlinux:2
COPY ./id_rsa.pub /tmp/
RUN yum -y update && \
yum -y install \
sudo \
shadow-utils \
procps \
wget \
openssh-server \
openssh-clients \
which \
iproute \
e2fsprogs && \
yum clean all && \
wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python && \
systemctl enable sshd.service && \
echo "PasswordAuthentication no" >> /etc/ssh/sshd_config && \
useradd ec2-user && \
echo "ec2-user ALL=NOPASSWD: ALL" >> /etc/sudoers && \
sudo -u ec2-user mkdir -p /home/ec2-user/.ssh && \
mv /tmp/id_rsa.pub /home/ec2-user/.ssh/ && \
chmod -R go-rwx /home/ec2-user/.ssh && \
cat /home/ec2-user/.ssh/id_rsa.pub >> /home/ec2-user/.ssh/authorized_keys && \
echo "export LANG=en_US.UTF-8" >> /home/ec2-user/.bash_profile
上記のコードを「Dockerfile」で保存し、amznlinux2配下に設置してください。少しだけ補足すると、上記のコードで限りなく初期作成したEC2のサーバーに近い状態でコンテナを立ち上げることができます。ec2-userも作成され、用意したキーペアでSSH接続することも可能です。
AnsibleコンテナのDockerfile
上記の記事を参考に作成しました。
FROM centos:7
RUN yum install epel-release -y && \
yum -y update && \
yum --enablerepo=epel install python2-pip.noarch -y && \
yum install openssh-server -y && \
yum install openssh-clients -y && \
yum reinstall glibc-common -y && \
yum install sshpass -y && \
yum remove python27-chardet.noarch -y && \
pip install --upgrade pip && \
pip install ansible && \
pip install pywinrm && \
yum clean all
ENV LANG ja_JP.UTF-8
RUN mkdir -p /etc/ansible
COPY id_rsa /tmp
RUN chmod 600 /tmp/id_rsa
AnsibleのコンテナからEC2のコンテナへSSH接続できるよう、「/tmp」フォルダに秘密鍵を配置し、パーミッションを600に変更しています。
ansible.cfg ファイルには下記を記述しておいてください。
[ssh_connection]
ssh_args = -o StrictHostKeyChecking=no
こうすることで、AnsibleでEC2コンテナにSSH接続した際に、接続先の鍵情報(未知の鍵)に関して確認をされないように制御することができます。
hosts(inventoryファイル) には下記を記述します。
[local]
amznlinux
[local:vars]
ansible_user=ec2-user
ansible_ssh_private_key_file=/tmp/id_rsa
Ansibleで実行するplaybookファイルは一旦下記を記述します。(やりたいことを記述するようにしてください。)
- hosts: local
tasks:
- name: deploy
copy:
src: ./src
dest: /home/ec2-user
mode: 0755
src フォルダ内には適当にファイルやフォルダーを配置してください。上記のplaybookでは、name: deployとある通り、srcフォルダを/home/ec2-userへアップロードします。
docker-compose.yml
上記2つのコンテナを起動するdocker-compose.ymlファイルは下記になります。
version: "3"
services:
ansible:
container_name: ansible
build: ./ansible
links:
- amznlinux2
tty: true
volumes:
- ./ansible/data:/etc/ansible
privileged: true
amznlinux2:
container_name: amznlinux
build: ./amznlinux2
tty: true
privileged: true
command: /sbin/init
ports:
- "2222:22"
「ansible」「amznlinux」という名前でそれぞれコンテナを作成します。EC2のコンテナには、2222番ポートから22番ポートへ接続できるようにポートの設定をしています。これにより、Teratermなどのツールを使用してEC2コンテナへのSSH通信を可能にします。
コンテナの起動
ansible-test フォルダ内で下記コマンドを実行します。
docker-compose up -d
docker psコマンドで2つのコンテナが立ち上がっていることが確認できればOKです。
AnsibleコンテナからEC2コンテナへの通信の確認
AnsibleのコンテナからEC2のコンテナへSSHを使って接続してみます。Dockerfileを作成するところで補足として説明しましたが、EC2のコンテナには「ec2-user」が作成されており、事前に作成したキーペアを使って接続できるようにしてあります。また、Ansibleのコンテナには、/tmp に秘密鍵を配置しました。
それでは、Ansibleコンテナ内へ入り、配置済みの秘密鍵を使ってEC2コンテナへ接続します。
まず、下記のコマンドを入力し、Ansibleのコンテナに入ります。
docker exec -it ansible /bin/bash
次に下記のコマンドを入力し、EC2コンテナへ接続を試みます。途中でyes/noが問われたらyesと入力してください。
ssh -i /tmp/id_rsa ec2-user@amznlinux
下記画像の通り、ユーザーがec2-userとなっていたら、AnsibleとEC2コンテナ間は繋がっており、SSHで接続できたということになります。
クライアントツールを使って直接EC2コンテナへログインする
SSHが利用できるクライアントツールを使えば、直接EC2のコンテナへ接続することができます。
下記画像の通り、Hostをlocalhost、TCP portを2222に設定し、ec2-user、秘密鍵を選択すれば直接EC2コンテナへログインすることができます。
Ansibleの実行
Ansibleコンテナへ入り、playbookが保存されているフォルダへ移動します。
cd /etc/ansible
このフォルダ内で、下記コマンドを実行してください。
ansible-playbook -i hosts playbook.yml
failedが0となっていればOKです。
src フォルダがEC2コンテナへアップロードされたか確認してみましょう。
/home/ec2-user 内に、srcフォルダ、またその配下のファイルやフォルダがAnsibleコンテナからアップロードされたことが確認できました。
まとめ
Dockerを使用し、ローカル環境にAnsibleとEC2コンテナを作成し、AnsibleコンテナからEC2コンテナへ通信できることを確認しました。
Ansibleの練習が気軽にできる環境を作成することができました。サーバーの構築やファイルのアップロード、バックアップなどの作業をコードによって管理し、手作業によるミスなどを減らしていければ良いですね。