[小ネタ]便利なCloudFormationスタックのクイック作成リンクをクイックに作成してみた

CloudFormationスタックのクイック作成リンクは、リンクをクリックするだけで作って欲しいリソースを作成する為のページへ飛べるのでとても便利です。 そんなクイック作成リンクを「作成出来る」シェルスクリプトを「作って」みました。
2019.08.01

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

今年も徐々に寒さが和らぎ、来ましたね。春と共に。ヤツが。

……などという書き出しから始まる小ネタの覚え書きを見つけた頃に、夏がやって来ました。

▲ 水出し麦茶を作り置く事は忘れないのに……

こんにちは、AWS事業本部のShirotaです。喉元過ぎれば小ネタ忘れる。酷いです。
そんな訳で、7月最後は埋もれていた小ネタを掘り返して浄化させてあげようと思います。(もう8月ですが、このブログを書き始めたのは7月だったのです)

人間は不運(ミス)と踊(ダンス)っちまう生き物である

突然ですが、人間はミスをする生き物です。
ヒューマンエラー と言う言葉が定義されているくらい、ミスをする生き物なのです。
そんなWikipediaの「ヒューマンエラー」のページには以下の一文が記載されていました。

対策とは言え、人間である以上必ず失敗 (エラー) は起こりうる、人間に任せる完璧な対応策はないといった観点に基づいた対策を講じる必要がある。

何か、カッコイイ。 完璧なものは作れないけど、そこを目指して立ち向かう人類のこの姿勢。
そして、予防策として以下の項目が記されてます。

予防策としては下記のものなどがある。啓発や注意喚起するもの、注意力や意識が散漫になることを防ぐもののほか、「人間は間違える」ことを前提とした対策が考案されてきた。

  • 危険予知トレーニング (KYT)
  • 指差喚呼
  • メモやチェックリストによる記憶エラー対策
  • 疲労を起させないための勤務時間管理、適度な休息
  • ガム・コーヒーなど眠気覚ましになるものを喫食する。
  • ダブルチェック

絶対にミスが許されない重要な業務については、1人の人間に任せるのではなく、必ず、2人以上の人間を配置し、二次チェックあるいは三次チェックといった厳重なチェック体制を設けている場合がある。

極論を言えば、これをしても間違える時は間違えます。にんげんだもの。
コーヒーを飲んでも私が爆睡して「あああああ」などと入力された画面が見つかるのですから。

極限まで人力での入力を減らしたい  

そんな事をしてしまう人間の介在を極力減らす事、そうする事で確率を極限まで減らしていく事は可能です。
例えば、CloudFormationを用いた作業。
テンプレートを作ってしまえば、同じ設定のリソースの作成が何度でも作れる。インフラをコード管理する上での利点だと思います。
ただ、今回はもっと欲張りさんになってみたいと思います。そう、 まだ足らぬ の精神で挑みます。

今回は CloudFormationのスタックのクイック作成リンク を作るシェルスクリプトを作ってみました 。ややこしいですね。
まずは、CloudFormationのスタックのクイック作成リンクについて軽くお話したいと思います。

CloudFormationスタックのクイック作成リンクとは

簡単に説明すると、ブラウザに入力するだけでスタック作成ページに飛ぶリンクです。
そのリンクを開くと、既に必要パラメータの入力が完了しており、[Create stack]ボタンを押すだけでスタックの作成が開始されます。
このリンクの利点は、 URLを共有するだけ で、共有された人がこちらの想定するパラメータが入ったスタック作成ページに飛べるところにあります。
この便利なクイック作成リンク、構造はとても分かりやすく出来ています。
以下で、具体例を挙げながらURLの構造について解説します。

今回、例として「AWSが提供しているCloudFormationのサンプルテンプレートを用いたクイック作成リンク」を以下に記載しました。

    https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review #東京(ap-northeast-1)リージョンでスタックを作成する
    ?stackName=Test-EC2-ElasticIP #作成するスタック名
    &templateURL=https://s3-ap-northeast-1.amazonaws.com/cloudformation-templates-ap-northeast-1/EIP_With_Association.template #サンプルテンプレートのURL  
    &param_InstanceType=t2.micro #上記テンプレートで指定する必要のあるパラメータ1  
    &param_KeyName=TestStackURL #上記テンプレートで指定する必要のあるパラメータ2  
    &param_SSHLocation=XXX.XXX.XXX.XXX/32 #上記テンプレートで指定する必要のあるパラメータ3

今回使用したテンプレートは CloudFormationのユーザーガイド にある「ElasticIPアドレスを持つAmazon EC2インスタンス」です。
このテンプレートを用いると、デフォルトVPCのデフォルトサブネット内にEC2インスタンスが起動します(サブネットの指定が特に無い為)。
また、EC2インスタンスにはEIPとSSH接続の為のセキュリティグループがアタッチされる為、起動後すぐにEC2インスタンスにSSH接続する事が可能となっています。
 

クイック作成リンクを使ってみる

このテンプレートを使用する際には、以下のパラメータを決定及びリソースを作成しておく必要があります。

  • 作成するEC2インスタンスのインスタンスタイプ
  • 作成するEC2インスタンスで用いる秘密鍵
  • SSH接続元となるIPアドレス(CIDR)

秘密鍵を作成した上で、実際に上記のクイック作成リンクを使ってみます。

▲ 上記のリンク先。後は右下のボタンを押すだけでスタックが作成出来ます

