4
2

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.

AWS Systems Manager Run Commandを使ってCircleCIからEC2上でコマンドを実行する

Last updated at Posted at 2019-08-25

はじめに

CircleCIからセキュリティグループでアクセスが制限されているEC2上で何かしらのコマンド(ChefやAnsibleたたくなど)を実行したいということがあり、Systems Manager Run Commandを使って実現しました。
Systems Manager Run Commandは初めてさわりましたが手軽で便利だったのでおすすめです。

アクセス制限の問題

多くの場合はEC2へのアクセスはセキュリティグループ等で制限されているため、CircleCIからsshで接続しようとしてもそのままでは接続できない。
また、CircleCIのインスタンスのIPアドレスは動的に設定されるためIPアドレスの制限を許可するのも手間がかかります。(こちらの記事であるような方法で実現は可能)

circle_ci_ec2_ssh.png

Systems Manager Run Commandを使った方法

こういった場合にSystems Manager Run Commandを使えば、IAMで適切なアクセス権を設定することでSSHを使用せずに(セキュリティグループ問題を気にせずに)EC2上でコマンドを実行できます。

やること

  • EC2にSSMにエージェントのインストール(使用するAMIによってはデフォルトでインストールされている)
  • EC2のIAMロール設定
  • コマンドを実行するIAMユーザー作成
  • CircliCI上の設定・処理の追加

EC2にSSMエージェントのインストール

Systems Manager Run Commandを使うためにEC2にSSMエージェントをインストールする必要があります。
SSMエージェントは使用するAMIによってはデフォルトでインストールされており、今回使用した Ubuntu Server 18.04 にはデフォルトでインストールされていためインストールは割愛します。

インストールが必要な場合はこちらを参照ください。

EC2のIAMロール(インスタンスプロファイル)設定

AmazonEC2RoleforSSM のポリシーをアタッチしたIAMロールを作成し割り当てます。

インスタンスの設定 > IAMロールの割り当て/置換 からさきほど作成したロールを割り当てます。

ec2_iam_role_setting.png

CircleCIからコマンドを実行するユーザーのポリシーの設定

テスト用にAmazonSSMFullAccessのポリシーがアタッチされたtest_ssm_userというIAMユーザーを作成します。
ssm_iam_user.png

CircleCI上の設定・処理の追加

ここまででコマンドを実行する準備ができたので、CIで実行する処理を追加していきます。
今回はRubyのaws-sdkを使ってスクリプトを書いていきます。

ec2_run_command.rb
require 'aws-sdk'

Aws.config.update(
  access_key_id:     ENV['SSM_ACCESS_KEY_ID'],
  secret_access_key: ENV['SSM_SECRET_ACCESS_KEY'],
  region:            'ap-northeast-1'
)

Aws::SSM::Client.new.send_command(
  document_name: "AWS-RunShellScript",
  instance_ids: [ENV['EC2_INSTANCE_ID']],
  parameters: {
    commands: ["echo Hello > /tmp/hello.txt"], # この部分がEC2上で実行するコマンド
    executionTimeout:["3600"]
  },
  timeout_seconds: 600,
)

環境変数の設定

コマンドを実行するユーザー(test_ssm_user)のcredentialの情報とコマンドを実行するインスタンスの情報を環境変数に追加
ci_env_vars.png

config.yml

CircleCIのworkflowを定義します。

.circle/config.yml
version: 2.1
executors:
  default:
    working_directory: ~/ec2_sample
    docker:
      - image: ruby:2.6.3-stretch
        environment:
          BUNDLE_GEMFILE: /root/ec2_sample/Gemfile
          BUNDLE_PATH: /root/ec2_sample/vendor/bundle/ruby/2.6.0
jobs:
  run-command:
    executor:
      name: default
    steps:
      - attach_workspace:
          at: ~/ec2_sample
      - checkout
      - restore_cache:
          keys:
            - gf-bundle-1-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
            - gf-bundle-1-{{ .Branch }}-
            - gf-bundle-1-
      - run:
          name: bundler install
          command: gem install bundler:2.0.1
      - run:
          name: bundle install
          command: bundle install --path=./vendor/bundle
      - run:
          name: deploy
          command: bundle exec ruby ec2_run_command.rb # scriptを実行

workflows:
  ec2-ci:
    jobs:
      - run-command

scriptをrubyで書いたのでrubyのDockerイメージを使ったり色々書いてますが、bundle exec ruby ec2_run_command.rb でさきほど書いたscriptを実行しているだけのjobです。

動作確認

run command のjob実行後
スクリーンショット 2019-08-25 19.01.34.png

さきほどコマンドに書いたecho Hello > /tmp/hello.txtがec2上で実行され、hello.txtが作成されていることが確認できました。

$ cat /tmp/hello.txt 
Hello

まとめ

以上、CircleCIからSystems Manager Run Commandを使ってEC2上でコマンドを実行する方法でした。
今回はCircleCIから実行するという使い方をしましたが、他の場面でもちょっとしたことをやるのにRun Commandは使えそうだなという印象です。

参考

チュートリアル: Run Command で AWS CLI を使用する
SSM エージェント の使用
Amazon EC2 Linux インスタンスに SSM エージェント を手動でインストールする
CircleCI2.0からEC2にアクセスするときだけ特定のIPを許可したい

4
2
1

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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?