Azure Blob Storage を使った Static website を GitHub Actions でデプロイする

はじめに

しばらく前に作った以下のレジュメサイトの DevOps を Travis CI から GitHub Actions に引っ越した。

cv.kheiakiyama.com

理由としては GitHub Actions を実用したかったためだ。

GitHub Actions のバックエンドが Azure Pipelines の fork 版

新 GitHub Actions 入門 - 生産性向上ブログ

と聞いていた背景と、普段 Azure Pipelines を利用している立場からも GitHub Actions との違いを知りたかった。

Travis CI で構成したときの記事は以下。
kheiakiyama.hateblo.jp

GitHub Actions のドキュメント

ドキュメントは日本語で用意されている。

help.github.com

ただ、Azure Pipelines を知っているせいか、「Artifact」 が「成果物」となっているなど、違和感が多々あり、英語のドキュメントを読むほうがしっくりくるかもしれない。

help.github.com

それにしても Azure Pipelines のドキュメントは英語のみなのに GitHub Actions は違うんですね。。

↓ Azure Pipelines のドキュメント
Azure Pipelines documentation | Microsoft Docs

GitHub Actions での実装

現物は GitHub 上のリンク を参照してもらうとして、定義ファイルの yaml に解説を追記しておく。

name: "release"
on: # rebuild master branch changes
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2 # 利用する GitHub Actions を ダウンロードするための処理
    - uses: actions/setup-ruby@v1 # jekyll で使う ruby のインストール用 GitHub Action
      with:
        ruby-version: 2.5
    - name: Set up bundler
      run: gem install bundler
    - name: nokogiri dependencies # bundle install で nokogiri を正しくインストールするための依存ライブラリのインストール
      run: |
        sudo apt-get update
        sudo apt-get install libxml2 libxslt1-dev
    - name: jekyll build
      run: |
        bundle install --jobs 4
        ./scripts/cibuild
      env:
        NOKOGIRI_USE_SYSTEM_LIBRARIES: false
    - name: Upload jekyll output # Azure DevOps ではおなじみの Artifact にアップロード、次の Job に受け渡す
      uses: actions/upload-artifact@v1
      with:
        name: jekyll
        path: './_site'

  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
    - uses: actions/checkout@v2
    - uses: kheiakiyama/install-azcopy-action@v1 # azcopy のインストール。詳細は別記事で。
      with: 
        version: 'v10'
    - name: Download jekyll output # build job でアップロードした Artifact をダウンロード。 name と同名の path にダウンロードされる
      uses: actions/download-artifact@v1
      with:
        name: jekyll
    - name: azcopy upload jekyll content # azcopy で Blob Storage にコンテンツをアップロード
      run: |
        azcopy --version | grep 'azcopy'
        azcopy --source ./jekyll --destination "$BLOB_CONTAINER_URL" --dest-key ${{ secrets.STORAGE_KEY }} --recursive --quiet --set-content-type
      env:
        BLOB_CONTAINER_URL: 'https://kheiakiyama.blob.core.windows.net/$web'
    - uses: azure/login@v1 # Azure CDN のパージのために azcli でログイン
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}
    - name: Azure CLI script # Azure CDN パージ
      uses: azure/CLI@v1
      with:
        inlineScript: |
          az cdn endpoint purge -g kheiakiyama.com --profile-name kheiakiyama-cdn -n cv-kheiakiyama --content-paths '/*'

Travis CI の頃からこのリポジトリは public なのだが、GitHub Actions の実行ログにしてもシークレットは見えないので、特に問題ではない。
(Azure Resource の名前は見せているが、まあ特に問題ないかと)

感想

Azure DevOps の fork というのには納得で、Multi staging build の Azure Pipelines とほぼ同じ使い勝手だった。
Azure Pipelines でいうところの Task は GitHub Actions ではまだ充実していないところがあるという感じ。
Azure 関係の GitHub Actions は結構数がある様子。

GitHub Marketplace · Actions to improve your workflow · GitHub

開発者が 3rd Party の Actions を作れるので、今後 GitHub Actions がどの程度充実していって Azure Pipelines と差がついていくのかを見守っていきたい。

