【Rundeck】Rundeckで作ったJobを別環境にインポートする(Centos8)

# はじめに
以下の記事で記載した手順をボタン一つで実行してくれる[Rundeck](https://www.rundeck.com/open-source)のJobを作成した。
せっかくなのでそのJobを新しくEC2に構築した[Rundeck](https://www.rundeck.com/open-source)でインポートするところまで記事にする。
また、検証時にpluginがGUI上からインストールできるようになっていたのがわかったので併せて紹介する。

#### 記事
[EC2 環境にprometheusとthanosを構築する(CentOS8)](https://qiita.com/vidil/items/546edb9ae59d77909d71)
[エージェントレスでオートスケーリングなAWS監視(Centos8)](https://qiita.com/vidil/items/def40cfbce52504d9cd8)

# Rundeckインストール
まずJobをインポートするためのRundeckを構築する。

### インストール
```ruby:rundeckインストール
yum install java-1.8.0
curl -s https://packagecloud.io/install/repositories/pagerduty/rundeck/script.rpm.sh | sudo bash
yum install rundeck-3.3.10.20210301-1.noarch
```

ここまでで画面は出るが画面の遷移がうまくいかないので以下コンフィグのgrails.serverURLにグローバルIPを記述する。

```ruby:/etc/rundeck/rundeck-config.properties
#loglevel.default is the default log level for jobs: ERROR,WARN,INFO,VERBOSE,DEBUG
loglevel.default=INFO
rdeck.base=/var/lib/rundeck

#rss.enabled if set to true enables RSS feeds that are public (non-authenticated)
rss.enabled=false
# change hostname here
grails.serverURL=http://[グローバルIP]:4440 ## ←ここ ##
dataSource.dbCreate = update
dataSource.url = jdbc:h2:file:/var/lib/rundeck/data/rundeckdb;MVCC=true

# Encryption for key storage
rundeck.storage.provider.1.type=db
rundeck.storage.provider.1.path=keys

rundeck.storage.converter.1.type=jasypt-encryption
rundeck.storage.converter.1.path=keys
rundeck.storage.converter.1.config.encryptorType=custom
rundeck.storage.converter.1.config.password=d6e9804ecce8647a
rundeck.storage.converter.1.config.algorithm=PBEWITHSHA256AND128BITAES-CBC-BC
rundeck.storage.converter.1.config.provider=BC

# Encryption for project config storage
rundeck.projectsStorageType=db

rundeck.config.storage.converter.1.type=jasypt-encryption
rundeck.config.storage.converter.1.path=projects
rundeck.config.storage.converter.1.config.password=d6e9804ecce8647a
rundeck.config.storage.converter.1.config.encryptorType=custom
rundeck.config.storage.converter.1.config.algorithm=PBEWITHSHA256AND128BITAES-CBC-BC
rundeck.config.storage.converter.1.config.provider=BC

rundeck.feature.repository.enabled=true
```

準備ができたのでサービスを起動する。

```ruby:rundeckインストール
service runeckd start
```
※コマンドが通ってから起動までにすこし時間がかかるので注意

### ec2プラグイン追加
「http://[グローバルIP]:4440」で画面がでるのでデフォルト管理者のadmin/adminでログインする。
![rundeck-ログイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/575ba048-0f10-b31b-8b4b-ed6999d81b16.png)

次にログイン後の画面右上の歯車マーク？から「plugins」→「Find Plugins」を選択する。
![rundeck-findplugin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/32d8ad36-1c62-d66b-aba6-68a1cec6aa97.png)

「AWS EC2 Node」を探し「Install」をクリックする
![rundeck-ec2plugin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/8807d2c0-f51e-32e6-2b43-62cadf890119.png)

しばらくするとインストールが完了する。
![rundeck-install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/4600a1cd-f32c-e85a-bf30-952985fdbe02.png)

### プロジェクト作成
まずJobをインポートするためのプロジェクトを作成する。
![rundeck-create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/7118f349-7f74-82d8-50ee-288bd13b7e84.png)

基本的に「Project Name」だけ入力して作成すれば大丈夫だが、環境によりちゃんとEC2にアクセスできる鍵とユーザを指定すること。
![rundeck-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/3ae8bc38-c3fd-f6b7-ca13-30434a3382b3.png)

次に、先ほどインストールしたEC2pluginの設定を行うため「Add a new Node Source」を選択する。
![rundeck-project2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/d883802c-f160-7229-1d6a-b56d6338060c.png)

「AWS EC2 Resources」を選択する。
![rundeck-plugin選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/b22fda5e-ce98-5135-f461-84aafa9c7739.png)

最低限「Access Key」「Secret Key」「Endpoint」を入力し、saveする。
※公式に記述がみられなかったのでこの際のポリシーは「AmazonEC2ReadOnlyAccess」を使用している。
![rundeck-plugin設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/0e62af5b-bdf3-dec8-9cf3-c1f202c75780.png)

### Jobインポート
以下のJobをコピーして任意のファイル名で保存する。
※拡張子の縛りとかもないので本当に好きなファイル名でOK

<details><summary>1.prometheusインストール</summary><div>

```rb
- defaultTab: nodes
  description: |
    <説明>
    # Prometheusのインストールを行います。
  executionEnabled: true
  id: 6fae508b-2883-4910-a4a2-710507fdfbb9
  loglevel: INFO
  name: 1.Prometheusインストール
  nodeFilterEditable: false
  nodefilters:
    dispatch:
      excludePrecedence: true
      keepgoing: false
      rankOrder: ascending
      successOnEmptyNodeFilter: false
      threadcount: '1'
    filter: .*
  nodesSelectedByDefault: true
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - description: packagecloudリポジトリ追加
      exec: curl -s https://packagecloud.io/install/repositories/prometheus-rpm/release/script.rpm.sh
        | sudo bash
    - description: prometheusインストール
      exec: sudo yum install -y prometheus2-2.25.2-1.el8.x86_64
    - description: node_exporterインストール
      exec: ' sudo yum install -y node_exporter-1.1.2-1.el8.x86_64'
    - description: prometheus.yml作成
      script: "sudo tee /etc/prometheus/prometheus.yml << 'EOF' > /dev/null \n# my\
        \ global config\nglobal:\n  scrape_interval:     60s # Set the scrape interval\
        \ to every 15 seconds. Default is every 1 minute.\n  evaluation_interval:\
        \ 60s # Evaluate rules every 15 seconds. The default is every 1 minute.\n\
        \  # scrape_timeout is set to the global default (10s).\n\n  external_labels:\n\
        \    cluster: prometheus\n\n# Alertmanager configuration\nalerting:\n  alertmanagers:\n\
        \  - static_configs:\n    - targets:\n      # - alertmanager:9093\n\n# Load\
        \ rules once and periodically evaluate them according to the global 'evaluation_interval'.\n\
        rule_files:\n  # - \"first_rules.yml\"\n  # - \"second_rules.yml\"\n\n# A\
        \ scrape configuration containing exactly one endpoint to scrape:\n# Here\
        \ it's Prometheus itself.\nscrape_configs:\n  # The job name is added as a\
        \ label `job=<job_name>` to any timeseries scraped from this config.\n  -\
        \ job_name: 'prometheus'\n\n    # metrics_path defaults to '/metrics'\n  \
        \  # scheme defaults to 'http'.\n\n    static_configs:\n    - targets: ['localhost:9090']\n\
        \n  - job_name: node\n    static_configs:\n    - targets: ['localhost:9100']\n\
        EOF"
    - description: node_exporterサービス登録
      exec: sudo systemctl enable node_exporter
    - description: prometheusサービス登録
      exec: sudo systemctl enable prometheus
    - description: node_exporterサービス起動
      exec: sudo systemctl start node_exporter
    - description: prometheusサービス起動
      exec: sudo systemctl start prometheus
    keepgoing: false
    strategy: node-first
  uuid: 6fae508b-2883-4910-a4a2-710507fdfbb9
```
</div></details>
<details><summary>2.thanosインストール</summary><div>

```rb
- defaultTab: nodes
  description: |
    <説明>
    # thanosのインストールを行います。
    ### アクセスキー/シークレットキーの設定に必要なS3のアクセス権限は以下のポリシーになります。

    ```
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Statement",
                "Effect": "Allow",
                "Action": [
                    "s3:ListBucket",
                    "s3:GetObject",
                    "s3:DeleteObject",
                    "s3:PutObject"
                ],
                "Resource": [
                    "arn:aws:s3:::[バケット名]/*",
                    "arn:aws:s3:::[バケット名]"
                ]
            }
        ]
    }
    ```
  executionEnabled: true
  id: 7840b836-8c04-423f-9480-dece53d75e96
  loglevel: INFO
  name: 2.thanosインストール
  nodeFilterEditable: false
  nodefilters:
    dispatch:
      excludePrecedence: true
      keepgoing: false
      rankOrder: ascending
      successOnEmptyNodeFilter: false
      threadcount: '1'
    filter: .*
  nodesSelectedByDefault: true
  options:
  - description: thanosが利用するS3のバケット名を指定してください。
    name: S3bucketname
    required: true
  - description: thanosが利用するIAMユーザのaccesskeyを設定してください。
    name: thanos_accesskey
    required: true
    secure: true
    value: XXXXXXXXXXXXXXXXXXXX
    valueExposed: true
  - description: thanosが利用するIAMユーザのsecretkeyを指定してください。
    name: thanos_secretkey
    required: true
    secure: true
    value: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    valueExposed: true
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - description: thanosインストール
      exec: sudo yum install -y thanos-0.18.0-1.el8.x86_64
    - description: S3コンフィグ作成
      script: |-
        sudo tee /etc/prometheus/s3.conf << 'EOF'
        type: S3
        config:
          bucket: "@option.S3bucketname@"
          endpoint: "s3.amazonaws.com"
          region: "ap-northeast-1"
          access_key: "@option.thanos_accesskey@"
          insecure: false
          signature_version2: false
          secret_key: "@option.thanos_secretkey@"
          put_user_metadata: {}
          http_config:
            response_header_timeout: 2m
            insecure_skip_verify: false
          trace:
            enable: false
          list_objects_version: ""
          part_size: 67108864
          sse_config:
            type: ""
            kms_key_id: ""
            kms_encryption_context: {}
            encryption_key: ""
        EOF
    - description: thanos-sidecar起動ファイル作成
      exec: echo "THANOS_SIDECAR_OPTS=\'--tsdb.path=/var/lib/prometheus/data --prometheus.url=http://localhost:9090
        --objstore.config-file /etc/prometheus/s3.conf\'" | sudo tee /etc/default/thanos-sidecar
    - description: thanos-query起動ファイル作成
      exec: echo "THANOS_QUERY_OPTS=\'--http-address=0.0.0.0:10904 --grpc-address=0.0.0.0:10903
        --store=localhost:10901\'" | sudo tee /etc/default/thanos-query
    - description: thanos-store起動ファイル作成
      exec: echo "THANOS_STORE_OPTS=\'--data-dir=/var/lib/thanos/store --http-address=0.0.0.0:10906
        --grpc-address=0.0.0.0:10905 --objstore.config-file /etc/prometheus/s3.conf\'"
        | sudo tee /etc/default/thanos-store
    - description: thanos-compact起動ファイル作成
      exec: echo "THANOS_COMPACT_OPTS=\'--data-dir=/var/lib/thanos/compact --http-address=0.0.0.0:10912
        --objstore.config-file /etc/prometheus/s3.conf\'" |sudo tee /etc/default/thanos-compact
    - description: prometheus起動ファイル変更
      exec: echo "PROMETHEUS_OPTS=\'--config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data
        --storage.tsdb.min-block-duration=1d --storage.tsdb.max-block-duration=1d\'"
        | sudo tee /etc/default/prometheus
    - description: prometheusサービス再起動
      exec: sudo systemctl restart prometheus
    - description: thanos-sidecarサービス登録
      exec: sudo systemctl enable thanos-sidecar
    - description: thanos-queryサービス登録
      exec: sudo systemctl enable thanos-query
    - description: thanos-storeサービス登録
      exec: sudo systemctl enable thanos-store
    - description: thanos-compactサービス登録
      exec: sudo systemctl enable thanos-compact
    - description: thanos-sidecarサービス起動
      exec: sudo systemctl start thanos-sidecar
    - description: thanos-queryサービス起動
      exec: sudo systemctl start thanos-query
    - description: thanos-storeサービス起動
      exec: sudo systemctl start thanos-store
    - description: thanos-compactサービス起動
      exec: sudo systemctl start thanos-compact
    keepgoing: false
    strategy: node-first
  uuid: 7840b836-8c04-423f-9480-dece53d75e96

```
</div></details>
<details><summary>3.yaceインストール</summary><div>

```rb
- defaultTab: nodes
  description: |
    ＜説明＞
    # yaceインストールを行います。
    ### アクセスキー/シークレットキーの設定に必要なyaceのアクセス権限は以下のポリシーになります。

    ```
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": [
                    "tag:GetResources",
                    "cloudwatch:GetMetricData",
                    "cloudwatch:GetMetricStatistics",
                    "cloudwatch:ListMetrics"
                ],
                "Resource": "*"
            }
        ]
    }
    ```
  executionEnabled: true
  id: f6dfdffb-d809-4ff5-8dd7-0b780f67dc39
  loglevel: INFO
  name: 3.yaceインストール
  nodeFilterEditable: false
  nodefilters:
    dispatch:
      excludePrecedence: true
      keepgoing: false
      rankOrder: ascending
      successOnEmptyNodeFilter: false
      threadcount: '1'
    filter: .*
  nodesSelectedByDefault: true
  options:
  - description: yaceが利用するIAMユーザのAccesskeyを指定してください。
    name: yace_accesskey
    required: true
    secure: true
    value: XXXXXXXXXXXXXXXXXXXX
    valueExposed: true
  - description: yaceが利用するIAMユーザのSecretkeyを指定してください。
    name: yace_secretkey
    required: true
    secure: true
    value: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    valueExposed: true
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - description: selinux無効化
      exec: sudo sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
    - configuration:
        command: ssh ${node.username}@${node.hostname} 'sudo reboot & exit 0'
      description: インスタンス再起動
      nodeStep: true
      type: localexec
    - configuration:
        cycles: '1'
        interval: 3s
        progress: 'true'
      description: 再起動待ち
      nodeStep: true
      type: nixy-waitfor-sleep-workflow-node-step
    - configuration:
        host: ${node.hostname}
        interval: '60'
        maxtry: '10'
        port: '22'
      description: 再起動完了待機
      nodeStep: true
      type: nixy-waitfor-local-port-open
    - description: pipインストール
      exec: sudo yum install -y python3-pip
    - description: awscliインストール
      exec: sudo pip3 install awscli
    - description: awsコンフィグ作成
      script: |-
        sudo su - root -c"aws configure set aws_access_key_id @option.yace_accesskey@"
        sudo su - root -c"aws configure set aws_secret_access_key @option.yace_secretkey@"
        sudo su - root -c"aws configure set default.region ap-northeast-1"
    - description: wgetインストール
      exec: sudo yum install -y wget
    - description: yace取得
      exec: wget https://github.com/ivx/yet-another-cloudwatch-exporter/releases/download/v0.26.3-alpha/yet-another-cloudwatch-exporter_0.26.3-alpha_Linux_x86_64.tar.gz
    - description: yace解凍
      exec: tar -zxf yet-another-cloudwatch-exporter_0.26.3-alpha_Linux_x86_64.tar.gz
    - description: yace移設
      script: |-
        sudo mv yace /usr/local/
        sudo chown root:root /usr/local/yace
    - description: yaceコンフィグ作成
      script: |-
        sudo tee /etc/prometheus/yace.conf << 'EOF' > /dev/null
        discovery:
          exportedTagsOnMetrics:
            ec2:
              - Name
          jobs:
          - type: ec2
            regions:
              - ap-northeast-1
            period: 60
            length: 300
            delay: 60
            nilToZero: true
            searchTags:
              - key: Name
                value: .*
            metrics:
              - name: CPUUtilization
                statistics:
                - Maximum
              - name: DiskReadBytes
                statistics:
                - Maximum
              - name: DiskWriteBytes
                statistics:
                - Maximum
              - name: NetworkIn
                statistics:
                - Sum
              - name: NetworkOut
                statistics:
                - Sum
        EOF
    - description: yaceサービス化
      script: |-
        sudo tee /usr/lib/systemd/system/yace.service << 'EOF' > /dev/null
        [Unit]
        Description=yace
        After=network.target

        [Service]
        Type=simple
        User=root
        ExecStart=/usr/local/yace -config.file /etc/prometheus/yace.conf

        [Install]
        WantedBy=multi-user.target
        EOF
    - description: yaceサービス登録
      exec: sudo systemctl enable yace
    - description: yaceサービス起動
      exec: sudo systemctl start yace
    - description: prometheus.yml追記
      script: |-
        sudo tee -a /etc/prometheus/prometheus.yml << 'EOF' > /dev/null

          - job_name: cloudwatch
            static_configs:
              - targets: ['localhost:5000']
        EOF
    - description: prometheus再起動
      exec: sudo systemctl restart prometheus
    keepgoing: false
    strategy: node-first
  uuid: f6dfdffb-d809-4ff5-8dd7-0b780f67dc39

```
</div></details>

