Amazon EC2 インスタンスを1からコマンドラインで立ててみる(その3:EC2インスタンスを作成する) [Amazon AWS]
では、いよいよEC2インスタンスを作成したいと思います。使用するコマンドは aws ec2 run-instances です。
ここまでに用意した、IAMロール、セキュリティグループ、そしてキーペアを指定してEC2インスタンスを作成すればいいんですが、ここでちょっと悩ましい問題が発生します。
aws ec2 run-instances --image-id (イメージID) --key-name (キーペア名) --security-groups (セキュリティグループ名) --instance-type (インスタンスの種類) --iam-instance-profile (インスタンスプロファイル名)
最低限、必要なオプションはこれくらいなんですが、この他に指定すべきオプションがあります。
--user-data ユーザーデータ
1.「イメージID」とはなんぞ??
「AMI」と呼ばれる、仮想マシンのイメージファイルに対するIDのことをいいます。全てのEC2インスタンスは「AMI」を作成することができ、AMIにはAmazonさんがあらかじめ用意している物もあります。Amazonさんがあらかじめ用意しているAMIは、たいていの場合は「OSをインストールしてごく最低限のセットアップだけを施した状態」で提供されています。
また、この他にもAmazon AWSの利用者が便利な機能を盛り込んだAMIを提供しており、これを用いることもできます。 (個人的には全く使用する気にはなれませんが…)
Amazonさん純正のAMIを使用して「OSインストール直後」のインスタンスを用意することになります。
で、それをどーやって調べるのか?というと…これもコマンドラインから調べることになります。(全部1行でね!)
aws ec2 describe-images --filters "Name=owner-alias,Values=amazon,Name=description,Values=Amazon Linux AMI x86_64 PV EBS"
で、良いはずなんですが、困った事に、OSのイメージはバージョンアップ等の理由でどんどん新しい物が「追加」されてしまいます。ということは、日を追う毎にこのコマンドで表示されるAMIイメージの数はどんどん増える一方。なので、よーく見ないと「ついうっかり古いバージョンの環境でインスタンスを立てちゃった」なんてことにもなりかねません。
そんな訳で、jqコマンドと組み合わせて古い順にソートするのがオススメです。
コマンドラインから実行するとこんな感じ。(全部1行でね!)
aws ec2 describe-images --filters "Name=owner-alias,Values=amazon,Name=description,Values=Amazon Linux AMI x86_64 PV EBS" | jq '.Images | sort_by(.ImageLocation)'
これで、一番最後に表示されたイメージの情報のIDを使うのがタブン正解。(今のところ。)
「 "ImageId": "ami-25dd9324",」って書いてある箇所がお目当ての情報になります。この記事を書いている時点での最新のものは「ami-25dd9324」ということになります。
ちなみに、今回インストールしようとしているOSのイメージは、Amazonさんが用意しているカスタムメイドなLinuxである、「Amazon Linux(64ビット版)」です。Windows Serverとか、Red Hat Linuxとか、SUSE Linuxとか、Ubuntuとかもあるんですが、物によってはOSのライセンス使用料金がかかったりこともあるので、Linuxでサクッとお試しするのであれば、「Amazon Linux」が良いんじゃないかなーと思ったりします。はい。Red Hat Linux系を扱い慣れている人ならコレがいいかもー。
2.インスタンスの種類 とはなんぞや?
Amazon AWS EC2の人気の秘けつの一つに、「豊富なインスタンスの種類がある」ことが挙げられるとおもいます。ここでいう「インスタンスの種類」とは、
① CPUのコア数
② 搭載しているメモリの量
③ インスタンスストレージサイズ
④ IO性能
といったものの組み合わせをいい、それぞれにユニークな名前が割り当てられています。
くわしいことは、 http://aws.amazon.com/jp/ec2/instance-types/ を見てくださいな。
当然、提供されるリソースが大きくなればなるほど、お値段もお高くなってきますので、そこら辺はお財布と相談した上で決定してみてください。
で、個人用途しては、t1.microとかをチョイスすることになると思います。
「ユーザーデータ」はちょっと横においておくとして、ここまでの情報でインスタンスをローンチできますので、実際にやってみたいと思います。なお、このままでは若干不便なのでもうちょっと待った方がいいよ!
実行すると、こんな感じになります。
注目するのは、「"InstanceId": "i-989e2881",」という部分。これがそのインスタンスを表す「インスタンスID」になります。これを使ってあれこれ操作することが多くなります。
次に、「"State"」のブロック。「"Name": "pending"」となっていますが、これは作業中であることを示しています。ここが「Running」になれば、インスタンスの作成が完了して起動したことになります。インスタンスの作成には数十秒~数分程度かかります。インスタンスの作成が完了したかどうか確認するには、先ほど確認したインスタンスIDを指定して確認します。
上記例でrunningになったことが確認できましたので、インスタンスが完成し、起動しているということが判ります。
では、さっそくsshでログインしましょう。
…どうやって?(笑)
アドレスを調べないことにはどうしようもありませんので(あたりまえ)、それを調べます。
ちなみに、VPCを使用しないインスタンスは、基本的にインスタンスを起動する度にアドレスが変わるので、その都度調べなければなりません。インスタンスを停止しないかぎり、rebootだけでアドレスは変化しません。
コマンドは、 aws ec2 describe-instances --instance-ids (インスタンスID) | jq '.Reservations[].Instances[].PublicDnsName' です。
ということなので、このアドレスを使ってインスタンスにアクセスします。
sshでログインする際には、作成・保存しておいたキーペアを使用します。また、ログインするアカウントは「ec2-user」という物を使用します。
というわけで、ちゃんとログインできましたね!!
ところで…。
「このインスタンスの名前が気に入らないクマ。」
…という人も多いと思います。(笑)
また、インスタンスが1個しか無いうちは問題になりませんが、インスタンスが増えてくると…
「お前は一体何者なんだ!?」
…という事態に陥ります。(笑)そこで、インスタンスに名前を付けておく必要性が高くなります。そしてその名前をhostnameに反映したいと思うようになります。
このblogでは、GUIを使っていないのですが、GUIでインスタンスの一覧を管理する場合、インスタンスには「Name」という『タグ』を使用するルールになっています。(Nameでなくても差し支えないが、他のサービスとの兼ね合いでNameを使用することが強く推奨されます)
では、Nameタグを使って名前を付けたいと思います。コマンドは、
aws ec2 create-tags --resources (インスタンスID) --tags Key=Name,Value=(インスタンス名) です。
そして、このNameタグからhostnameを付けるようにします。方法は二つあります。一つは、/etc/rc.local にその処理をベッタリと書き込むか、もう一つは「ユーザーデータ」を使用してインスタンス起動時にその処理を行う方法です。
まあ、/etc/rc.localにベッタリと書いてしまってもバチはあたりませんが、ここではもっと「それらしく」振る舞うこととしてユーザーデータを使用してインスタンス起動時にhostnameを設定させたいと思います。
ユーザーデータは、「インスタンスを作成する時」か、または「インスタンスが停止中」にだけ設定・編集することができます。なお、ユーザーデータの動作について詳しい事は、「ggrks」の精神でお願いします。(笑)
では、設定してみましょう。
まず、「Nameタグ」からインスタンスの名前を獲得して、hostnameとして設定するシェルスクリプトを作成します。
通常は、1行目にシェバングが来るところですが、それよりも先に、「#cloud-boothook」とかくのがミソです。あとはよくあるシェルスクリプトです。アクセスキーとシークレットキーは適切に設定してください。(個人的にはここに書きたくないので、ロールでどうにかなるかな?と思ったり思わなかったり…。それはまたの機会に!!)
これを適当なファイルに保存します。なお、シェルスクリプトとして実行するわけでは無いので、実行権とかそんなのどーでも良いです。はい。
そして、このファイルを、Base64でエンコードしておきます。base64コマンドが使えればソレで。
で、このファイルをaws ec2 run-instances コマンドに --user-data オプションを付けて渡してやります。
なお、Nameタグを付けるのはインスタンス作成中でも可能です。
インスタンスの作成が完了したらログインしてみます。なお、Nameタグを付けたタイミングによってはうまくhostnameが変わらないことがありますので、その場合にはインスタンスを1回リブートしてみてください。
と、うまいことhostnameが付きました。
次のアーティクルでは、このインスタンスを調き…じゃない、きちんとセットアップして育ててみたいと思います。
ここまでに用意した、IAMロール、セキュリティグループ、そしてキーペアを指定してEC2インスタンスを作成すればいいんですが、ここでちょっと悩ましい問題が発生します。
aws ec2 run-instances --image-id (イメージID) --key-name (キーペア名) --security-groups (セキュリティグループ名) --instance-type (インスタンスの種類) --iam-instance-profile (インスタンスプロファイル名)
最低限、必要なオプションはこれくらいなんですが、この他に指定すべきオプションがあります。
--user-data ユーザーデータ
1.「イメージID」とはなんぞ??
「AMI」と呼ばれる、仮想マシンのイメージファイルに対するIDのことをいいます。全てのEC2インスタンスは「AMI」を作成することができ、AMIにはAmazonさんがあらかじめ用意している物もあります。Amazonさんがあらかじめ用意しているAMIは、たいていの場合は「OSをインストールしてごく最低限のセットアップだけを施した状態」で提供されています。
また、この他にもAmazon AWSの利用者が便利な機能を盛り込んだAMIを提供しており、これを用いることもできます。 (個人的には全く使用する気にはなれませんが…)
Amazonさん純正のAMIを使用して「OSインストール直後」のインスタンスを用意することになります。
で、それをどーやって調べるのか?というと…これもコマンドラインから調べることになります。(全部1行でね!)
aws ec2 describe-images --filters "Name=owner-alias,Values=amazon,Name=description,Values=Amazon Linux AMI x86_64 PV EBS"
で、良いはずなんですが、困った事に、OSのイメージはバージョンアップ等の理由でどんどん新しい物が「追加」されてしまいます。ということは、日を追う毎にこのコマンドで表示されるAMIイメージの数はどんどん増える一方。なので、よーく見ないと「ついうっかり古いバージョンの環境でインスタンスを立てちゃった」なんてことにもなりかねません。
そんな訳で、jqコマンドと組み合わせて古い順にソートするのがオススメです。
コマンドラインから実行するとこんな感じ。(全部1行でね!)
aws ec2 describe-images --filters "Name=owner-alias,Values=amazon,Name=description,Values=Amazon Linux AMI x86_64 PV EBS" | jq '.Images | sort_by(.ImageLocation)'
これで、一番最後に表示されたイメージの情報のIDを使うのがタブン正解。(今のところ。)
{ "Description": "Amazon Linux AMI x86_64 PV EBS", "ImageType": "machine", "Public": true, "RootDeviceName": "/dev/sda1", "OwnerId": "137112412989", "KernelId": "aki-176bf516", "ImageLocation": "amazon/amzn-ami-pv-2014.03.2.x86_64-ebs", "Architecture": "x86_64", "VirtualizationType": "paravirtual", "Name": "amzn-ami-pv-2014.03.2.x86_64-ebs", "Hypervisor": "xen", "ImageOwnerAlias": "amazon", "ImageId": "ami-25dd9324", "RootDeviceType": "ebs", "State": "available", "BlockDeviceMappings": [ { "Ebs": { "Encrypted": false, "VolumeType": "standard", "VolumeSize": 8, "SnapshotId": "snap-e70ea007", "DeleteOnTermination": true }, "DeviceName": "/dev/sda1" } ] } ]
「 "ImageId": "ami-25dd9324",」って書いてある箇所がお目当ての情報になります。この記事を書いている時点での最新のものは「ami-25dd9324」ということになります。
ちなみに、今回インストールしようとしているOSのイメージは、Amazonさんが用意しているカスタムメイドなLinuxである、「Amazon Linux(64ビット版)」です。Windows Serverとか、Red Hat Linuxとか、SUSE Linuxとか、Ubuntuとかもあるんですが、物によってはOSのライセンス使用料金がかかったりこともあるので、Linuxでサクッとお試しするのであれば、「Amazon Linux」が良いんじゃないかなーと思ったりします。はい。Red Hat Linux系を扱い慣れている人ならコレがいいかもー。
2.インスタンスの種類 とはなんぞや?
Amazon AWS EC2の人気の秘けつの一つに、「豊富なインスタンスの種類がある」ことが挙げられるとおもいます。ここでいう「インスタンスの種類」とは、
① CPUのコア数
② 搭載しているメモリの量
③ インスタンスストレージサイズ
④ IO性能
といったものの組み合わせをいい、それぞれにユニークな名前が割り当てられています。
くわしいことは、 http://aws.amazon.com/jp/ec2/instance-types/ を見てくださいな。
当然、提供されるリソースが大きくなればなるほど、お値段もお高くなってきますので、そこら辺はお財布と相談した上で決定してみてください。
で、個人用途しては、t1.microとかをチョイスすることになると思います。
「ユーザーデータ」はちょっと横においておくとして、ここまでの情報でインスタンスをローンチできますので、実際にやってみたいと思います。なお、このままでは若干不便なのでもうちょっと待った方がいいよ!
実行すると、こんな感じになります。
[root@maya tmp]# aws ec2 run-instances --image-id ami-25dd9324 --security-groups piro791sg --instance-type t1.micro --key-name piro791key --iam-instance-profile Arn=arn:aws:iam::XXXXXXXXXXXX:instance-profile/piro791profile { "OwnerId": "XXXXXXXXXXXX", "ReservationId": "r-XXXXXXXX", "Groups": [ { "GroupName": "piro791sg", "GroupId": "sg-cd170ccc" } ], "Instances": [ { "Monitoring": { "State": "disabled" }, "PublicDnsName": null, "KernelId": "aki-176bf516", "State": { "Code": 0, "Name": "pending" }, "EbsOptimized": false, "LaunchTime": "2014-08-25T05:04:56.000Z", "ProductCodes": [], "StateTransitionReason": null, "InstanceId": "i-989e2881", "ImageId": "ami-25dd9324", "PrivateDnsName": null, "KeyName": "piro791key", "SecurityGroups": [ { "GroupName": "piro791sg", "GroupId": "sg-cd170ccc" } ], "ClientToken": null, "InstanceType": "t1.micro", "NetworkInterfaces": [], "Placement": { "Tenancy": "default", "GroupName": null, "AvailabilityZone": "ap-northeast-1c" }, "Hypervisor": "xen", "BlockDeviceMappings": [], "Architecture": "x86_64", "StateReason": { "Message": "pending", "Code": "pending" }, "IamInstanceProfile": { "Id": "AIPAIPOFVOGVSDWV2Y73A", "Arn": "arn:aws:iam::XXXXXXXXXXXX:instance-profile/piro791profile" }, "RootDeviceName": "/dev/sda1", "VirtualizationType": "paravirtual", "RootDeviceType": "ebs", "AmiLaunchIndex": 0 } ] }
注目するのは、「"InstanceId": "i-989e2881",」という部分。これがそのインスタンスを表す「インスタンスID」になります。これを使ってあれこれ操作することが多くなります。
次に、「"State"」のブロック。「"Name": "pending"」となっていますが、これは作業中であることを示しています。ここが「Running」になれば、インスタンスの作成が完了して起動したことになります。インスタンスの作成には数十秒~数分程度かかります。インスタンスの作成が完了したかどうか確認するには、先ほど確認したインスタンスIDを指定して確認します。
[root@maya tmp]# aws ec2 describe-instances --instance-ids i-989e2881 | jq '.Reservations[].Instances[].State' { "Name": "running", "Code": 16 }
上記例でrunningになったことが確認できましたので、インスタンスが完成し、起動しているということが判ります。
では、さっそくsshでログインしましょう。
…どうやって?(笑)
アドレスを調べないことにはどうしようもありませんので(あたりまえ)、それを調べます。
ちなみに、VPCを使用しないインスタンスは、基本的にインスタンスを起動する度にアドレスが変わるので、その都度調べなければなりません。インスタンスを停止しないかぎり、rebootだけでアドレスは変化しません。
コマンドは、 aws ec2 describe-instances --instance-ids (インスタンスID) | jq '.Reservations[].Instances[].PublicDnsName' です。
[root@maya tmp]# aws ec2 describe-instances --instance-ids i-989e2881 | jq '.Reservations[].Instances[].PublicDnsName' "ec2-54-95-17-129.ap-northeast-1.compute.amazonaws.com"
ということなので、このアドレスを使ってインスタンスにアクセスします。
sshでログインする際には、作成・保存しておいたキーペアを使用します。また、ログインするアカウントは「ec2-user」という物を使用します。
[root@maya ~]# ssh -i piro791key.pem -l ec2-user ec2-54-95-17-129.ap-northeast-1.compute.amazonaws.com The authenticity of host 'ec2-54-95-17-129.ap-northeast-1.compute.amazonaws.com (54.95.17.129)' can't be established. ECDSA key fingerprint is 03:3c:ae:33:b2:02:df:4b:92:b5:69:0d:af:35:80:0c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'ec2-54-95-17-129.ap-northeast-1.compute.amazonaws.com,54.95.17.129' (ECDSA) to the list of known hosts. __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/ 9 package(s) needed for security, out of 28 available Run "sudo yum update" to apply all updates. [ec2-user@ip-10-126-162-87 ~]$
というわけで、ちゃんとログインできましたね!!
ところで…。
[ec2-user@ip-10-126-162-87 ~]$ uname -a Linux ip-10-126-162-87 3.10.42-52.145.amzn1.x86_64 #1 SMP Tue Ju n 10 23:46:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux [ec2-user@ip-10-126-162-87 ~]$
「このインスタンスの名前が気に入らないクマ。」
…という人も多いと思います。(笑)
また、インスタンスが1個しか無いうちは問題になりませんが、インスタンスが増えてくると…
「お前は一体何者なんだ!?」
…という事態に陥ります。(笑)そこで、インスタンスに名前を付けておく必要性が高くなります。そしてその名前をhostnameに反映したいと思うようになります。
このblogでは、GUIを使っていないのですが、GUIでインスタンスの一覧を管理する場合、インスタンスには「Name」という『タグ』を使用するルールになっています。(Nameでなくても差し支えないが、他のサービスとの兼ね合いでNameを使用することが強く推奨されます)
では、Nameタグを使って名前を付けたいと思います。コマンドは、
aws ec2 create-tags --resources (インスタンスID) --tags Key=Name,Value=(インスタンス名) です。
[root@maya ~]# aws ec2 create-tags --resources i-989e2881 --tags Key=Name,Value=piro791 { "return": "true" } [root@maya ~]#
そして、このNameタグからhostnameを付けるようにします。方法は二つあります。一つは、/etc/rc.local にその処理をベッタリと書き込むか、もう一つは「ユーザーデータ」を使用してインスタンス起動時にその処理を行う方法です。
まあ、/etc/rc.localにベッタリと書いてしまってもバチはあたりませんが、ここではもっと「それらしく」振る舞うこととしてユーザーデータを使用してインスタンス起動時にhostnameを設定させたいと思います。
ユーザーデータは、「インスタンスを作成する時」か、または「インスタンスが停止中」にだけ設定・編集することができます。なお、ユーザーデータの動作について詳しい事は、「ggrks」の精神でお願いします。(笑)
では、設定してみましょう。
まず、「Nameタグ」からインスタンスの名前を獲得して、hostnameとして設定するシェルスクリプトを作成します。
#cloud-boothook #!/bin/sh export AWS_ACCESS_KEY="HOGEHOGE" export AWS_SECRET_KEY="HOGEHOGEHOGEHOGE" export EC2_URL=https://ec2.ap-northeast-1.amazonaws.com export EC2_REGION=ap-northeast-1 export AWS_DEFAULT_REGION=$EC2_REGION export EC2_HOME=/opt/aws/apitools/ec2 export JAVA_HOME=/usr/lib/jvm/jre INSTANCE_ID=`/opt/aws/bin/ec2-metadata | /bin/awk '/^instance-id/{print $2}'` TAG_NAME=`/opt/aws/bin/ec2-describe-instances $INSTANCE_ID | /bin/awk '/^TAG.*Name/{print $5}'` hostname $TAG_NAME echo $INSTANCE_ID":"$TAG_NAME | /usr/bin/tee /tmp/cloud-init.log
通常は、1行目にシェバングが来るところですが、それよりも先に、「#cloud-boothook」とかくのがミソです。あとはよくあるシェルスクリプトです。アクセスキーとシークレットキーは適切に設定してください。(個人的にはここに書きたくないので、ロールでどうにかなるかな?と思ったり思わなかったり…。それはまたの機会に!!)
これを適当なファイルに保存します。なお、シェルスクリプトとして実行するわけでは無いので、実行権とかそんなのどーでも良いです。はい。
そして、このファイルを、Base64でエンコードしておきます。base64コマンドが使えればソレで。
[root@maya tmp]# base64 user-data > user-data.base64 [root@maya tmp]# cat user-data.base64 I2Nsb3VkLWJvb3Rob29rCiMhL2Jpbi9zaAoKZXhwb3J0IEFXU19BQ0NFU1NfS0VZPSJBS0lBSlVN U1VRUFhXTFo2VEk3USIKZXhwb3J0IEFXU19TRUNSRVRfS0VZPSJEUkQyMk1kTkptVk54bVlCeVI3 (略) b3N0bmFtZSAkVEFHX05BTUUKCmVjaG8gJElOU1RBTkNFX0lEIjoiJFRBR19OQU1FIHwgL3Vzci9i aW4vdGVlIC90bXAvY2xvdWQtaW5pdC5sb2cKCg== [root@maya tmp]#
で、このファイルをaws ec2 run-instances コマンドに --user-data オプションを付けて渡してやります。
[root@maya tmp]# aws ec2 run-instances --image-id ami-25dd9324 --security-groups piro791sg --instance-type t1.micro --key-name piro791key --iam-instance-profile Arn=arn:aws:iam::XXXXXXXXXXXX:instance-profile/piro791profile --user-data file://user-data.base64 { "OwnerId": "XXXXXXXXXXXX", "ReservationId": "r-XXXXXXXX", "Groups": [ { "GroupName": "piro791sg", "GroupId": "sg-cd170ccc" } ], "Instances": [ { "Monitoring": { "State": "disabled" }, "PublicDnsName": null, "KernelId": "aki-176bf516", "State": { "Code": 0, "Name": "pending" }, "EbsOptimized": false, "LaunchTime": "2014-08-25T07:28:16.000Z", "ProductCodes": [], "StateTransitionReason": null, "InstanceId": "i-88883e91", "ImageId": "ami-25dd9324", (以下略) [root@maya tmp]# aws ec2 create-tags --resources i-88883e91 --tags Key=Name,Value=piro791 { "return": "true" } [root@maya tmp]#
なお、Nameタグを付けるのはインスタンス作成中でも可能です。
インスタンスの作成が完了したらログインしてみます。なお、Nameタグを付けたタイミングによってはうまくhostnameが変わらないことがありますので、その場合にはインスタンスを1回リブートしてみてください。
[root@maya ~]# ssh -i piro791key.pem -l ec2-user ec2-54-168-166-3.ap-northeast-1.compute.amazonaws.com The authenticity of host 'ec2-54-168-166-3.ap-northeast-1.compute.amazonaws.com (54.168.166.3)' can't be established. ECDSA key fingerprint is 35:8b:b1:e2:45:29:d2:77:ef:89:e6:3a:64:b3:6e:3a. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'ec2-54-168-166-3.ap-northeast-1.compute.amazonaws.com,54.168.166.3' (ECDSA) to the list of known hosts. __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2014.03-release-notes/ 9 package(s) needed for security, out of 28 available Run "sudo yum update" to apply all updates. [ec2-user@piro791 ~]$ uname -a Linux piro791 3.10.42-52.145.amzn1.x86_64 #1 SMP Tue Jun 10 23:46:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux [ec2-user@piro791 ~]$
と、うまいことhostnameが付きました。
次のアーティクルでは、このインスタンスを調き…じゃない、きちんとセットアップして育ててみたいと思います。
2014-08-25 16:38
nice!(0)
コメント(0)
トラックバック(0)
コメント 0