[Terraform]EC2 Linux作成時のユーザデータにfile関数を使用する

EC2 Linux作成時のユーザデータは、Terraformだとfile関数を使用すると楽に書けますよ!
2021.11.14

こんにちは!コンサル部のinomaso(@inomasosan)です。

TerraformでEC2 Linux作成時のユーザデータに、ヒアドキュメント以外を使用したかったので調べてみました。

まずは結論から

file関数を使用することで、別ファイルに作成した内容を読み取ることができます。
ちなみにtemplate_fileData Sourceでも記述可能ですが、file関数と比較するとコードが長くなってしまいます。

ヒアドキュメントじゃだめなの?

短い内容であれば以下のようにヒアドキュメントで記述してもいいのですが、長いコードの場合はファイルを分けたいところです。

resource "aws_instance" "ec2" {
  ...中略...
  user_data = <<EOF
    #!/bin/bash
    yum update -y

    ## Apache Setup
    yum install -y httpd
    chown -R apache:apache /var/www/html
    systemctl start httpd
    systemctl enable httpd

    EOF
}

検証環境

今回実行した環境は以下の通りです。

項目 バージョン
macOS BigSur 11.6
Terraform 1.0.7
AWSプロバイダー 3.65.0

Terraformコード

今回はEC2 LinuxのユーザデータでApacheセットアップを検証しました。

aws_ec2.tf

resource "aws_instance" "ec2" {
  ## AmazonLinux2
  ami = "ami-0e60b6d05dc38ff11"
  ...中略...
  user_data = file("script.sh")
}

script.sh

#!/bin/bash
yum update -y

## Apache Setup
yum install -y httpd
chown -R apache:apache /var/www/html
systemctl start httpd
systemctl enable httpd

ユーザデータの結果確認

ユーザデータの結果は/var/log/cloud-init-output.logから確認できます。
後半にApacheセットアップのログがありました。

$ sudo cat /var/log/cloud-init-output.log
...中略...
Cloud-init v. 19.3-44.amzn2 running 'modules:final' at Sat, 13 Nov 2021 16:36:48 +0000. Up 19.13 seconds.
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
No packages marked for update
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.51-1.amzn2 will be installed
--> Processing Dependency: httpd-tools = 2.4.51-1.amzn2 for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: httpd-filesystem = 2.4.51-1.amzn2 for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: system-logos-httpd for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: mod_http2 for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: httpd-filesystem for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.51-1.amzn2.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.51-1.amzn2.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.7.0-9.amzn2 will be installed
---> Package apr-util.x86_64 0:1.6.1-5.amzn2.0.2 will be installed
--> Processing Dependency: apr-util-bdb(x86-64) = 1.6.1-5.amzn2.0.2 for package: apr-util-1.6.1-5.amzn2.0.2.x86_64
---> Package generic-logos-httpd.noarch 0:18.0.0-4.amzn2 will be installed
---> Package httpd-filesystem.noarch 0:2.4.51-1.amzn2 will be installed
---> Package httpd-tools.x86_64 0:2.4.51-1.amzn2 will be installed
---> Package mailcap.noarch 0:2.1.41-2.amzn2 will be installed
---> Package mod_http2.x86_64 0:1.15.19-1.amzn2.0.1 will be installed
--> Running transaction check
---> Package apr-util-bdb.x86_64 0:1.6.1-5.amzn2.0.2 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package                Arch      Version                   Repository     Size
================================================================================
Installing:
 httpd                  x86_64    2.4.51-1.amzn2            amzn2-core    1.3 M
Installing for dependencies:
 apr                    x86_64    1.7.0-9.amzn2             amzn2-core    122 k
 apr-util               x86_64    1.6.1-5.amzn2.0.2         amzn2-core     99 k
 apr-util-bdb           x86_64    1.6.1-5.amzn2.0.2         amzn2-core     19 k
 generic-logos-httpd    noarch    18.0.0-4.amzn2            amzn2-core     19 k
 httpd-filesystem       noarch    2.4.51-1.amzn2            amzn2-core     24 k
 httpd-tools            x86_64    2.4.51-1.amzn2            amzn2-core     88 k
 mailcap                noarch    2.1.41-2.amzn2            amzn2-core     31 k
 mod_http2              x86_64    1.15.19-1.amzn2.0.1       amzn2-core    149 k

