最新のrundeckでsshレス環境ジョブマネージャを実現しよう 

## AWSをとりまくジョブマネージャ状況

AWSではインフラに必要な様々なリソースが提供、拡充され続けていますが、ことジョブマネージャに関して言うと、AWSで提供されている各リソースに付随したcron相当の機能しかなく充実した機能が提供されているとは言えません。ジョブマネージャは海外では熱い話題みたいなのでそのうち実装されるのかもしれませんが、現時点での対応のため、市販、フリーのジョブマネージャを選定する必要がありました。

今回はフリーであるにも関わらず市販のジョブマネージャにも負けない機能を有しているrundeckを取り上げ、その機能の紹介と拡充に至るまでの経緯を簡単に紹介します。

## rundeckを採用した理由

ジョブフローを記述するならAzkabanやAirflowといった選択肢もあるのですが、さわりということで直感的なコマンドライン記述が可能なrundeckを採用しました。
jenkinsなどはむしろCI/CDツールとしての性格が強いためジョブマネージャとしては適切ではないと判断しました。どんなツールにも言えることですが、これだけジョブマネージャが世の中に存在していながらもまだ新たなツールが誕生、更新され続けていることはそれだけ満足する機能を提供することができていないということだし、世のニーズも変わり続けているということといえます。その点、rundeckはjp1やら千手やらに比較しても特に申し分ない機能を有しているといえます。あいつら高いですから。

こないだまでは日本語化対応しなければテンプレを入れなければいけなかったのですが、最新だと黙っていても日本語化対応されています。すばらしい対訳状況です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/244490/ff103042-f887-7afb-b57e-1f2ea09a411c.png" width=80%>

## sshレス時代の夜明け

ジョブマネージャにつきまとう便利さの半面として、管理の煩雑さが挙げられます。
例えばAWSにジョブマネージャを導入した場合、操作対象のサーバのセキュリティグループに対しsshのポートを開ける必要があり、サーバの増強や拡充に伴いネットワーク設定の見直しも図られるため、併せて管理コストも上昇し、さらにはオペミスやセキュリティ事故の元となる懸念がありました。

そういった事態を解決してくれる救世主が現れました。ssm-agentです。
ssm-agentをサーバに導入することにより、わざわざセキュリティグループのインバウンドに22番を指定しなくとも、同じVPC内のサーバであれば任意のコマンドを送ることができます。VPCエンドポイントを使用すれば、VPC間をまたぐこともできますし、さらにはオンプレ資産にも導入できるすごいやつです。
これでよくわかっていない人に大事なサーバを触らせて大惨事になることは避けられます。

## ssm-agentの導入

Amazon linuxを導入すれば最初からssm-agentはami内に組み込まれていますが、顧客状況が許さず自由にOSを選ぶことができないこともあると思います。
今回は、CentOS<img src="https://s3-ap-northeast-1.amazonaws.com/sista05-development/capture/centos.jpg" width=2%>を使用した場合でのssm-agentの導入とその自動アップデート設定を、ネットを探せばたくさん類例はあるものの載せてみました。

````shell:cmd
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm

````
run_commandを使うだけなら操作対象のEC2にポリシーAmazonEC2RoleforSSMを付与すればよいです。
s3にログ出力したいのであればバッチインスタンスにs3関連のポリシーを付与する必要がありますが、run_command自体に出力先のs3を指定するオプションが存在するのでとりあえず今のところは不要です。



ssm-agentを導入すると、自動的なssm-agentのアップデートが可能になります。

````shell:auto_update_command
aws ssm create-association --targets Key=tag:TagKey,Values=TagValue --name AWS-UpdateSSMAgent --schedule-expression "cron(0 0 2 ? * SUN *)"
```


## rundeckの導入

rundeckはdockerで構築しました。
[Serverあれこれ様の](http://serverarekore.blogspot.com/2018/10/dockerrundeck306mariadb103.html)のサイトを参考に一部改変しています。

```````Docker:Dockerfile
FROM alpine:3.8

