YAMLのエイリアスでAnsibleファイルの重複を減らす
渡辺です。
あまり知られていないかもしれませんが、YAMLでは標準機能としてアンカーとエイリアスがあります。 Ansibleでも利用できるため、構成管理を行う場合に役立つので紹介したいと思います。
冗長化した値を一括管理する
例として、EC2インスタンスを定義したグループ変数があるとしましょう。
ec2: - name: FrontWebA instance_type: t2.small image: ami-1a15c77b instance_profile_name: web key_name: dev_key subnet_name: FrontA group: - Internal - Mainte root_volume_size: 8 assign_public_ip: false - name: FrontWebC instance_type: t2.small image: ami-1a15c77b instance_profile_name: web key_name: dev_key subnet_name: FrontC group: - Internal - Mainte root_volume_size: 8 assign_public_ip: false
異なるAZに冗長化したインスタンスを作るのであれば、必然的に重複個所が多くなります。
重複は悪です。 重複個所があると、変更時に複数個所を変更しなければならなくなり、置換時のミスから不具合を混入させやすくなります。 かといって、可読性が犠牲になるようなグループ変数の構造変更は避けなければなりません。
エイリアスで値を参照する
このようなケースで有効なのがエイリアスとアンカーです。
YAMLでは、&名称
でアンカーを定義し、アンカーの値を*名称
でエイリアスとして参照できます。
具体的にみてみましょう。
ec2: - name: FrontWebA instance_type: t2.small image: &amazon_linux ami-1a15c77b instance_profile_name: web key_name: dev_key subnet_name: FrontA group: - Internal - Mainte root_volume_size: 8 assign_public_ip: false - name: FrontWebC instance_type: t2.small image: *amazon_linux instance_profile_name: web key_name: dev_key subnet_name: FrontC group: - Internal - Mainte root_volume_size: 8 assign_public_ip: false
ここでは、AmazonLinuxのイメージIDのアンカー(&amazon_linux
)を定義し、重複して出現する個所をエイリアス(*amazon_linux
)で参照しています。
このようにアンカーとエイリアスを利用すれば、AmazonLinuxの最新版がリリースされた場合でも、イメージIDの変更個所は1個所で済みます。
エイリアスでデータ構造を参照する
YAMLのエイリアスでは、値だけではなくリストなどのデータ構造ごと参照することができます。
ec2: - name: FrontWebA instance_type: t2.small image: &amazon_linux ami-1a15c77b instance_profile_name: web key_name: dev_key subnet_name: FrontA group: &front_group - Internal - Mainte root_volume_size: 8 assign_public_ip: false - name: FrontWebC instance_type: t2.small image: *amazon_linux instance_profile_name: web key_name: dev_key subnet_name: FrontC group: *front_group root_volume_size: 8 assign_public_ip: false
共通部分をマージする
<<:
を使うとエイリアスで定義した個所をデータ構造にマージすることができます。
これは似た構造を持ったデータが多く出現する場合には便利です。
ec2_front: &ec2_front instance_type: t2.small image: ami-1a15c77b instance_profile_name: web key_name: dev_key group: - Internal - Mainte root_volume_size: 8 assign_public_ip: false ec2: - name: FrontWebA subnet_name: FrontA <<: *ec2_front - name: FrontWebC subnet_name: FrontC <<: *ec2_front
記述量は減りましたが、直感的ではなくなりました。
まとめ
Ansible PlaybookのフォーマットであるYAMLのエイリアス機能は値だけでなくデータ構造も参照できるため、設定ファイルから重複を減らすことに役立ちます。 共通部分が多い場合は、さらにマージ機能を利用することで、重複はほとんどなくなってくるでしょう。
ただし、可読性を高めるために利用する機能です。 マージを多用しすぎて読みにくくなったら本末転倒なので、用法と用量を守ってご利用ください。