0
0

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 3 years have passed since last update.

【Rundeck】常に最新のOSでインスタンスが立ち上がる仕組みを作る

0
Posted at

はじめに

というわけでpackerとRundeckを連携させた仕組みを紹介したい。
名付けて「常に最新のOSでインスタンスが立ち上がる仕組み」である。
一応書いておくが本記事は何か定義したり方向性を決定するものではない。
思考実験の結果ただ出来上がっただけのものである。

前提

早速紹介したいのだが前提として以下のようなLaunchJobを使っている必要がある。
同じようなことしていればよく全く同じ必要はない。あくまでサンプル。

image.png
Job自体の定義は以下

LaunchJob
- defaultTab: nodes
  description: EC2のインスタンスを作成します。
  executionEnabled: true
  group: OS最新化グループ/インスタンス作成
  id: 8f1f4e4a-9c43-4a51-b0ab-718482aad522
  loglevel: INFO
  name: インスタンス作成(自動更新対応版)
  nodeFilterEditable: false
  options:
  - description: サーバ名を入力してください。
    name: name
    required: true
  - description: |-
      AMIイメージのIDを入力してください。(デフォルト:alma9_last)<br>
      さかのぼる場合はhttp://54.65.21.190:4440/project/Project/job/show/940c3365-49ee-4f66-9fa1-8e3bfe820744を実行してidをさがしてください。
    name: AMI
    required: true
    value: alma9_last
  - description: 台数を指定してください。(デフォルト1台)
    label: 台数
    name: count
    required: true
    value: '1'
  - description: インスタンスタイプを指定してください。(デフォルト:t3.micro)
    label: インスタンスタイプ
    name: instancetype
    required: true
    value: t3.micro
  - description: 私用するキーペア名を指定してください。(デフォルト:aws-1)
    name: keyname
    required: true
    value: aws-1
  - description: セキュリティグループを指定してください。(デフォルト:sg-03179fefab86413aa)
    name: securitygroup
    required: true
    value: sg-03179fefab86413aa
  - description: サブネットIDを指定してください。(デフォルト:subnet-095c2be997f1ffc36)
    name: subnetid
    required: true
    value: subnet-095c2be997f1ffc36
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - script: |-
        ami=`sudo cat /var/lib/rundeck/ami/@option.AMI@`
        aws ec2 run-instances --image-id $ami  --count @option.count@ --instance-type @option.instancetype@ --key-name @option.keyname@ --security-group-ids @option.securitygroup@ --subnet-id @option.subnetid@ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=@option.name@}]'
    keepgoing: false
    strategy: node-first
  uuid: 8f1f4e4a-9c43-4a51-b0ab-718482aad522

1.packerインストール

今回先述のLaunchJobを含めて3つのJobを作ったのだがこれが2つ目になる。
内容としては前回packerのインストールとして記載した手順そのままである。
正直この辺りはRundeckのLaunch時に含めてしまえばいいのだが今回の記事をJobだけで説明したいので作った。
image.png

Job自体の定義は以下

1.packerインストール
- defaultTab: output
  description: packerをrundeckにインストールします。
  executionEnabled: true
  group: OS最新化グループ/インスタンス作成
  id: b9626365-435f-411e-9036-ace00f1765f1
  loglevel: INFO
  name: 1.packerインストール
  nodeFilterEditable: false
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - description: yum-utilsインストール
      exec: sudo yum install -y yum-utils
    - description: hashicorp.repoインストール
      exec: sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
    - description: packerインストール
      exec: sudo yum -y install packer
    keepgoing: false
    strategy: node-first
  uuid: b9626365-435f-411e-9036-ace00f1765f1

2.OS最新化(AlmaLinux9)

今回作成したJobの3つ目。
このJobが今回の肝である。
この後に少しstep毎の解説を入れようと思う。
image.png

Job自体の定義は以下

2.OS最新化(AlmaLinux9)
- defaultTab: output
  description: AlmaLinux9のAMIに初期設定とOSの最新化を行います。
  executionEnabled: true
  group: OS最新化グループ/インスタンス作成
  id: 2efa29d8-66a5-4176-9b93-20deb849b907
  loglevel: INFO
  name: 2.OS最新化(AlmaLinux9)
  nodeFilterEditable: false
  options:
  - description: packerが使用するAWSのアクセスキーを指定します。
    label: AWSACCESSKEY
    name: AWSACCESSKEY
    required: true
    secure: true
    value: AKIARMBDZBNOHKR7A4FA
    valueExposed: true
  - description: packerが使用するAWSのシークレットアクセスキーを指定します。
    label: AWSSECRETACCESSKEY
    name: AWSSECRETACCESSKEY
    required: true
    secure: true
    value: KCL7v0xnceY9m33JUhJN6p0JnsSYJzK/X8As5AXk
    valueExposed: true
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - description: /var/lib/rundeck/packer作成
      script: |-
        if [ -e /var/lib/rundeck/packer ]; then
            echo "Directory Exist"
        else
            mkdir /var/lib/rundeck/packer
        fi
    - description: Alma9用jsonファイル作成
      script: |
        cat << EOL > /var/lib/rundeck/packer/ami.json
        {
          "builders": [
            {
              "type": "amazon-ebs",
              "ami_name": "AlmaLinux9-{{isotime | clean_resource_name}}",
              "temporary_key_pair_type": "ed25519",
              "access_key": "@option.AWSACCESSKEY@",
              "secret_key": "@option.AWSSECRETACCESSKEY@",
              "region": "ap-northeast-1",
              "source_ami": "ami-0c376282479945650",
              "instance_type": "t3.micro",
              "vpc_id": "vpc-093046de5a854c9c5",
              "ssh_username": "ec2-user",
              "security_group_ids": [
                "sg-03179fefab86413aa"
              ],
              "subnet_id": "subnet-095c2be997f1ffc36",
              "associate_public_ip_address": true
            }
          ],
              "provisioners": [
          {
              "type": "shell",
              "inline": [
              "sudo update-crypto-policies --set DEFAULT:SHA1",
              "sudo su -c\"echo PubkeyAcceptedAlgorithms=+ssh-rsa >> /etc/ssh/sshd_config\"",
              "sudo sed -i \"s/=enforcing/=disabled/\" /etc/selinux/config",
              "sudo dnf update -y"
               ]
          }
         ]
        }
        EOL
    - description: AMIイメージ作成
      exec: packer build /var/lib/rundeck/packer/ami.json
      plugins:
        LogFilter:
        - config:
            invalidKeyPattern: \s|\$|\{|\}|\\
            logData: 'false'
            name: lastami
            regex: '^ap-northeast-1: (.+)$'
          type: key-value-data
    - description: AMI用ディレクトリ作成
      script: |-
        if [ -e /var/lib/rundeck/ami ]; then
            echo "Directory Exist"
        else
            mkdir /var/lib/rundeck/ami
        fi
    - description: 初回実行用
      exec: touch /var/lib/rundeck/ami/alma9_last
    - description: 過去分アーカイブ
      exec: mv /var/lib/rundeck/ami/alma9_last /var/lib/rundeck/ami/alma9_`date +%Y%m%d%H%M%S`
    - description: AMI最新化
      exec: echo ${data.lastami} > '/var/lib/rundeck/ami/alma9_last
    keepgoing: false
    strategy: node-first
  uuid: 2efa29d8-66a5-4176-9b93-20deb849b907

