LoginSignup
12
13

More than 5 years have passed since last update.

SSH のアクセス制限された GCP に Circle CI からデプロイする

Last updated at Posted at 2016-07-07

表題の通り,GCP(Google Cloud Platform) でいうところの default-allow-ssh などに特定のIPアドレスが指定されているケースで,Circle CI(など)から自動デプロイさせたいと思ったらちょっと困ったという話です.

方針

公開しているサーバに対して,社内など一部の場所からのみ ssh アクセスできるようにすることが多いと思います.
GCP だと例えばこんな感じになると思います.
image

その場合,外部のCIサービスから自動デプロイさせたい場合,CIサービスのIPアドレスに対して ssh 接続を許可しないといけないですが,Circle CI の場合,IPアドレスが固定されていません.

そこで,デプロイの都度,自身の IP アドレスを取得して,デプロイ先の許可アドレスに追加することにします.
また,その IP アドレスは次回は使用されない可能性が高いので,デプロイが完了したら許可アドレスから削除することにします.

gcloud コマンドを利用する

Circle CI では gcloud コマンドが使用できるので,それを使用します.
=> cite: https://circleci.com/docs/google-auth/
※ 上記の内容には init は書かれていないのですが,使用できなかったため,最初に gcloud init をしています

setup_gcloud() {
    echo $GCP_CLIENT_SECRET | base64 --decode > ${HOME}/client-secret.json

    yes no | gcloud init
    gcloud --quiet components update
    gcloud auth activate-service-account --key-file ${HOME}/client-secret.json
    gcloud config set project $GCP_PROJECT
}

ここで, $GCP_CLIENT_SECRET, $GCP_PROJECT の環境変数はあらかじめウェブ上から Circle CI に登録しておきます.
image

setup_gcloud を実行すると,gcloud への認証が済むので,続いて GCP の firewall-rules の変更ができるようにします.

GCP のファイアウォールルールを動的に変更する

まずは,実行時の circle ci サーバの GLOBAL_IP を dig コマンドで取得しておきます.

GLOBAL_IP=`dig +short myip.opendns.com @resolver1.opendns.com`

IPアドレスの変更ができるようにしますが,この時,デプロイ前の設定値を取得しておくと,元に戻すのが楽です.
(↓ 変数が雑に書かれてますが,関数呼び出し前に定義してある想定です)

fetch_default_source_ranges() {
    gcloud compute firewall-rules describe default-allow-ssh --format json | jq -r '.sourceRanges | join(",")'
}

update_gcp_firewall() {
    gcloud compute firewall-rules update default-allow-ssh --source-ranges "${DEFAULT_SOURCE_RANGES},${GLOBAL_IP}"

}

rollback_gcp_firewall() {
    gcloud compute firewall-rules update default-allow-ssh --source-ranges $DEFAULT_SOURCE_RANGES
}

default-allow-ssh は各自の設定名に読み替えてください.

デプロイ前に update_gcp_firewall で許可IPを追加し,終了時(エラー時)に rollback_gcp_firewall で,設定を戻します.
この時,あらかじめデプロイ前の許可IPを fetch_default_source_ranges によって取得しておきます.

Circle CI では jq が使えたので使ってます.
使えるコマンドがいろいろと用意されている良いですね.

まとめ

まとめると,以下のようになります(関数定義は除く).

setup_gcloud

GLOBAL_IP=`dig +short myip.opendns.com @resolver1.opendns.com`
DEFAULT_SOURCE_RANGES=fetch_default_source_ranges

update_gcp_firewall

// デプロイ: bundle exec cap dev deploy など

if [ $? -eq 0 ]
then
    rollback_gcp_firewall
    // slack 通知など
    true
else
    rollback_gcp_firewall
    // slack 通知など
    false
fi

実行すると,デプロイ直前と完了後に,このようなちょっとわかりづらいログが出ているのが分かります.

image

以上です

12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13