DMM英会話の予約メールから自動的にカレンダー予約(2019/9/3改訂版対応)

追記

2021/1/5 時点で利用可能なことを確認済み

背景・問題

DMM 英会話を使い始めて9ヶ月近くになる。
DMM 英会話ではレッスンを登録すると、その日時が書かれたメールが届く。
スケジュール管理の都合上、以下の記事を参考に Google カレンダーに自動登録するハックを利用していた。

blog.shotarok.com

しかし、2019/09/03 に予約メールが重複して届くようになり、翌 09/04 には新しいフォーマットのメールのみ届くようになってしまった。

以前のメールフォーマットに依存していたため、これまでのハックが使えなくなってしまった。

原因

システム改訂にともなうフォーマット変更だと思われる。

2019/09/03 までのメール

  • タイトル「【DMM英会話】レッスン予約完了のお知らせ」
  • 送信元 no-reply@eikaiwa.dmm.com

2019/09/03 から後のメール

  • タイトル「レッスン予約」
  • 送信元 noreply@eikaiwa.dmm.com

解決策

Google Apps Script を少し修正した。

DMMEnglish.gs だけ修正すれば問題ないはず。
レッスン5分前あたりにリマインドメールが届くのだが、自分の場合はメール見てないのでこれも開封したことにしている。

function DMMEnglish() {
  var criteria = "from:noreply@eikaiwa.dmm.com レッスン予約";
  eachUnreadMessage(criteria, function (message) {
    var body = message.getBody();
    var [matched, year, month, day, sh, sm] = /様、(\d+)\/(\d\d)\/(\d\d)\s(\d\d):(\d\d)/.exec(body);
    var sdate = new Date(year, month-1, day, sh, sm);
    var edate = new Date(sdate.getTime() + 30 * 60000);
    createEvent("DMM英会話", sdate, edate, "https://eikaiwa.dmm.com/book/book_list/");
  });
  // レッスン前のリマインドメールも開く
  criteria = "from:noreply@eikaiwa.dmm.com レッスンのお知らせ";
  eachUnreadMessage(criteria, function (message) {
    //開くだけ
  });
}

ほかの設定はさきのブログ記事に準じたままなので、このスクリプトだけ直せばOK。

CentOS で Microsoft SQL Server Command Line Client を使いたいときの Docker Image

公式で用意された Docker ImageUbuntu 16.04 ベースになっており、CentOS で使いたかったので書いた。

Docker Hub

Docker Hub - kheiakiyama/centos7-mssql-tools

GitHub

GitHub - kheiakiyama/centos7-mssql-tools: Unofficial images for Microsoft SQL Server Command Line Tools (sqlcmd/bcp) on CentOS7

つくりかた

Linux 環境での利用方法は以下のドキュメントにあるので、それを Dockerfile におこすだけ。

docs.microsoft.com

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

プログラマのためのDocker教科書 第2版 インフラの基礎知識&コードによる環境構築の自動化

Surface Book あるいはノートPCに貼ったシールをいい感じに剥がす

ITエンジニアが宗教アピールのために貼っているシール。
リファクタリングしたくなったので剥がすことにした。

準備したもの

手順

  1. 換気大事。窓を開ける
  2. シール剥がしスプレーを吹き付ける
  3. シールを剥がす
  4. 液が溜まったところをヘラをかけて糊のダマを追いやり、キッチンペーパーで拭き取る
  5. スプレー、ヘラ、キッチンペーパーを何度か繰り返す
  6. ダマが減ってきたら消しゴムをかけて、消しカスがつくところを入念にかける
  7. もう一度スプレー、ヘラ、キッチンペーパーとハンカチ
  8. ウェットティッシュで仕上げ

終わりに

Surface Book がプラスチック素材のようなので、影響ないか心配だったがどうにかなってよかった。
写真は撮るのを忘れた。
1個剥がすのもわりと面倒なので、多神教はあまりよくない。

Fire TV が HDMI 出力を専有するときの回避策として Alexa 連携を使う

背景・課題

