3
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?

More than 1 year has passed since last update.

入門 AWS CloudFormation #6(出力とエクスポート、及びそれらの別テンプレートでの利用編)

Last updated at Posted at 2023-02-28

インフラやクラウドの専門というわけではないのですがそろそろIaC周りもちゃんと勉強しておきたい・・・という感じなのでAWSのCloudFormationについて入門しつつ復習として記事にまとめておきます。

※とりあえず最初ということでごく基本的なところを中心に記事を書いていきます。

注意事項と前記事までの振り返り

本記事の処理を動かすとEC2関係などで色々と追加になったり起動したりします。その辺はリソースの停止や削除などをしないとお金がかかったりしてくる可能性があるためご注意ください。

また、本記事は6記事目となります。前回までの内容を踏襲していく形となっているのでご注意ください。

1記事目:

2記事目:

3記事目:

4記事目:

5記事目:

※以前先行して一部出力関係の部分は触れたので重複しているところも本記事にトピックをまとめるために触れていきます。

本記事で触れること

前記事までに少し出力(Outputs)関係について触れましたが、その辺りを詳しく触れていくのとその値のエクスポートや別のYAMLテンプレートのファイルから参照したりなどをしていこうと思います。

出力値設定の基本

4記事目辺りにある程度触れた感じとなりますが復習的に触れておきます。

出力はOutputsというセクションに定義することで何らかリソースの属性値などの値の出力を行えます。

内容を確認したりすることができるのに加えて出力値をエクスポートすることで他のテンプレートファイルから参照したりすることもできます。

書き方としては以下のようになります。

Outputs:
  <出力値の論理名>:
    Value: <設定する値>

例えばRef関数でEC2インスタンスの論理名を指定するとインスタンスIDが返ってくるので、そちらの値を出力値として指定したい場合には以下のようになります。

Outputs:
  MyEC2InstanceId:
    Value: !Ref MyEC2Instance

YAMLテンプレートに組み込んで変更セットを作成して試してみます。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0590f3a1742b17914
      InstanceType: t3.nano
Outputs:
  MyEC2InstanceId:
    Value: !Ref MyEC2Instance

反映した変更セットは更新のイベントなどが完了すると出力タブにてOutputsセクションで指定した出力値の対象のキーと値が確認できます(直後ではイベント完了後に一度リロードしないと反映されないかもしれません)。

image.png

リソースの属性値を出力に設定する

以下の以前の組み込み関数の記事のFn::GetAtt関数の節でも触れましたが、各リソースの属性値をFn::GetAttで取得できるため取得結果の値をOutputsセクションにて設定することができます。

サポートされている属性名などに関しては以下の公式ページから対象のサービスのリンクを選択していってアクセスできるページにてFn::Ref関数とFn::GetAtt関数で取れる値と属性名、内容の説明などが確認できます。

たとえばEC2インスタンスのページであればFn::GetAtt関数の内容は以下のようになっていることを確認できます。

image.png

例としてAvailability Zoneの値を出力に設定する場合YAMLテンプレートは以下のようになります(!GetAtt <リソースの論理名>.<ドキュメント上に記載がある属性名>といった形になります)。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0590f3a1742b17914
      InstanceType: t3.nano
Outputs:
  MyEC2InstanceAz:
    Value: !GetAtt MyEC2Instance.AvailabilityZone

変更セットを作成・反映して確認してみます。

更新のイベントが終わってから出力タブを確認するとFn::GetAtt関数で取得した値(MyEC2Instance.AvailabilityZone)が出力値として設定されていることを確認できます。

image.png

出力をエクスポートする

Outputsなどの設定値に対してExportのキーを追加すると対象の値をエクスポートすることができます。エクスポートした値は他のYAMLテンプレートなどから参照ができるようになります。

Exportキーの中にはNameキーを指定して出力値の名前(他のテンプレートなどから参照する時に使用する名前)の設定が必要になります。

書き方としては以下のようになります。

    Export:
      Name: <設定する名前>

これを対象のOutputs内の値に追加します。インスタンスのAvailabilityZoneの値をエクスポートする形だと以下のようになります(出力名はOutputs部分の論理名と同じMyEC2InstanceAZとしましたが、Outputsのところで設定した論理名とずれていても使えます)。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0590f3a1742b17914
      InstanceType: t3.nano
Outputs:
  MyEC2InstanceAz:
    Value: !GetAtt MyEC2Instance.AvailabilityZone
    Export:
      Name: MyEC2InstanceAZ

変更セットを反映して出力タブの部分を見てみるとap-northeast-1dというAvailabilityZoneの値が出力されていることが確認できます。

image.png

また、Exportが設定されている場合にはエクスポートメニュー内でも値が確認できるようになります。CloudFormationの左のサイドメニューにあるエクスポートを選択します。

image.png

エクスポートの画面ではExportで指定した名前や対象の値、関連するスタック情報などが表示されます。

image.png

エクスポートした値の他のスタックからの参照とFn::ImportValue関数

エクスポートした値を別のYAMLテンプレートによるスタックで参照してみましょう。

別のYAMLファイルを作成し、シンプルなEC2インスタンスの記述を行います。事前にエクスポートした値はFn::ImportValue関数を使うことで参照することができます。

