SSブログ

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を使うのがタブン正解。(今のところ。)

  {
    "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が付きました。

 次のアーティクルでは、このインスタンスを調き…じゃない、きちんとセットアップして育ててみたいと思います。

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。