ステップ1 /var/lib/rundeck/packer作成

前回記載していなかったがpackerはvalidate時などに結構ファイルを作ったりする。
今回Jobにするにあたって管理上専用のディレクトリを設けたほうがよさそうだったので入れておいた。
そこ!「validateしてないじゃん」とか突っ込んではいけない!

ステップ2 Alma9用jsonファイル作成

ここが要点になる。
内容としては前回と一緒だが実行するコマンドの最後にdnf update -yを入れている。
(当たり前だが)これを入れる事でOS(pkg)の状態がその時点での最新になる。
運用の現場でもやっているところはやっているがなんだかんだ忘れがちなところ。
ここにいれておけば新規サーバ立ち上げ時に意識しなくても最新の状態で上がってくれる。

ステップ3 AMIイメージ作成

これはコマンドそのまま。ステップ2の内容でAMIを作成する。
ただここは少し小技を使っている。
以前紹介したlogfilterというプラグインを使ってログ出力から出来上がったAMIのIDを変数にもらってきている。

ステップ4 AMI用ディレクトリ作成

ステップ5 初回実行用

(ステップ4と5でセット)
ここはすごく悩んだ箇所。
当初はAMIを作成したあとほかのJobのOptionを直接書き換えてしまえばいいとおもっていた。
だが直接書き換えたところ書き換えた内容がRundeckの画面で反映されなかった。
そううまく行かせてはもらえないらしい。
仕方ないので下策っぽいがファイルに書き出す形に路線変更している。
とりあえず目的は達成できるので問題はないがこういった場合Runeckではどうするのがよいのか引き続き検討したい。

ステップ6 過去分アーカイブ

ステップ7 AMI最新化

(ステップ6と7でセット)
やりたいことはステップ7だけなのだが往々にして不測の事態は起こるものなのである程度履歴を保持できるようにした。
AMI用ディレクトリをlsするようなJobでも作っておけば過去のAMIIDを確認しつつ使いたいAMIを指定できる。
そのJobも作ってある。(4個目)
image.png

Job自体の定義は以下

amiid確認
- defaultTab: nodes
  description: ''
  executionEnabled: true
  id: 940c3365-49ee-4f66-9fa1-8e3bfe820744
  loglevel: INFO
  name: amiid確認
  nodeFilterEditable: false
  nodefilters:
    dispatch:
      excludePrecedence: true
      keepgoing: false
      rankOrder: ascending
      successOnEmptyNodeFilter: false
      threadcount: '1'
    filter: 'name: Rundeck'
  nodesSelectedByDefault: true
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - exec: sudo "ls -l /var/lib/rundeck/ami |awk '{print $9}'"
    keepgoing: false
    strategy: node-first
  uuid: 940c3365-49ee-4f66-9fa1-8e3bfe820744
こういうJobをさらっと作れるのがRundeckのいいところだと思っている。

まとめ

あとはこの2.OS最新化(AlmaLinux9)を一週間なり1カ月の頻度でスケジュールしておけば自動でOSの各種アップデートに対応してくれる。
そしてインスタンスを作る側はJobが勝手に最新版を使ってくれるので意識せずに最新のバージョンを使用することができる。
また、最新版で動かない場合は自分で確認して動くバージョンを使ってLaunchできるのでこちらの手がかからない。
大変よい仕組みができた。(使いどころは知らないが)

あとがき

うむ、大変良い仕組みである。
Almalinux9単体では意味がなくpacker単体でも意味がなくRundeck単体でも意味はない。
3つが合わさることでよい仕組みができた。大変満足。
ちなみにjsonファイルを増やせばほかのOSにも適用できるので汎用性も高い。

ただ今回久しぶりにRundeckを触ったらCentos8のリポジトリ使えなくなってるし他も色々動かなくなっていて散々だった。
今後しばらくはAlmalinux9用に作り直しがてら細かい解説記事をちょくちょく書いていく生活をしようとおもう。
とにかく記事が少ないので自分で作らねば。
なお、繰り返しになるが私はRundeckの回し者ではない。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?