Emacsで CloudFormationテンプレートを書くということ

2019.10.27

VSCode には CloudFormation(CFn)テンプレートを書くための便利な拡張機能 があります。

基本的に CFnテンプレートを書くときはこれを使えばいいと思います。

(完)

…ですが、どうしても Emacsを使いたい人向けに

  • Emacsで CFnテンプレートを書く方法を 2つほど
  • あると便利な拡張

を書いていこうと思います。 ※ CFnテンプレートの形式は YAML を想定

目次

  1. 方法1: yaml-mode
  2. 方法2: org-mode
  3. (参考) あると便利な拡張
  4. おわりに

方法1: yaml-mode

素直に YAMLファイルを yaml-mode で書く方法です。 M-x package-install yaml-mode で取得できます。

後述の (参考) あると便利な拡張 に書いた各パッケージを入れて、 補完機能やシンタックスチェック機能など充実させていくとよいかと思います。以上!

方法2: org-mode

Emacs から離れられない理由の 1つに org-mode がありますよね。 org-mode 上で CFnテンプレートを編集・管理する方法 を考察してみます。

2-1. 素直に書く

コードブロック (#+BEGIN_SRC#+END_SRC) 内に CFnテンプレートを書きます。

コードブロックに書いているオプションは下記の通り

  • yaml … 言語に yamlを指定
  • :tangle $filepath … コードブロックの内容を $filepath に出力します

コードの出力は C-c C-v t (org-babel-tangle) で行います。 (※ tangle は文芸的プログラミングの用語、コードの出力の意味)

yaml の編集は org-buffer 内で行えますが、 後述する シンタックスチェック 機能の恩恵などを受けたい場合は コードブロック内で C-c ' (org-edit-special) を実行します。yaml-mode で編集ができます。

わざわざ org-buffer 上で CFnテンプレートを書くメリット は何でしょうか。

▼ 複数の CFnテンプレートを 1 bufferで管理できる

上図みたいに管理できます。 CFnテンプレートは行数が多くなりがち ですがコードブロックは折り畳めるので、 複数の CFnテンプレートが絡むシステム全体を俯瞰できます。 必要に応じて エクスポート値などをメモ書きすると、管理が楽になるかもしれません。

▼ 1 bufferで設計書にもなり、コードにもなる

文芸的プログラミング(wiki) らしく CFnテンプレートを編集・管理できます。

org-buffer で構築する AWSシステムの設計書を記述し、 設計書に従って CFnテンプレートを作成します。 作成した設計書、テンプレートは それぞれ別のコマンドで出力 できます。

2-2. noweb 機能も使う

noweb(wiki)文芸的プログラミングで使用するツール:noweb yes オプションで以下のような <<>> を使った記述ができるようになります。 (詳細の使用方法は orgmode: Noweb-reference 参照)

CFnテンプレート作成で nowebを使ってみましょう。 以下は リソース単位で 分けた例です。

メインの yamlコード内の <<sample-xxx>> は それ以降の yamlコードを参照しています。 各リソースの yamlコードには リソースの Type,Properties を書いていきます。

▼ noweb機能を使うメリット

長くなりがちな YAMLファイルの全体を俯瞰 できます (そもそも yaml-mode でコードの折りたたみ・展開ができれば良い話ですが)。

また、 深くなりがちなインデントの煩わしさから解放 されます。 上で示した noweb使用例の場合、リソースの Type,Properties 記述は 全体のインデント無しで書けます。

▼ noweb機能を使うデメリット

文芸的プログラミングの特徴かもしれませんが 管理が大変です。 nowebを使うインデントレベル、コードブロックの命名規則は予め自分で ルールを作成したほうが良いです。

(参考) あると便利な拡張

テンプレート機能: yasnippet

YASnippetEmacs用のテンプレートシステム です。 キーワードを入力するだけで長いテンプレート(スニペット) の挿入が可能です。

自分でテンプレートを作成することももちろん可能ですが、 YASnippet#where-are-the-snippets にあるように、有志で用意されたスニペット集を使用することもできます。

私は yasnippet-snippets をインストールしています。 例えば python-mode上で

  • p[TAB]print()
  • r[TAB]return
  • utf8# -*- coding: utf-8 -*-

といった挿入ができるようになります。

CFnの場合、 よく使うリソースのスニペット を作成すると良いでしょう。 (探してみると Andreas Gerler氏による aws-snippets といったものがあったりします)

補完機能: company

company-mode は Emacsに補完機能を提供します。

(画像: http://company-mode.github.io/ より引用)

CFnテンプレート作成において !Ref xxx といった、 前に定義したリソースを参照 するケースが多いです。 そういった場合に company-mode の補完機能が役に立ちます。

comany-mode の細かい設定項目については Taiju Aokiさんの記事(Qiita) が参考になります。

シンタックスチェック: flycheck + cfn-lint

CFnテンプレート のシンタックスチェックには flycheck + Cfn Lint で可能です。

flycheck は リアルタイムにシンタックスチェックを行う ためのツールです。 M-x package-install flycheck でインストール、有効化しましょう。

その後、CFnテンプレートのシンタックスチェックのためのプログラムを pip install cfn-lint でインストールします。

あとは Cfn Lint: emacswiki の設定を init.el に記載すれば完了です。 タイポなど指摘してくれます。

(画像: https://www.emacswiki.org/emacs/CfnLint より引用)

おわりに

以上、Emacsで CFnテンプレートを書く方法についてつらつらと書いてみました。

私は 全てを org-mode で管理したい 人なので org-mode (noweb)を使った テンプレート作成を進めていこうと思います。