Fn::ImportValue: <Exportで事前に指定した名前>といった書き方になります。短縮系では!ImportValue <Exportで事前に指定した名前>となります。

新しく追加するYAMLテンプレートのEC2インスタンスのAvailabilityZoneの属性部分でこのFn::ImportValue関数を使うと以下のようになります。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MySecondEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0590f3a1742b17914
      InstanceType: t3.nano
      AvailabilityZone: !ImportValue MyEC2InstanceAZ

新しいスタックとして作成するため変更セットではなくスタックの作成から対応をしていきます。

image.png

スタックの名前はmy-second-ec2-instanceとしました。

image.png

作成処理が終わるまで待ちます。

image.png

完了後にEC2インスタンスのページにアクセスしてみると2つ目のインスタンスが作成されていることが確認できます。また、アベイラビリティゾーンの部分を見てみると!ImportValue関数で参照した値が設定されているので2つとも同じap-northeast-1dの値が設定されていることが確認できます。

image.png

エクスポートした値を利用する際の注意点

ドキュメントを見たり他のエクスポートに関して以下のような注意点があるようです。

※自信がない点もあるためある程度は後の節で試してみようと思います。

  • AWSアカウントごとにエクスポートする値の名前を一意にする必要があります。アカウントを複数プロジェクトとかで共有している場合とかは配慮が必要かもしれません。
  • 異なるリージョン間ではエクスポートした値をFn::ImportValue関数で利用することはできません。参照したい場合にはリージョンを合わせておく必要があります。
  • 別のスタックがエクスポートした値をFn::ImportValue関数などで参照している場合、エクスポートした値の削除が効かなかったりするケースがあります。恐らく削除したい場合には先に参照しているスタック側で参照を消すなどの対応が必要になります。
  • ドキュメントには「別のスタックによって参照されている出力値を変更または削除することはできません。」と書かれており、参照されている出力値に関しても変更が効きません。

試しに他から参照されている、エクスポートの記述があるスタックを削除してみる

ドキュメントなどには参照されていると削除が効かないと書かれていたので試しに削除してみてエラーになることを確認します。

現在2つのスタックがあり、OutputsExportを設定している1つ目のスタックの方を削除します。

image.png

対象のスタックを選択して削除ボタンを押します。

image.png

上部に変な感じの日本語になっていますがメッセージが表示されました。しかしスタックが消えていません。エラーメッセージとかも表示されない・・・?気配がしています(これは少々分かりづらい気配が・・・)。

image.png

どうやら対象のスタックのページに行ってイベントとかのタブを見るのが無難なようです。こちらを見るとDELETE_IN_PROGRESSとかのイベントが発行されていることが確認できます。しかしUPDATE_COMPLETEになりつつもExport MyEC2InstanceAZ cannot be deleted as it is in use by my-second-ec2-instanceというメッセージが出ておりエクスポートの値がmy-second-ec2-instanceのスタックで使われているから削除できないよ、といったメッセージが表示されています。どうやら情報としてはこちらを見ればOKそうです。

image.png

試しにエクスポートする値を更新してみる

エクスポートした値が外部から参照されていると、対象のエクスポートした値を別の値に変更できなくなるとドキュメントに書かれています。どんな感じなのか実際に試してみます。

まずは1つ目のスタックのYAMLテンプレートでAvailabilityZone: ap-northeast-1aというAZの指定をべたで追加しています(この辺のハードコーディングは良くないとは思いますが検証なため一旦OKとします)。現在このスタックではap-northeast-1cにAZがなっているので変更がかかる想定です。

AWSTemplateFormatVersion: "2010-09-09"
Resources:
  MyEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0590f3a1742b17914
      InstanceType: t3.nano
      AvailabilityZone: ap-northeast-1a
Outputs:
  MyEC2InstanceAz:
    Value: !GetAtt MyEC2Instance.AvailabilityZone
    Export:
      Name: MyEC2InstanceAZ

変更セットを反映してみたらExport MyEC2InstanceAZ cannot be updated as it is in use by my-second-ec2-instanceというエラーメッセージと共に変更が失敗しました。

image.png

やはり他のスタックで参照していると値の更新も効かなくなるようです。割と不便と言えば不便・・・には感じますが、インフラでそこまで頻繁に更新がかからないので運用的に大丈夫というところでしょうか・・・?

更新したくなった場合にはどうすべきか?という点なのですがAWSのドキュメントによると、

  • エクスポートされた出力値をインポートしているスタックを検索する
  • Fn::ImportValue関数でインポートしている箇所を、実際の現在エクスポートされている値でべた書きで上書きしてスタックへ変更を反映する
  • エクスポートしている値を更新する

といった手順を踏めば良いようです。

必要に応じて値のべた書きにした箇所をFn::ImportValue関数を利用する形に戻せば元通りとなります。

検証で使ったスタックやリソースの削除を行っておく

ここまでで複数のスタックを使ったエクスポートとインポートに対する検証が出来たので2つ目のスタックを削除しておきます(EC2インスタンスなども追加になっておりコストもかかるので)。

image.png

2つ目のスタックでは値のエクスポートなどはしていないので正常に削除が通りました。

image.png

EC2インスタンスのページを確認してみてもインスタンスが1つのみ残っていることを確認できます。

image.png

参考文献・参考サイト・参考講座まとめ

3
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
3
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?