自宅では大型ディスプレイに Fire TV、PS4Nintendo Switch、たまに PC を接続している。
その中で Fire TV がスリープしている間(スクリーンセーバーではない)に HDMI 出力が残り、たとえば Switch を起動したときも Fire TV が優先されてしまい、スムーズにゲームで遊べない、という問題があった。

回避策1

簡単な回避策として、Fire TV の電源をサクッと落とせる電源タップを使った。

しかし、イチイチ電源を落とすのが煩わしかった。

回避策2

ここが本題。
Alexa と連携して電源コントロールできる TP-LINK の HS105 という製品を利用した。

これによって発話で Fire TV の電源を入れたり切ったりできるようになった。

TP-LINK HS105 セットアップ

ここの手順は購入した際についてくる説明書のとおりなので割愛。
バイス名は発話しやすい名前にしておくのが無難。
f:id:khei-fuji:20180513210800p:plain

セットアップが完了した時点で iPhone アプリから電源のオン/オフが可能になる。

Alexa の設定 - デバイス

まずは Alexa にスマートホーム製品として TP-LINK HS105 を認識させる必要がある。
この手順はデバイスの公式 HP が分かりやすい。

Amazon AlexaにTP-Linkスマートホーム機器を接続するには - TP-Link

これによってスマートホームのデバイスに、Kasa で設定したデバイス名が表示される。

f:id:khei-fuji:20180513210804p:plain

バイス名が気に入らなかった場合は、Kasa で名前を設定し直し、Alexa に「デバイスを検出して」と発話すれば再度情報を更新してくれる。

Alexa の設定 - 定型アクション

個別デバイスの操作ができれば十分かもしれないが、ここは好みで。
自分の場合は「おはよう」で Fire TV をオンに、「おやすみ」で Fire TV をオフにしたかったので、定型アクションを設定した。

Amazon.co.jp ヘルプ - スマートホーム製品の定型アクションを作成する

おわりに

AbemaTV を朝晩観るのが日課です。

AbemaTV

AbemaTV

  • 株式会社AbemaTV
  • エンターテインメント
  • 無料

CentOS に ansible で mackerel-agent を雑にインストールする

先日 Raspberry Pi 2 に mackerel-agent をインストールしたので、ついでに CentOS 環境にもインストールした。

kheiakiyama.hateblo.jp

mackerel.io


CentOS

以下、プレイブック

---
- name: install mackerel-agent repo
  shell: |
    curl -fsSL https://mackerel.io/assets/files/scripts/setup-yum.sh | sh
  args:
    creates: /etc/mackerel-agent/mackerel-agent.conf

- name: install mackerel-agent
  yum: name=mackerel-agent state=latest

- name: mackerel-agent conf
  lineinfile: 
    dest=/etc/mackerel-agent/mackerel-agent.conf
    line='{{ item.line }}'
    regexp='{{ item.regexp }}'
  with_items:
    - { line: 'apikey="{{ mackerel_apikey }}"', regexp: '^apikey="{{ mackerel_apikey }}"' }
  notify: restart mackerel-agent

mackerel-agent の yum リポジトリの登録を /etc/mackerel-agent/mackerel-agent.conf でチェックするというのはいささか雑だが、雑にインストールする と断りを入れているのでよしとした。

Ansible徹底入門 クラウド時代の新しい構成管理の実現

Ansible徹底入門 クラウド時代の新しい構成管理の実現

自宅の温度湿度を RaspberryPi2 でログ取り始めた

はじめに

自分のコンテキストを書いておく。
電子工作経験はほぼなし。
10年前、パトランプのXFD体験イベントに参加した先輩からデバイス完成品を譲ってもらったレベル。
たぶんそのイベントはこのへん
電子工作のウデマエは1といって差し支えないだろう。

準備

買ったものは以下のとおり

f:id:khei-fuji:20151225205944j:plain

結果

ログはこんな感じで確認できる。

f:id:khei-fuji:20160104145918p:plain

それぞれ温度と湿度。

サーバー代を惜しんで RaspberryPi2 内にログを残している。
そのためログは自宅内でしか確認できない。


