GitHub Actions で Ansible の playbook を生成して特定のTagのEC2をターゲットに実行
GitHub Actions で Ansible の playbook を生成して特定のTagのEC2をターゲットに実行するYAMLを書いたので、備忘でメモしておきます。
本来であれば以下のようなオープンなActionsを利用すべきでしょう。(自前で頑張るのは極力避けておくのが良いはず)
Run Ansible playbook · Actions · GitHub Marketplace · GitHub
どんな仕組みか
簡単な構成が以下の通り。

何を書いたか
こんな感じのGitHub Actions用のYAMLを書きました。
name: deploy
on:
push:
workflow_dispatch: #手動実行を許可
branches: [ master ]
paths:
- "deploy_files/**"
- ".github/workflows/deploy.yml"
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
pip3 install virtualenv
virtualenv ansible-venv
pip3 install ansible
- name: Create Ansible inventory
env:
# Valiables for aws-cli to get ec2 list
AWS_ACCESS_KEY_ID: "${{secrets.AWS_ACCESS_KEY_ID}}"
AWS_SECRET_ACCESS_KEY: "${{secrets.AWS_SECRET_ACCESS_KEY}}"
AWS_DEFAULT_REGION: "ap-northeast-1"
# Valiables for aws-cli's "--filter"
TAG_ENV: "dev"
TAG_SERVICE: "web"
## deployするのは起動中のサーバのみとする
TAG_INSTANCE_STATE: "running"
run: |
echo "[target]" > inventory
aws ec2 describe-instances \
--filters "Name=tag:Service,Values=${TAG_SERVICE}" "Name=tag:Env,Values=${TAG_ENV}" "Name=instance-state-name,Values=${TAG_INSTANCE_STATE}" \
--query 'Reservations[].Instances[].PrivateIpAddress' | jq -r @csv | tr ',' '\n' >> inventory
- name: Create ansible-playbook
env:
# Valiables for SSH
SSH_USER: sre_github_actions
run: |
# RSYNCの準備
sudo apt-get install -y rsync
echo "${{secrets.SSH_PRIVATE_KEY_ANSIBLE}}" > /tmp/sshkey
chmod 400 /tmp/sshkey
# Ansibleのためのユーザ設定
echo "[defaults]" > ansible.cfg
echo "remote_user = ${SSH_USER}" >> ansible.cfg
# Create ansible-playbook
cat << EOF > playbook.yaml
---
- name: Do playbook
hosts: target
become: yes
gather_facts: no
tasks:
- name: Copy files
ansible.builtin.copy:
src: deploy_files/
dest: /tmp/
owner: root
group: root
EOF
# Check playbook
cat playbook.yaml
- name: Deploy
run: |
hostname
date
pwd
ls -l
# Deployを実行
ansible-playbook --key-file "/tmp/sshkey" -i inventory playbook.yaml
実行に必要なもの
RepositoryのSecretsに以下を設定しておく必要があります。
- aws cli で特定のEC2のIPリストを取得するための変数
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- ansibleで利用する、sshの秘密鍵
- SSH_PRIVATE_KEY_ANSIBLE
加えて runs-on: self-hosted でセルフホステッドのランナーを指定しています。
理由はansibleを各サーバへ実行するためには、内部のネットワークで動作するランナーを利用するのが簡単だからです。