Transaction Summary
================================================================================
Install  1 Package (+8 Dependent packages)

Total download size: 1.9 M
Installed size: 5.2 M
Downloading packages:
--------------------------------------------------------------------------------
Total                                              9.3 MB/s | 1.9 MB  00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : apr-1.7.0-9.amzn2.x86_64                                     1/9
  Installing : apr-util-bdb-1.6.1-5.amzn2.0.2.x86_64                        2/9
  Installing : apr-util-1.6.1-5.amzn2.0.2.x86_64                            3/9
  Installing : httpd-tools-2.4.51-1.amzn2.x86_64                            4/9
  Installing : generic-logos-httpd-18.0.0-4.amzn2.noarch                    5/9
  Installing : mailcap-2.1.41-2.amzn2.noarch                                6/9
  Installing : httpd-filesystem-2.4.51-1.amzn2.noarch                       7/9
  Installing : mod_http2-1.15.19-1.amzn2.0.1.x86_64                         8/9
  Installing : httpd-2.4.51-1.amzn2.x86_64                                  9/9
  Verifying  : apr-util-1.6.1-5.amzn2.0.2.x86_64                            1/9
  Verifying  : httpd-2.4.51-1.amzn2.x86_64                                  2/9
  Verifying  : apr-util-bdb-1.6.1-5.amzn2.0.2.x86_64                        3/9
  Verifying  : httpd-filesystem-2.4.51-1.amzn2.noarch                       4/9
  Verifying  : apr-1.7.0-9.amzn2.x86_64                                     5/9
  Verifying  : mailcap-2.1.41-2.amzn2.noarch                                6/9
  Verifying  : generic-logos-httpd-18.0.0-4.amzn2.noarch                    7/9
  Verifying  : mod_http2-1.15.19-1.amzn2.0.1.x86_64                         8/9
  Verifying  : httpd-tools-2.4.51-1.amzn2.x86_64                            9/9

Installed:
  httpd.x86_64 0:2.4.51-1.amzn2

Dependency Installed:
  apr.x86_64 0:1.7.0-9.amzn2
  apr-util.x86_64 0:1.6.1-5.amzn2.0.2
  apr-util-bdb.x86_64 0:1.6.1-5.amzn2.0.2
  generic-logos-httpd.noarch 0:18.0.0-4.amzn2
  httpd-filesystem.noarch 0:2.4.51-1.amzn2
  httpd-tools.x86_64 0:2.4.51-1.amzn2
  mailcap.noarch 0:2.1.41-2.amzn2
  mod_http2.x86_64 0:1.15.19-1.amzn2.0.1

Complete!
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
Cloud-init v. 19.3-44.amzn2 finished at Sat, 13 Nov 2021 16:36:52 +0000. Datasource DataSourceEc2.  Up 23.59 seconds

別ファイルに変数を渡したい場合はどうしたらいいの?

templatefile関数を使用すると、templatefile(path, vars)のワンライナーで記述可能です。

ちなみにtemplate_fileのData Sourceを使用した書き方

Terraformがv0.12未満の場合は、以下のように書く必要がありました。
file関数やtemplatefile関数と比較すると、複数ブロックを記述する必要があるので、どうしても冗長的に感じてしまいますね。

aws_ec2.tf

resource "aws_instance" "ec2" {
  ## AmazonLinux2
  ami = "ami-0e60b6d05dc38ff11"
  ...中略...
  user_data = data.template_file.script.rendered
}

data "template_file" "script" {
  template = file("script.sh")
    ## fileに変数を受け渡す場合は、varsを使用
  /*
  vars = {
    efs_id = aws_efs_file_system.efs.id
  }
  */
}

script.sh

#!/bin/bash
yum update -y

## Apache Setup
yum install -y httpd
chown -R apache:apache /var/www/html
systemctl start httpd
systemctl enable httpd

参考URL

まとめ

Terraformでの書き方を調べていた際は、最初に見つけたのがtemplate_fileの古い書き方だったので、この機会にfile関数やtemplatefile関数での楽な書き方もちゃんと理解できたので良かったです。

この記事が、どなたかのお役に立てば幸いです。それでは!