作成したプロジェクトのJob画面から「ジョブ定義のアップロード」を選択する。
![rundeck-job.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/8204a052-8ac1-e22d-e0d0-b9128384d873.png)

先ほど保存したファイルを指定しYAML formatを選択の上、「Upload」する。
※まっさらな環境であれば他のオプションは無視でOK
![rundeck-jobupload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/4252e6bc-8c44-74f1-aa3a-551c7724315c.png)

「1 ジョブ was successfully created/modified」が表示されればUpload完了。
![rundeck-jobsuccess.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/e1f44377-bf59-6914-18c4-d1c9aeb7e0f6.png)


### Jobサンプル
インポート後のJobサンプルを載せておく。
![rundeck-thanos1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/d89d4480-0ed2-5af7-7215-1b457f897daf.png)
![rundeck-thanos2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/dd06e05d-b156-c271-1ad5-5615d62b3b58.png)
![rundeck-thanos3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/e510e683-95a8-3e08-30b7-3ba69b6afa0f.png)
![rundeck-thanos4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/0d0df6fb-8151-a93b-d1a7-fa27d45045cd.png)

# あとがき
今回初めてDescriptionなどフル活用してJobを作成したのだけど出来上がりの見易さがすごい。
(現場だとそういうところに時間かけられないので)
もっとユーザライクに寄せようとすると足りない部分はあるけど脳死でDescription書くだけでもこの仕上がり。
これならインフラ嫌いの人や一般職の人も中身見てくれそうだし、引継ぎというか教材的な方面の可能性を感じた。
なお、今回の環境では「3.yaceインストール」は実行できない為、後日別記事にて紹介します。