スタックを作成して、実際にEC2インスタンスを作ってみました。

▲ すぐSSH接続出来る状態で起動していました

クイック作成リンクを作ってみる

では、実際にクイック作成リンクを作ってみましょう。
既に用意されているゴール(クイック作成リンク)に向けて、前提として必要な情報を入れていくシェルスクリプトを用意してみました。

    #!/bin/bash

    MyIP=`curl -s http://checkip.amazonaws.com/`

    echo "https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review
    ?stackName=Test-EC2-ElasticIP  
    &templateURL=https://s3-ap-northeast-1.amazonaws.com/cloudformation-templates-ap-northeast-1/EIP_With_Association.template  
    &param_InstanceType=t2.micro  
    &param_KeyName=$1  
    &param_SSHLocation=$MyIP/32"

セキュリティグループに登録するSSH接続の接続元のグローバルIPアドレスは、AWSが提供しているグローバルIPアドレスを取得出来るサイトからcurlコマンドを用いて取ってきて、MyIPという変数に格納しています。
このシェルスクリプトを実行する際に、引数として秘密鍵の名前を用いる事で秘密鍵を指定できるようにしました。
今回は、EC2インスタンスを手っ取り早く作成して触れるようにする事を考えてインスタンスタイプを無料枠のある t2.micro に固定しています。
もし、他のインスタンスタイプにしたい場合は引数をもう一つ用意して、指定できる形にしてあげましょう。ただし、サンプルテンプレート のパラメータ部分に記載のあるタイプのみ選択出来るという制約付きにはなってしまいます。
EC2インスタンスのAMIもサンプルテンプレートの指定のものしか使えないので、Amazon Linux 1 のEC2インスタンスになってしまいます。
より構築出来るリソースの自由度を上げたい場合は、自分でCloudFormationのテンプレートを作り、S3にアップロードして使いましょう。

実際に、上のシェルスクリプトを実行してみると以下のようにURLが生成されます。

    $ bash ./StackURL-Maker.sh TestStackURL
    https://ap-northeast-1.console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/create/review
    ?stackName=Test-EC2-ElasticIP  
    &templateURL=https://s3-ap-northeast-1.amazonaws.com/cloudformation-templates-ap-northeast-1/EIP_With_Association.template  
    &param_InstanceType=t2.micro  
    &param_KeyName=TestStackURL  
    &param_SSHLocation=XXX.XXX.XXX.XXX/32

後は、このURLをコピーすれば誰でも簡単にEC2インスタンスを構築するスタックを作成する事が出来ます!

オマケ: SSH接続用のコマンドも作ってみる

EC2インスタンス作成用のクイック作成リンクを教えると同時に、SSH接続のコマンドを教える必要がある事もあるかもしれません。
その際に、SSH接続のコマンドを作れるシェルスクリプトを作ってみました。

事前準備

このシェルスクリプト内では、AWS CLIを使用しています。
事前に、AWS CLIのインストールと設定を行っておいて下さい。

AWS CLI のインストール
AWS CLI の設定

シェルスクリプト

シェルスクリプトは、以下になります。

    #!/bin/bash

    FullPathKey=`find ~/.ssh -name "$1.pem"`
    EC2EIP=`aws cloudformation describe-stacks --stack-name Test-EC2-ElasticIP | jq -r .Stacks[].Outputs[1].OutputValue`

    echo "ssh -i $FullPathKey ec2-user@$EC2EIP"

秘密鍵を置いているディレクトリから秘密鍵ファイルのフルパスを取ってきて変数に格納する為、クイック作成リンクのシェルスクリプト同様、引数に秘密鍵の名前を用います。
また、作成済みのスタックからEIPを取得する為、AWS CLIを用いています。

▲ Outputsから作成したEIPの情報を得られます

上記のシェルスクリプトを実行すると、以下のようにSSH接続用のコマンドが生成されます。
実際に、生成したコマンドを使ってみました。

    $ bash ./SSH-Command-Maker.sh TestStackURL
    ssh -i /Users/Shirota/.ssh/TestStackURL.pem ec2-user@XXX.XXX.XXX.XXX
    $ ssh -i /Users/Shirota/.ssh/TestStackURL.pem ec2-user@XXX.XXX.XXX.XXX
    The authenticity of host 'XXX.XXX.XXX.XXX (XXX.XXX.XXX.XXX)' can't be established.
    ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXX.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'XXX.XXX.XXX.XXX' (ECDSA) to the list of known hosts.

        __|  __|_  )
        _|  (     /   Amazon Linux AMI
        ___|\___|___|

    https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
    19 package(s) needed for security, out of 28 available
    Run "sudo yum update" to apply all updates.
    [ec2-user@ip-XXX-XXX-XXX-XXX ~]$

本末転倒にならない程度に楽していこう

スタック作成リンクは、実際に人にAWSリソースの作成依頼をする際に便利です。
URLの構造も分かり易く、テンプレートの用意さえ出来れば様々な場面で使えると思います。
今回は、スタック作成リンクを作成するシェルスクリプトを作ってみました(ややこしい!)が、これを作成する方に手間が掛かっていては効率化の観点で微妙になってしまいます。その為、今回は小ネタという形で紹介させて頂きました。

もし、EC2インスタンスを構築するきっかけ、ひいてはCloudFormationに触れるきっかけ等になれば幸いです。