ytt を使ってYAMLのテンプレート化を初めてみた

みなさんYAMLってますか?画面にジョーギ当てたりしていますか?
私も最近YAMLを扱う機会が多くなってきて、修正するのが億劫になってきていたりしています。

今回は、YAMLをいろいろ操作できるっぽいという話を聞いたので、carveltoolsのyttを使ってみようと思います。

yttうんぬんは、ぐぐると日本語でもわかりやすく説明してくれている記事があるので、
ここではスルー。とにかく触ってみる。

## とにかく Playground で遊んでみよう

とにかく ytt を触って、どんな感じにYAMLを操作できるのかを試すには、以下、公式サイトのPlaygroundを触るのがとにかく手っ取り早いみたい。

Playground楽しいヨ ということさえ伝えられれば、この記事としてはもういいかなーと思っていたりする。

https://carvel.dev/ytt/#example:example-plain-yaml

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131643/4f3c85f0-be02-47fd-d38f-158499587fbe.png)

ここで触ってみよう。

## やりたいこと

私がやりたいことは、最近AWSのCloudformationのYAMLファイルを触ることが多くなったので、パラメータなどをyttを使って外出しにして、いい感じに管理できないかな? というのを試してみたいと思う。

が、はたして ytt で実現できるか?

## PlaygroundにCloudformationのYAMLを張り込んでみた
(使い方は色々あるのだろうけど) Plain yaml を参考に、
パラメータ用のファイルと、テンプレートになるファイルを作って、
値をはめ込んで見るようにした。

こんな関係になるみたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131643/cc703c81-ae52-ac08-2efc-3bd6b1f2b454.png)

なるほどなるほど。パラメータファイルだけ外出しにして、テンプレートにはめ込んで出力させることは、サクッとできそう!


### サンプル

```parameters.yml
#@data/values
---
Parameters:
  EnvironmentName:
    Default: "mebachiMaguro"

VpcCIDR: "10.0.0.0/16"
```

```vpc.yml
#@ load("@ytt:data", "data")

#@ def environmentNameDefault():
#@   return data.values.Parameters.EnvironmentName.Default
#@ end

#@ def vpcCIDR():
#@   return data.values.VpcCIDR
#@ end

AWSTemplateFormatVersion: "2010-09-09"
Description: VPC 2AZ public/private Subnet with IGW / AZ2 is Dummy AZ

Parameters:
  EnvironmentName:
    Description: Enter your Environment name
    Type: String
    Default: #@ environmentNameDefault()

  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: #@ vpcCIDR()

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-vpc

```

```iam.yaml
#@ load("@ytt:data", "data")

#@ def environmentNameDefault():
#@   return data.values.Parameters.EnvironmentName.Default
#@ end

#@ def vpcCIDR():
#@   return data.values.VpcCIDR
#@ end

AWSTemplateFormatVersion: "2010-09-09"
Description: Deploy EC2 Instance with SessionManager Settings

Parameters:
  EnvironmentName:
    Description: Enter your Environment name
    Type: String
    Default: #@ environmentNameDefault()

Resources:
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${EnvironmentName}-AllowSessionManager-Role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
```

## 手元で動かしてみよう

### ytt のインストール(Mac)
https://carvel.dev/ytt/docs/v0.40.0/install/#via-script-macos-or-linux
ここの内容を実施すればいいだけっぽい。

```bash
$ mkdir local-bin/
$ curl -L https://carvel.dev/install.sh | K14SIO_INSTALL_BIN_DIR=local-bin bash

$ export PATH=$PWD/local-bin/:$PATH
$ ytt version
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131643/45bedf21-d323-6624-76ae-c3e2bbb97932.png)
m1 Macでも素直にインストールできた。

### ファイルを準備
先程のYAMLはPlayground上で貼り付けていただけなので、
ファイルとして出力できないと、つらいので、コマンドラインから試してみる。

先程のYAMLをファイルとして配置して...


```bash
% ls -la
total 24
drwxr-xr-x   5 make0x0  staff   160 12 22 23:10 ./
drwxr-xr-x+ 57 make0x0  staff  1824 12 22 23:10 ../
-rw-r--r--   1 make0x0  staff   893 12 22 23:10 iam.yaml
-rw-r--r--   1 make0x0  staff   102 12 22 23:09 parameters.yml
-rw-r--r--   1 make0x0  staff   785 12 22 23:09 vpc.yml
```

### yttの出力コマンドを実行
```bash
% ytt -f ./ytt-sample --output-files ytt-output

creating: ytt-output/iam.yaml
creating: ytt-output/vpc.yml
```

### 出力結果を確認
```bash
make0x0 (arm64):~/ytt-output 
% ls    
iam.yaml* vpc.yml*
make0x0 (arm64):~/ytt-output 
% cat iam.yaml           
AWSTemplateFormatVersion: "2010-09-09"
Description: Deploy EC2 Instance with SessionManager Settings
Parameters:
  EnvironmentName:
    Description: Enter your Environment name
    Type: String
    Default: mebachiMaguro
Resources:
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ${EnvironmentName}-AllowSessionManager-Role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

make0x0 (arm64):~/ytt-output 
% cat vpc.yml 
AWSTemplateFormatVersion: "2010-09-09"
Description: VPC 2AZ public/private Subnet with IGW / AZ2 is Dummy AZ
Parameters:
  EnvironmentName:
    Description: Enter your Environment name
    Type: String
    Default: mebachiMaguro
  VpcCIDR:
    Description: Please enter the IP range (CIDR notation) for this VPC
    Type: String
    Default: 10.0.0.0/16
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
      - Key: Name
        Value: ${EnvironmentName}-vpc
```

おお! ちゃんとファイルとして出力してくれたぞ!

## まとめ

ということで、まともにドキュメント読まずしてもかんたんにテンプレート化して、出力を得られることがわかりました! かんたんだよ!

Playground のメニューを見るだけでも、リストを展開したりとか、If文とかできそうですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131643/b41a86c9-e800-4743-7355-173362af4b44.png)

ちゃんとドキュメント読んで、YAMLに強い人類になりたいと思います!