ビビリフクロウの足跡

いつもお世話になっているインターネットへの恩返し

自宅プライベートクラウドにおけるCDのご紹介

自宅プライベートクラウドをお休みの時間に粛々と構築しています。現在は構築用のコードリポジトリ(ansibleだったり、k8sマニフェストだったり、docker-composeだったり。。。)に対するデプロイが全て手動で煩雑だったため、CDをGitLab CIにて実現しようと奮闘しています。本日はその模様をお伝えしたく。。。

まず、私はアーキテクチャ図を書くのが好きなので、全体構成の説明です。

f:id:bbrfkr:20200628191917p:plain

結構シンプルでして、インフラコードがGitLab.comにプッシュされましたら (もちろん、プライベートリポジトリ)、自宅インフラ内で動いているGitLab Runnerがそのイベントをキャッチします。GitLab Runnerはその後、AWXに対してPlaybookの実行を依頼します。AWXはHashicorp Vaultに対して、CA秘密鍵で署名されたSSH公開鍵の生成を依頼し、その鍵をもって構成管理対象サーバに接続・Playbook実行を行います。

私はAWXに登録するJob Templateを管理したくなかったので、GitLabのCD過程でその時必要なJob Templateを作っては消すようにしています。AWXを管理するためのplaybookとか、二度手間過ぎて作りたくないし、実行履歴はGitLab上から確認できるので、これで良しとしています。

参考までに、CDで使っている .gitlab-ci.yml をぺたり。lower系のジョブはKVMホストなどのインフラでも基礎となる部分の実行ジョブ、それ以外をupper系のジョブとしてまとめています。。。

stages:
  - test
  - execute
  - cleanup_execute
  
.common_template: &common_template
  image: $DYNAMIS_CI_IMAGE

test:
  <<: *common_template
  stage: test
  script:
    - ansible-lint src/*.yaml
  tags:
    - stg
  except:
    - master
    - tags

.execute_template: &execute_template
  stage: execute
  script:
    - >
      awx job_templates create
      --name ${AWX_JOB_TEMPLATE_NAME}
      --project ubuntu-os-common
      --playbook src/site.yaml
      --inventory dynamis
      --scm_branch ${CI_COMMIT_REF_SLUG}
      --become_enabled true
      --job_type run
      --limit "${AWX_EXEC_LIMIT}"
    - >
      awx job_templates associate ${AWX_JOB_TEMPLATE_NAME}
      --credential ${AWX_SSH_CREDENTIAL}
    - >
      awx job_templates launch ${AWX_JOB_TEMPLATE_NAME}
      --monitor
  when: manual
  allow_failure: false

execute_stg_lower:
  <<: *common_template
  <<: *execute_template
  variables:
    TOWER_HOST: $AWX_HOST_STG
    TOWER_USERNAME: $AWX_USERNAME_STG
    TOWER_PASSWORD: $AWX_PASSWORD_STG
    AWX_SSH_CREDENTIAL: $AWX_SSH_CREDENTIAL_STG
    AWX_EXEC_LIMIT: lower
    AWX_JOB_TEMPLATE_NAME: &job_templates_stg_lower ubuntu-os-common-execute-stg-lower
  tags:
    - stg
  only:
    - master

execute_stg_upper:
  <<: *common_template
  <<: *execute_template
  variables:
    TOWER_HOST: $AWX_HOST_STG
    TOWER_USERNAME: $AWX_USERNAME_STG
    TOWER_PASSWORD: $AWX_PASSWORD_STG
    AWX_SSH_CREDENTIAL: $AWX_SSH_CREDENTIAL_STG
    AWX_EXEC_LIMIT: all:!lower:!kernel
    AWX_JOB_TEMPLATE_NAME: &job_templates_stg_upper ubuntu-os-common-execute-stg-upper
  tags:
    - stg
  only:
    - master

execute_prod_lower:
  <<: *common_template
  <<: *execute_template
  variables:
    TOWER_HOST: $AWX_HOST_PROD
    TOWER_USERNAME: $AWX_USERNAME_PROD
    TOWER_PASSWORD: $AWX_PASSWORD_PROD
    AWX_SSH_CREDENTIAL: $AWX_SSH_CREDENTIAL_PROD
    AWX_EXEC_LIMIT: lower
    AWX_JOB_TEMPLATE_NAME: &job_templates_prod_lower ubuntu-os-common-execute-prod-lower
  tags:
    - prod
  only:
    - tags

execute_prod_upper:
  <<: *common_template
  <<: *execute_template
  variables:
    TOWER_HOST: $AWX_HOST_PROD
    TOWER_USERNAME: $AWX_USERNAME_PROD
    TOWER_PASSWORD: $AWX_PASSWORD_PROD
    AWX_SSH_CREDENTIAL: $AWX_SSH_CREDENTIAL_PROD
    AWX_EXEC_LIMIT: all:!lower:!kernel
    AWX_JOB_TEMPLATE_NAME: &job_templates_prod_upper ubuntu-os-common-execute-prod-upper
  tags:
    - prod
  only:
    - tags
    
.cleanup_execute_template: &cleanup_execute_template
  stage: cleanup_execute
  script:
    - awx job_templates delete ${AWX_JOB_TEMPLATE_NAME}
  when: always

cleanup_execute_stg_lower:
  <<: *common_template
  <<: *cleanup_execute_template
  variables:
    TOWER_HOST: $AWX_HOST_STG
    TOWER_USERNAME: $AWX_USERNAME_STG
    TOWER_PASSWORD: $AWX_PASSWORD_STG
    AWX_JOB_TEMPLATE_NAME: *job_templates_stg_lower
  tags:
    - stg
  needs:
    - execute_stg_lower
  only:
    - master

cleanup_execute_stg_upper:
  <<: *common_template
  <<: *cleanup_execute_template
  variables:
    TOWER_HOST: $AWX_HOST_STG
    TOWER_USERNAME: $AWX_USERNAME_STG
    TOWER_PASSWORD: $AWX_PASSWORD_STG
    AWX_JOB_TEMPLATE_NAME: *job_templates_stg_upper
  tags:
    - stg
  needs:
    - execute_stg_upper
  only:
    - master

cleanup_execute_prod_lower:
  <<: *common_template
  <<: *cleanup_execute_template
  variables:
    TOWER_HOST: $AWX_HOST_PROD
    TOWER_USERNAME: $AWX_USERNAME_PROD
    TOWER_PASSWORD: $AWX_PASSWORD_PROD
    AWX_JOB_TEMPLATE_NAME: *job_templates_prod_lower
  tags:
    - prod
  needs:
    - execute_prod_lower
  only:
    - tags

cleanup_execute_prod_upper:
  <<: *common_template
  <<: *cleanup_execute_template
  variables:
    TOWER_HOST: $AWX_HOST_PROD
    TOWER_USERNAME: $AWX_USERNAME_PROD
    TOWER_PASSWORD: $AWX_PASSWORD_PROD
    AWX_JOB_TEMPLATE_NAME: *job_templates_prod_upper
  tags:
    - prod
  needs:
    - execute_prod_upper
  only:
  - tags