0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第22回 Terraform講座|Outputsで「作ったリソースの必要な情報」を取り出す

0
Posted at

Terraformの学習も、少しずつ「AWSリソースを作る」だけではなくなってきました。

前回は Variables を学びました。

Variablesでは、

«Terraformの外から設定値を渡す»

という考え方を学びました。

今回登場するのは、その反対側にある機能です。

それが、

Outputs

です。


今日の実務シナリオ

Terraformを実行したとします。

terraform apply

するとAWSには、

  • ALB
  • EC2
  • RDS
  • VPC

などが作成されました。

ところが……

👨‍💼 上司

«「ALBのURL教えて。」»

😨

「どこで見るんだ……?」

AWSコンソールを開いて、

EC2
↓
ALB
↓
DNS name

と探すこともできます。

でも、毎回これをやるのは面倒です。

そこで登場するのが、

Output

です。


今日覚えるコード

例えばALBのDNS名を表示したい場合、

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

と書きます。

今回まず覚えるのは、

output

と、

value

です。


Outputすると何が起きる?

例えば、

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

と書いて、

terraform apply

を実行すると、Terraformの実行結果として、

alb_dns_name = sample-alb-123456.ap-northeast-1.elb.amazonaws.com

のように確認できます。

つまり、

Terraform
↓
AWSリソースを作る
↓
作ったリソースが持っている情報を取得
↓
Output
↓
必要な情報を確認

という流れです。


ここで重要なこと

最初は、

«Output = 作ったAWSサービスを表示する機能»

と思ってしまいやすいです。

でも、これは少し違います。

Outputは、

«AWSサービスそのものではなく、そのリソースが持っている「必要な情報」を取り出す機能»

と考えると分かりやすいです。


例えばALBの場合

ALBというAWSリソースがあります。

ALB

これだけ表示されても、

👨‍💼 上司

«「ALBがあるのは分かった。URLは?」»

となります。

欲しいのはALBそのものではありません。

欲しいのは、

DNS Name

です。

そこで、

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

とします。

すると、

ALB
↓
DNS Name
↓
sample-alb-123456.ap-northeast-1.elb.amazonaws.com

という情報を取り出せます。


"value" は何を指定している?

ここが今回かなり重要です。

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

この中の、

value

は、

«Outputとして何の値を出すのか»

を指定しています。

つまり、

output
↓
「何を出す?」
↓
value
↓
「ALBのDNS名を出して!」

というイメージです。


コードを分解してみる

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

これを分解すると、

output
↓
Outputを定義する

"alb_dns_name"
↓
Outputにつける名前

value
↓
何の値を出すか

aws_lb.alb.dns_name
↓
ALBのDNS名

となります。


AWSリソースと「属性」を区別する

ここが今回一番重要なポイントです。

例えば、

aws_lb.alb

は、

«ALBというリソース»

です。

一方、

aws_lb.alb.dns_name

は、

«そのALBが持っているDNS名という属性»

です。

同じように、

aws_db_instance.main.endpoint

なら、

«RDSインスタンスが持っているEndpoint»

です。

aws_vpc.main.id

なら、

«VPCが持っているVPC ID»

です。

つまり、

AWSリソース
↓
そのリソースが持っている情報
↓
必要なものをOutputする

という考え方です。


イメージしやすく考えてみる

AWSサービスを「人」だと考えてみます。

例えば、

EC2さん

という人がいたとします。

その人には、

名前
住所
電話番号
社員番号

など、いろいろな情報があります。

でも、

«「EC2さんを表示して!」»

と言われても、何を知りたいのか分かりません。

知りたいのは、

EC2
↓
Instance ID

かもしれないし、

EC2
↓
Private IP

かもしれません。

Outputは、

«そのリソース全部を表示するのではなく、必要な情報を指定して取り出す»

というイメージです。


今日の問題

Q1

なぜ、

output

を書くのでしょうか?


Q2

なぜ、

value

を書くのでしょうか?

何を指定していると思いますか?


⭐ 今日一番重要

会社でTerraformを実行したとします。

すると、

ALB
VPC
RDS
EC2

など、全部作成されました。

でも上司から、

«「RDS Endpointだけ教えて。」»

と言われました。

このとき、

Outputがあると便利なのはなぜでしょうか?


🎁 最後に応用問題

今まで勉強してきた中で、

«Outputしたら便利そうなものを3つ»

挙げてみてください。

例えば、

ALBのURL

のように、

«「作ったあとによく確認したい情報」»

を考えてみましょう。


今回の回答

Q1

«Terraformで作った情報を共有するときにしやすくなるため。»


Q2

«"output "alb_dns_name" {" にValueを書くことでALBの値(URL)を示せるから。»


⭐ 今日一番重要

«RDSのデータだけを共有できるから。»