RaspberryPi はリビングの一角に設置している。

f:id:khei-fuji:20160103094625j:plain

手前に向かって生えているのがDHT22センサー。

手順

ざっくり以下のように行った。
詳細は後述。

  • 初期設定
  • センサー(DHT22/AM2302)取り付け
  • 温度湿度データ取得テスト
  • ログ保存
  • ログ取得

初期設定

ローカライズ

locale やタイムゾーンなどを日本に変更。
このあたりを参考に。
Raspberry Pi 2の文字コードを変更する(日本語の設定) - wide_snow’s blog

ネットワーク

巷では無線LANの事例が多いが、ケチって RaspberryPi2 は有線LANで利用する。

スターターキットでは etc/network/interfacesdhcp ではなく manual に設定されていたため、自分で一度 dhcp に変更した。
その際は問題が起きたが以下の記事によって解決した。
linux - DHCP failure when rebooting RPI 2 - Super User

その後static に変更して終わり。
Raspberry Pi 2 IPアドレスを固定(有線LAN)にする - カタカタブログ

センサー(DHT22/AM2302)取り付け

ケーブルなどを細かく買うのが煩わしかったので、買ったのはモジュール化済みの DHT22。

f:id:khei-fuji:20160102142450j:plain

DHT22や互換性があるDHT11の情報はググれば多い。
が、モジュール化されたものの情報は見つからず、どう接続したらいいかわからなかった。
そこで基本をおさえることに。
下記サイトが大変わかりやすかった。

Raspberry Piで電子工作!Lチカ…の前にLピカ! | Device Plus - デバプラ


RaspberryPi のような機器では大きく分けて3つの接続先が用意されている。
電源、アース、入出力だ。
モジュールの + は電源、- はアース、out は出力、ということでそれぞれ 1, 9, 7 に接続した。

温度湿度データ取得テスト

GitHub に公開されているスクリプトを使ってテストする。

adafruit/Adafruit_Python_DHT · GitHub

サンプルのスクリプト example/AdafruitDHT.py を実行すると以下の結果が得られた。

Temp=20.3*  Humidity=37.3%

このスクリプトは以下サイトから知った。
Raspberry pi + pubnub で温度と湿度のリアルタイムグラフ表示 | ネットワークエンジニアを目指して - ブログ

このスクリプトを後で流用する。

ログ保存

GrowthForecast を使ってログの蓄積・可視化を行っている。

導入はこのへんを参考にすれば大体解決。


GrowthForecast の起動スクリプトは雑だが下のような形に落ち着いた。

世の中の記事を見ると GrowthForecast が小数対応する前の情報が多いが、今なら --enable-float-number オプションで小数が使える。


このスクリプトSupervisor に呼び出してもらう。

Supervisor の導入についてはこちらを参考。

GrowthForecast を CentOS 6.3 にインストールして Supervisor で管理する - 彼女からは、おいちゃんと呼ばれています

ログ取得

データ蓄積は、前述の example/AdafruitDHT.py を真似たスクリプトを cron で実行し、結果を GrowthForecast に投げることで解決する。


Adatemp.py 22 4 の 22 は DHT22、4 は RaspberryPi の7番が GPIO 4 なのでそれを指定している。
ここで実行している Adatemp.pyAdahumit.py は、AdafruitDHT.pycp してつくったスクリプト
それぞれファイルの最後から2番目の print を以下のように書き換える。

print '{0:0.1f}'.format(temperature)
print '{0:0.1f}'.format(humidity)

あとは作成したスクリプトを cron で実行すればいい。

最後に

ここまでの作業はすべて1日以内で完了した。
連休でちょっと試してみるにはほどよい作業量だと思う。
これが1万円でできるなんてすごい世の中になったものだと実感。

今後やってみたいこと。

  • どうせなら屋外にも設置する
  • 定期的に自分にプッシュ通知する


興味を持った方は下から購入してもらえると嬉しい。


Raspberry Piスターターパック (Pi2 用Standard)

Raspberry Piスターターパック (Pi2 用Standard)