ENV RUNDECK_VERSION "3.0.11-20181221"
ENV RUNTIME_PACKAGES "openjdk8 python py-pip "
ENV TZ Asia/Tokyo

RUN  apk update \
  && apk add  --no-cache $RUNTIME_PACKAGES \
  && pip install --upgrade awscli \
  && rm -rf /var/cache/apk/* \
  && mkdir -p /opt/rundeck/libext \
  && mkdir -p /etc/rundeck \
  && mkdir .aws \
  && wget https://dl.bintray.com/rundeck/rundeck-maven/rundeck-$RUNDECK_VERSION.war -O /opt/rundeck/rundeck-$RUNDECK_VERSION.war  \
  && wget https://github.com/higanworks/rundeck-slack-incoming-webhook-plugin/releases/download/v0.9.dev/rundeck-slack-incoming-webhook-plugin-0.9.jar \
  -O /opt/rundeck/libext/rundeck-slack-incoming-webhook-plugin-0.9.jar

COPY ./start.sh /
RUN chmod +x ./start.sh
COPY ./config /root/.aws/
COPY ./credentials /root/.aws/
EXPOSE 4440
VOLUME /opt/rundeck

CMD /start.sh $RUNDECK_VERSION

```````

docker-composeは参考先のままですが、AWSを使用しているのであればECSを使用すればよいですね。
ECSでは最近、[SSMパラメータストアから秘密情報を直に復号できるようになりました。](https://aws.amazon.com/jp/about-aws/whats-new/2018/12/aws-fargate-platform-version-1-3-adds-secrets-support/)
ECSで運用するなら、EFSでvolumeを永続化したりする必要もありますね。

## slack pluginを導入する

rundeckには[公式のplugin](https://docs.rundeck.com/plugins/)も含めてかなりのpluginが存在しますが、slackのpluginは公式せず、さらにslackプラグインはいくつかある様子なので、とくに[こちらの](https://github.com/higanworks/rundeck-slack-incoming-webhook-plugin)導入手順を紹介します。

rundeck の **[project settings]** -> **[edit  configuration]** ->  **[edit configuration file]**
 よりファイルにslackのwebhook URLを追記してください。

**[project settings]** -> **[edit  configuration]**
<img src="https://qiita-image-store.s3.amazonaws.com/0/244490/818a47e1-7444-dc8a-efcc-1c2bd7f9925c.png" width=50%>

**[edit configuration file]**
<img src="https://qiita-image-store.s3.amazonaws.com/0/244490/3184dc2b-dbb2-ae00-cfc1-2c3d44cecac4.png" width=50%>


```shell:webhooK_URL
project.plugin.Notification.SlackNotification.webhook_url=https://hooks.slack.com/services/T4GFG57RT/xxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxx
```

run commandは以下のような感じで実行しています。前述のとおりコマンド側で出力先を指定できます。

```shell:run_command
aws ssm send-command \
 --instance-ids "i-xxxxxxxxxxxxxxxxx" \ # 特定のタグが付いているインスタンスを選択的に実行することも可能
 --document-name "AWS-RunShellScript" \
 --comment "IP config" \
 --parameters commands=ifconfig \ # 実行コマンド
 --output-s3-bucket-name infratest-xxxxxxxxxxx # s3の名前を指定
　
```

以上、rundeckの成否がslackに出力されます。開発のお供に！

<img src="https://qiita-image-store.s3.amazonaws.com/0/244490/2b669f8e-ce5e-01bf-f532-a19fbb745e93.png" width=50%>



## 少し話は逸れますが

sshレスといえば最近では結構いろんなところでご紹介されていますが、ssm-agentを導入するとブラウザからCLIコンソール操作できるようにもなりました。ただ、通常のログインと異なり.bash_profile等が読み込まれないため、適宜パス設定など行う必要があります。

![console.PNG](https://qiita-image-store.s3.amazonaws.com/0/244490/b6ab7f8b-6b87-2920-12ae-becca64f1445.png)