16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CodeBuild から EC2 に SSH して Jenkins の息の根を止める

Last updated at Posted at 2019-06-01

背景

SSHして何かやる定形/不定形業務を廃止するのは、なかなか困難が伴います。

  • SSH接続を許可するか許可しないか、くらいしかできない
    • いやまあ、Linux側でがんばってユーザー/グループを組めばいいんですけど
  • 極少数のメンバーしか、保安上の理由から、許可できない
  • 極少数のメンバーは、能力高しで多忙なのに、たいしたことないSSH作業に忙殺される

以前は、SSH定形業務をJenkinsジョブとして形式知化していましたが、

  • JenkinsのEC2インスタンスが
    • SPOFとなる。単純に台数を増やせばいいものでもない。
    • 闇のダンジョンとなりがち
  • だからといって、今からJenkinsfileとかすごく頑張るのは、あまりに低い山の頂上を目指しているのではないか
  • Jenkinsおじさんの雇用が生まれてしまう

など問題がありました。このうち一部の問題について、CodeBuildジョブにすることで上手く扱えそうな感触が得られたので、まとめます。

ちなみに、ユニットテストやデプロイの類は、CircleCIやCodeBuildに移植済みで、Jenkinsには本当に「ポチるとSSHして何かするジョブ」だけが残っています。

作る

CodeBuildからEC2にSSHで何かさせてみます。

EC2 SSH Keypair、EC2インスタンスを作り、SSHできることを確認する

これは何も躓くところ無いですね。Keypair名は「hoge」で作ります。hoge.pemがダウンロードできてるものとして記述します。お手元から接続できることまで確認してください。

EC2 SSH KeypairのSSH秘密鍵をSSMパラメータストアに保管する

先程のSSH秘密鍵をSSMパラメータストアに暗号化保管します。

https://console.aws.amazon.com/systems-manager/parameters でパラメータの作成して、

スクリーンショット 2019-06-01 12.32.18.png

先程のSSH秘密鍵をまるっとコピーして、

cat hoge.pem | pbcopy

AWS System Managerのパラメータストアの「値」にベタッとして、暗号化保管するので「安全な文字列」で、パラメータの作成。

スクリーンショット 2019-06-01 12.40.01.png

AWSのEC2 SSH Keypairで作成した鍵なら1700文字くらいなので大丈夫ですが、手元のsshコマンドで生成した場合は、SSH秘密鍵の文字数に注意してください。4096文字までです。

CodeBuildジョブを作る

ジョブの組み立ては以下を参考に。ところかまわずSSHできるのはマズいでしょうから、VPC内でCodeBuildが起動するよう組むのが望ましいかと思います。

ポイントは以下。

  • CodeBuildの環境変数で、プレーンテキストではなくパラメータとして、SSMパラメータストアから読むようにする
    • 作例では、CodeBuildの環境変数「SSH_PRIV_KEY」に、SSMパラメータストアの「ssh_private_key」を読み込ませています
  • CodeBuildジョブに付けるIAMロールに、SSMパラメータストアを読む権限を付けてあげる
  • sshコマンドをインストール済みのコンテナを使うと面倒が少ないです。たとえば https://hub.docker.com/r/ansible/ansible-runner とか。

buildspec.yaml は以下のように。sshコマンドで、初回アクセス時の(yes/no?)に答えようがないので抑止したりしてます。

version: 0.2
phases:
  pre_build:
    commands:
      - mkdir ~/.ssh
      - echo "${SSH_PRIV_KEY}" > ~/.ssh/id_rsa
      - chmod 0700 ~/.ssh
      - chmod 0600 ~/.ssh/id_rsa
  build:
    commands:
      - ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ec2-user@172.16.0.6 -p 22 "pwd;ls -alF;hostname"

見てのとおりで、buildspec.yaml でシェル芸を極めたコマンドラインをsshに流し込むのはまあまあ大変です。

接続先のEC2内にシェルスクリプトの類を設置して、CodeBuildはそれを呼ぶだけにするのが良いんじゃないかと思っています。

そのシェルスクリプトは、AnsibleのGitHubリポジトリか、アプリケーションコードのGitHubリポジトリのどちらかで管理して。など。

CodeBuildの権限制御をどうするか

SSHに比べると、いくらか制御しやすいんじゃないでしょうか。

Jenkinsなら Jenkinsでユーザーに権限を付与してアクションを制限する - Qiita の手法で権限制御できました。

AWS なら、

  • IAMで権限制御する
    • IAMグループを作成し、どのIAMグループは、CodeBuildジョブ定義を作成/編集/削除できる、実行/中断できる、などを構成する
  • 誰が、いつ、どのジョブに、何をしたか、の
    • 雑なトラッキングは、CodeBuildのジョブのログで見る
    • 詳細なトラッキングは、AWS CloudTrailでやる

SSHの不定形業務はどうすんの

不定形だと思ってる業務も、Excel手順書(w)に書き出して、何度かやれば、これが定形業務で、ここは人間による条件分岐判断があって、その先は定形業務で、などと見えてくるはずなので、定形業務の部分をCodeBuildに切り出していくといいんじゃないですかね。

SSMセッションマネージャーもあるじゃん

これとかですね。非常に良いと思っていて、技術指針に従って、どちらでも使ったらいいのではないかと。

16
17
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
16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?