🎁 Outputしたら便利なもの

«EC2、RDS、VPC»


今回のレビュー

Q1:なぜOutputを書く?

回答

«Terraformで作った情報を共有するときにしやすくなるため。»

評価:💯

正解です。

より正確に言うなら、

«Terraformで作ったリソースの必要な情報を、Terraformの実行後に確認しやすくするため»

です。

例えば、

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

と書いておけば、

terraform apply

の後にALBのDNS名を確認できます。

AWSコンソールを開いて探しに行く必要がありません。


Q2:なぜ "value" を書く?

回答

«"output "alb_dns_name" {" にValueを書くことでALBの値(URL)を示せるから。»

評価:95点

方向性は合っています。

ただし、ここはもう一段正確に理解しておきましょう。

"value" は、

«Outputとして何の値を出すのかを指定する»

ものです。

例えば、

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

なら、

value
↓
aws_lb.alb.dns_name
↓
ALBのDNS名を出す

となります。

ここで大事なのは、

«valueは「ALBのURL専用」ではない»

ということです。

例えば、

output "vpc_id" {
value = aws_vpc.main.id
}

でもいい。

output "rds_endpoint" {
value = aws_db_instance.main.endpoint
}

でもいい。

output "ec2_private_ip" {
value = aws_instance.web.private_ip
}

でもいい。

つまり、

«"value" に「Outputしたい値」を指定する»

と覚えればOKです。


⭐ 今日一番重要な問題のレビュー

回答

«RDSのデータだけを共有できるから。»

評価:💯

これも考え方として正解です。

ただし、「RDSのデータ」というより、

«RDSの必要な情報»

と表現するとさらに正確です。

例えば、

output "rds_endpoint" {
value = aws_db_instance.main.endpoint
}

とすると、

RDS
↓
Endpoint
↓
sample-db.xxxxxx.ap-northeast-1.rds.amazonaws.com

という情報を確認できます。

上司から、

«「RDS Endpointだけ教えて。」»

と言われたときに、

AWSコンソールを開いて探すのではなく、

terraform apply
↓
Output
↓
RDS Endpoint

と確認できるわけです。

これが実務で便利なポイントです。


🎁 Outputしたら便利なもの

今回の回答は、

«EC2、RDS、VPC»

でした。

ここは少しだけ修正があります。

実はOutputするのは、

EC2そのもの

でも、

RDSそのもの

でも、

VPCそのもの

でもありません。

Outputするのは、

«そのリソースの中にある「知りたい情報」»

です。


例えばALB

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

取り出すのは、

ALB
↓
DNS Name

です。

これは、

«ブラウザからWebサービスへアクセスするとき»

などに便利です。


RDSなら

output "rds_endpoint" {
value = aws_db_instance.main.endpoint
}

取り出すのは、

RDS
↓
Endpoint

です。

これは、

«アプリケーションからRDSへ接続するとき»

などに必要になります。


VPCなら

output "vpc_id" {
value = aws_vpc.main.id
}

取り出すのは、

VPC
↓
VPC ID

です。

VPC IDは、

  • 別のTerraform構成
  • Module
  • AWSリソースの設定

などで必要になることがあります。


EC2なら何をOutputする?

ここで少し考えてみましょう。

EC2を作ったとして、

resource "aws_instance" "web" {

...

}

Outputするとしたら、何が便利でしょうか?

例えば、

Instance ID

output "ec2_instance_id" {
value = aws_instance.web.id
}

あるいは、

Private IP

output "ec2_private_ip" {
value = aws_instance.web.private_ip
}

などがあります。

場合によっては、

Public IP
Private DNS

などをOutputすることもあります。

つまり、

«「EC2をOutputする」»

ではなく、

«「EC2の何が必要なのか?」»

と考えることが重要です。


ここで大事な気づき

今回、少し面白いやり取りがありました。

「EC2からRDSへ通信するための情報をOutputしたい」

という考え方です。

これはかなり良い発想です。

なぜなら、

«「何をOutputできるか」ではなく、「誰が何のためにその情報を使うのか」»

を考えているからです。

例えば、

EC2
↓
RDSへ接続したい
↓
何の情報が必要?
↓
RDS Endpoint

となります。

だから、

output "rds_endpoint" {
value = aws_db_instance.main.endpoint
}

という設計につながります。

これは単なるTerraformの文法ではありません。

システム設計の考え方です。


Outputは「表示機能」だけではない

ここも少し発展的な話です。

Outputというと、

«Terraformを実行したら画面に表示されるもの»

というイメージを持ちやすいです。

もちろん、それも正しいです。

例えば、

terraform apply
↓
ALB DNS
RDS Endpoint
VPC ID

などを確認できます。

しかし、Outputにはもう一つ重要な役割があります。

それが、

