GitHub Actions で Ansible の playbook を生成して特定のTagのEC2をターゲットに実行するYAMLを書いたので、備忘でメモしておきます。
本来であれば以下のようなオープンなActionsを利用すべきでしょう。(自前で頑張るのは極力避けておくのが良いはず)
どんな仕組みか
簡単な構成が以下の通り。
何を書いたか
こんな感じの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を各サーバへ実行するためには、内部のネットワークで動作するランナーを利用するのが簡単だからです。