👻

CircleCI を使って Agentless で Linux にデプロイを行う(1)

に公開

今日はCircleCIを使ってUbuntuにnginxをデプロイしていきます。いままでのサンプルではすべてAWS CLIを用いてAWS Lambda 関数をデプロイしてきました。

勿論通常のLinuxにログインを行い必要なコマンドを実行させる、といったことが可能です。このためDeploy以外にもOSの初期設定や必要なライブラリのインストールなどが可能です。

CircleCIのDeploy環境はデフォルトではコンテナ型LinuxがCircleCIクラウド環境の中で起動しそこで様々なコマンドを実行できるようになっており、デプロイ以外にもOSメンテナンス、緊急時のパッチ適用基盤としても活用できます。

さっそくやってみる

1.SSH 秘密鍵の登録

まずはSSHの鍵を生成します。

ssh-keygen -t ed25519 -C "your_email@example.com"

その後生成された秘密鍵をCircleに登録しておきます。
Projectの右上Settingsボタンをクリックします。

左ペインSSH KeysからAdd SSH Keyをクリックして表示されるダイアログで登録します。

画面にFingerprintが表示されますのでそちらを手元にメモしておきます。config.ymlで用いるadd_ssh_keys ステップで指定に使用します。

次に任意のLinux環境(以下の手順ではUbuntuを使用しています)にSSHログインが行えるようにしています。先ほど作成されたSSH用公開鍵を~/.ssh/authorized_keysに登録すればはいれるようになります。

2. config.yml の設定

https://zenn.dev/kameoncloud/articles/641dbdd496a59d
の記事などを参考にGitHubレポジトリとCircleCI Projectが連携済でconfig.ymlのmainブランチへのマージをイベントとしてデプロイが実行される状態になっていることが前提です。

config.yml
version: 2.1

jobs:
  deploy-nginx:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout

      # CircleCIに登録したSSH鍵を使用(Fingerprintで指定)
      - add_ssh_keys:
          fingerprints:
            - "SHA256:xxxxxXaNRPC2eMjq1oXNBk"

      # known_hosts 登録
      - run:
          name: Register known_hosts
          command: |
            mkdir -p ~/.ssh
            ssh-keyscan -p 22 27.133.130.xxx >> ~/.ssh/known_hosts

      # Nginx インストールと起動(OSを自動判別)
      - run:
          name: Install & start Nginx
          command: |
            ssh -p 22 ubuntu@27.133.130.xxx 'bash -euxo pipefail -c "
              if command -v apt-get >/dev/null 2>&1; then
                sudo apt-get update -y
                sudo DEBIAN_FRONTEND=noninteractive apt-get install -y nginx
              elif command -v dnf >/dev/null 2>&1; then
                sudo dnf install -y nginx
              elif command -v yum >/dev/null 2>&1; then
                sudo yum install -y epel-release || true
                sudo yum install -y nginx
              elif command -v zypper >/dev/null 2>&1; then
                sudo zypper -n refresh
                sudo zypper -n install nginx
              else
                echo \"Unsupported OS\" >&2
                exit 1
              fi
              if command -v systemctl >/dev/null 2>&1; then
                sudo systemctl enable --now nginx
                sudo systemctl status nginx --no-pager
              else
                (sudo service nginx start || sudo /etc/init.d/nginx start) || true
              fi
            "'

      # Nginx応答確認
      - run:
          name: Check Nginx response
          command: |
            curl -I http://27.133.130.xxx || true

workflows:
  deploy:
    jobs:
      - deploy-nginx

以下の値はそれぞれ皆さんの環境用に書き換えてください。
"SHA256:xxxxxXaNRPC2eMjq1oXNBk",27.133.130.xxx,ubuntu
ubuntuはOSのSSHログインに用いるIDになります。

3. テスト

config.ymlをmainブランチにマージした時点でデプロイが実行されます。

無事すべてのプロセスが成功すれば作業完了です。
IPアドレスにブラウザでアクセスすれば無事nginxの画面が表示されます。

4. 補足:初回アクセス時のプロンプトの迂回

通常SSHで初めてのホストにアクセスを行うと、本当にアクセスを行ってよいか?というプロンプトが表示されます。自動でSSHログインを行うためにはそのプロンプトを回避する必要があるため以下の指定を行っています。

      # known_hosts 登録
      - run:
          name: Register known_hosts
          command: |
            mkdir -p ~/.ssh
            ssh-keyscan -p 22 27.133.130.xxx >> ~/.ssh/known_hosts

Discussion