«別のTerraform構成などへ、作成したリソースの情報を受け渡す»

という使い方です。


例えばVPCを別の構成から使いたい

例えば、

Terraform A
↓
VPCを作成
↓
VPC ID
↓
Terraform B
↓
EC2などを作成

という構成を考えます。

Terraform Aで、

output "vpc_id" {
value = aws_vpc.main.id
}

としておけば、

Terraform A
│
│ VPC ID
↓
Terraform B

という情報の受け渡しにつなげられます。

実際に別のTerraform構成からOutputを参照する場合は、Remote Stateなどの仕組みを使うことがあります。

そのため、

«Output = 画面に表示するだけ»

と覚えてしまうと少しもったいないです。

より正確には、

«Terraformで作成した重要な情報を外へ公開するためのインターフェース»

と考えることができます。


VariablesとOutputsをセットで考える

ここで前回のVariablesとつながります。

Variablesは、

外部
↓
Terraform

という方向でした。

例えば、

variable "instance_type" {
default = "t3.micro"
}

です。

一方、Outputsは、

Terraform
↓
外部

という方向です。

例えば、

output "vpc_id" {
value = aws_vpc.main.id
}

です。

図にすると、

          Terraform
              │
    ┌─────────┴─────────┐
    ↓                   ↓
Variables            Outputs
    ↓                   ↓

値を受け取る 値を外へ出す

この関係を理解すると、Terraformの設計がかなり見やすくなります。


今回覚えること

まずはこの形を覚えましょう。

output "名前" {
value = 取り出したい値
}

例えばALBなら、

output "alb_dns_name" {
value = aws_lb.alb.dns_name
}

RDSなら、

output "rds_endpoint" {
value = aws_db_instance.main.endpoint
}

VPCなら、

output "vpc_id" {
value = aws_vpc.main.id
}

です。


Outputを考えるときの質問

今後Outputを書くときは、

«「このリソースを作ったあと、誰が何を知りたい?」»

と考えてみましょう。

例えば、

ALB

誰が?
↓
開発者・利用者

何を?
↓
アクセス先

Output
↓
DNS Name

RDS

誰が?
↓
アプリケーション・開発者

何を?
↓
接続先

Output
↓
Endpoint

VPC

誰が?
↓
別のTerraform構成・AWSリソース

何を?
↓
VPCの識別情報

Output
↓
VPC ID

この考え方ができれば、

「Outputには何を書けばいいんだ?」

と迷いにくくなります。


🌟 今回の理解度

⭐⭐⭐⭐⭐ 5 / 5

Outputは、これまで学んできた、

  • VPC
  • Subnet
  • ALB
  • EC2
  • RDS
  • Security Group

のような「AWSリソース」とは少し性質が違います。

そのため、最初に難しく感じるのは自然です。

それでも今回、

«「EC2からRDSへ通信するための情報をOutputしたい」»

という発想が出てきました。

これはかなり重要です。

単に、

«「Outputは値を表示するもの」»

と暗記するのではなく、

誰が?
↓
何のために?
↓
どの情報が必要?
↓
その情報をOutputする

という考え方ができています。


🎓 次回予告

次回はいよいよ、

Module

に入ります。

ここからTerraformの「部品化」が始まります。

今までは例えば、

EC2
Security Group
Subnet
IAM

などを、それぞれTerraformに書いてきました。

でも、実務で同じような構成を何度も作るなら、

毎回全部書くのは大変です。

そこで、

EC2
+
Security Group
+
その他の設定

を一つの「部品」としてまとめます。

そして、

module "web" {
}

のように呼び出して使えるようにします。

イメージとしては、

今まで

EC2
SG
Subnet
IAM
などを
毎回書く
↓

Module

┌─────────────────┐
│ Web Server │
│ │
│ EC2 │
│ Security Group │
│ その他の設定 │
└─────────────────┘
↓
module "web"

です。

つまりModuleは、

«Terraformで作った構成を「部品」として再利用する仕組み»

です。

Variablesで、

«設定値を外から変えられるようにする»

Outputsで、

«作ったリソースの必要な情報を外へ出せるようにする»

そして次のModuleで、

«複数のTerraformコードを一つの部品として再利用する»

という流れになります。

ここまで来ると、Terraformがかなり「設計ツール」らしく見えてきます。

そしてModuleを理解したら、いよいよ次の段階。

「要件だけ渡すから、ゼロからAWS構成を設計してTerraformを書いてみる」

という実務総合演習に進めます。

ここからは、今まで覚えた知識がバラバラではなく、

VPC
↓
Subnet
↓
Route
↓
ALB
↓
EC2
↓
RDS
↓
Security Group
↓
Variables
↓
Outputs
↓
Module

という一本の設計としてつながっていきます。🔥☁️🚀

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?