SSブログ
Amazon AWS ブログトップ

EC2 SpotInstanceを使う [Amazon AWS]

Amazon EC2 のSpotInstanceは割とお安い訳ですよ。例えば、c3.2xlargeなら、定価0.511ドル/時のところ、SpotInstance価格ではなんと0.108ドル/時!!(この記事かいてる時点での価格)金利手数料はジャp(チガウ

SpotInstanceの仕組みとしては、Amazonさんの余剰リソースを安く使わせてもらおうというコンセプトのようで、その時のAmazonさんのリソースの空き具合に応じて「時価」が変動しますが、その時価よりも高い「スポット価格」を提示(入札)しているインスタンスに限って、リソースを使用してインスタンスを実行できるというもの。
例えば、今0.108ドル/時なので、「スポット価格」として0.2ドル/時を提示していれば、そのインスタンスは実行できるという感じ。
時折その時の「時価」がボーンと跳ね上がることがありますので、永続的に使用したいなーっていうのには向かないみたいですね。
一時的なバッチ処理をしたいとか、開発テストに使いたいとかそういう用途なら結構イケそうです。(Amazonさんもそう言ってますし。)

で、それを使ってみたいじゃないですか。コマンドラインから

という訳で試してみました。

スポットインスタンスはシャットダウン等するとインスタンス自体がTerminatedになってしまう模様(違ったらすんません)なので、1からインスタンスを立てて使おうという用途よりも、すでにあるインスタンスをスポットインスタンスで使うという感じが向いているのでしょうか。(違ったらすんません)

そんな訳でここでは「既存のEC2インスタンスからAMIを作成して、それをスポットインスタンスとして起動する」という作戦で実験したいと思います。

手順としてはこんな感じ。

① 既存のインスタンスからAMIを作成する
② (AMIの作成には時間がかかるので完成するのを待つ)
③ スポットインスタンスをリクエストする
④ (スポットリクエストが「履行中」のステータスになるのを待つ)
⑤ 必要に応じてタグを付けたりする



① 既存のインスタンスからAMIを作成する

 まず、既存のインスタンスからAMIを作成します。使用するコマンドは aws ec2 create-imageです。先に、既存のインスタンスのインスタンスIDを調べておく必要があります。

 aws ec2 create-image --instance-id (複製元となるインスタンスID) --name (AMIに付ける名前) --description (AMIに付ける説明文) --no-reboot

 「--no-reboot」オプションを省略すると、複製元となるインスタンスが強制的にリブートされます。問答無用です。このため、業務で使用中のインスタンスを指定した時などは悲しい思いをするかも知れないので要注意です。
 今のところ「--no-reboot」を付けたせいで問題になったということは経験していませんが、もしかしたら問題が発生するかもしれない?的な覚悟は一応しておいてください。(AmazonLinux以外の場合は特に…。)

 awsコマンドの実行結果は標準出力にjson型式で表示されますので、コイツを jqコマンドでパースしてやれば、AMIのIDが取得できます。取得すべき項目名は「.ImageId」です。


② (AMIの作成には時間がかかるので完成するのを待つ)

 AMIの作成には割と時間がかかりますね。ストレージの大きさにもよりますが。AmazonLinuxの標準(?)サイズの8GBでも数分はかかります。長いと10分以上要する事もあったりなかったり…。

 コマンドラインから完成したかどうかを確認したい場合は、aws ec2 describe-imagesコマンドで確認できます。

 aws ec2 describe-images --image-ids (AMIのID)

 作成が完了すると、「.Images[].State」に「available」が入ります。


③ スポットインスタンスをリクエストする

 はい。この記事の本丸です。(笑)
 スポットインスタンスをリクエストします。スポットインスタンスをリクエストすると、「リクエスト」が生成され、それにインスタンスが紐付く形になります。複数のインスタンスを同時に起動することも出来ますが、その場合は1個のインスタンスに1個のリクエストが関連付く格好になるので、スポットリクエストも複数作成されることとなります。スクリプトで処理する場合は配列処理するなり、ループ処理するなりしてください。

 使用するコマンドはaws ec2 request-spot-instancesです。
 ひとまず必要最低限のオプションとしてはこんな感じです。
 aws ec2 request-spot-instances --spot-price (提示する入札価格) --launch-specification (インスタンスをローンチするための情報)

 「提示する入札価格」は、お好みでどうぞ。単位はドル/時っぽいです。
 「インスタンスをローンチするための情報」には、最低でも次のような情報を指定することになります。
{
  "ImageId": "(AMIのID)",
  "InstanceType": "(インスタンスの種類)",
  "IamInstanceProfile": {
    "Arn": "(AMIインスタンスロールのArn)"
    },
  "SecurityGroupIds": ["(セキュリティグループID)"]
}


 VPCの中に入れたい時などは、VPCIDとかサブネットIDとかそういった情報も必要になってくると思います。(まだVPCの中に入れてテストしていないので…^^;)

 インスタンスをローンチするための情報をjson型式でファイルに書き出したら、file:///tmp/launch.json とかそんな感じで指定してコマンドに渡してやります。

 このコマンドを実行すると、実行結果がこれまたjson型式で返ってきますので、これまたjqコマンドで適宜パースしてやります。なお、「リクエストID」がこの後に必要となりますから、保存することをお忘れ無く。(リクエストIDは「.SpotInstanceRequests[].SpotInstanceRequestId」という項目に入ってきます。)


④ (スポットリクエストが「履行中」のステータスになるのを待つ)
 スポットインスタンスを生成した直後はまだインスタンスは存在しません。
 スポットリクエストが「履行中」というステータスになるのを待つ必要があります。確認するコマンドはaws ec2 describe-spot-instance-requestsです。コマンドラインで特定のリクエストIDだけ表示することが出来ないっぽいので、jqコマンドで必要な項目だけselectしてやる必要があります。
 おそらくこんな感じ。

aws ec2 describe-spot-instance-requests | jq '.SpotInstanceRequests[] | select ( .SpotInstanceRequestId == "(スポットインスタンスのリクエストID)" ) | .Status.Code'

 「.SpotInstanceRequests[].Status.Code」という項目にスポットインスタンスの状態が入っています。こいつが「fulfilled」になると、インスタンスが使用可能な状態となっていることを表します。
 また、スポットインスタンスの状態が「fulfilled」になった時、そのリクエストの「.SpotInstanceRequests[] .InstanceId」という項目を見ると、このリクエストに紐付いているEC2インスタンスのインスタンスIDが判明します。


⑤ 必要に応じてタグを付けたりする
 当たり前のように、ローンチされたばかりのEC2インスタンスにはタグも何も無いので(Nameタグすらない!!)、適宜タグを付けてあげましょう。



なお、注意点としては…
・インスタンスをshutdownするとインスタンスがterminatedになるっぽい
・スポットインスタンスの上限は20個まで(インスタンスサイズによっては10とかいう場合も有る)
・必ずしも「定価」より安いとは限らない模様
・Amazonさんの余剰リソースの状況によっては突然terminatedになる恐れがあるらしい

スポットインスタンスの上限を拡大してもらえるのかどうかは不明です。申請フォームには無かったようですが…??(私の目が節穴である可能性に注意)

それにして、安いよねー。

#トラフィック課金は高いけどなー。

Amazon EC2 インスタンスを1からコマンドラインで立ててみる(その4:環境を整える) [Amazon AWS]

 ぶっちゃけ、ここから先はありがちなLinuxセットアップのお話なんですが、EC2特有の問題がちょっとあるので、そこらへんを片付けてしまいましょう。

① ec2-user【以外】のログインアカウントを作成して、ec2-userは潰す
 まず、ログインアカウントのお話です。
 個人的にはec2-userは最初にログインする時「だけ」使うべきだと思っています。インスタンスにログインできたら、それ以降は自分のアカウントを作成してそちらを使うべきだと思っています。多分、キーペアも削除するべきなんだろうなあとか思ったりもしていますが。

 そんな訳で、useraddで新しくアカウントを作成します。

[root@maya ~]# slogin -i piro791key.pem -l ec2-user  ec2-54-199-31-204.ap-northeast-1.compute.amazonaws.com
Last login: Tue Aug 26 05:37:21 2014 from fs76eed40f.tkyc201.ap.nuro.jp

       __|  __|_  )
       _|  (     /   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 ~]$ sudo useradd piro791
[ec2-user@piro791 ~]$ sudo passwd piro791
ユーザー piro791 のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: 全ての認証トークンが正しく更新できました。
[ec2-user@piro791 ~]$
[ec2-user@piro791 ~]$
[ec2-user@piro791 ~]$ su - piro791
パスワード:
最後の失敗ログイン: 2014/08/26 (火) 05:42:57 UTC日時 pts/0
最後の正しいログインの後に 1 回の失敗ログインの試行があります
[piro791@piro791 ~]$


 で、新しいログインアカウントでssh鍵を忘れずに作成しておきましょう。

[piro791@piro791 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/piro791/.ssh/id_rsa):
Created directory '/home/piro791/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
(略)
[piro791@piro791 ~]$ cd .ssh
[piro791@piro791 .ssh]$ cat id_rsa.pub > authorized_keys
[piro791@piro791 .ssh]$ chmod 400 authorized_keys


 また、お好みに応じてrootにパスワードを設定するのも良いと思います。
 ssh鍵認証だけでパスワードを使用しないなら、rootの鍵も作成するとか鍵交換を済ませておくとかするとよいと思います。まあ、本来ならrootのパスワードも設定すべきですが。
 なお、rootのauthorized_keysに仕掛けがしてあります。このため、rootでいきなりログインしたいとかsshしたいとかscpしたいとかいうような場合は、rootのキーペアファイルを作成して(デフォルトでは存在しない)authorized_keysファイルの内容を差し替える必要があります。


② タイムゾーンとか言語設定とか
 日本人が使うのに困らないように変更しておきましょう。


③ yum update
 忘れずにね!!


④ お好みに応じてswapを追加する
 詳しい手順は Linuxのswap領域を追加する方法 を見てね!!

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

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

Amazon EC2 インスタンスを1からコマンドラインで立ててみる(その2の追加:EC2インスタンスを立てる前にすることの追加) [Amazon AWS]

 サーセン。2個、インスタンスを1から立てるに当たっての、重要な作業が漏れていました。

◎ キーペアを作成する

 EC2インスタンスにsshでログインするにあたっては、キーペアファイルが当然必要になります。特に、一番最初はコレが無いともうどうしようもない訳ですよ。
 そこで、キーペアを作成し、秘密鍵ファイルを入手することにします。

 コマンド一発…なんですが、若干の細工が必要です。(笑)

 ちなみに、使用するコマンドは aws ec2 create-key-pair --key-name (キーペアの名前) です。

 これをそのまま実行すると、JSON型式でこんな風に結果が返ってきてしまいます。

{
    "KeyMaterial": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA3jVtbfQ76gJtyv+6R15/AjAV3d/13m+UILhXEsxJG3Hbr6An2sDMw3rmAYFA\nUm+1G77gkD8O3RbIPo4BUUASqxHeCl7rltcfsEpQAOVSK0PoopSaDnPwOrVXM7uSdwqn804I2QzD\nIsZA/yf+uxsUCGzS6Jvow1v8qGTacLkrTCK6BPa/DNK2KzhxiLzrVnPiwhzH5A8TS2MaI0in8hTb\nceCejGUEXmcixYzZi6F(以下略)
    "KeyName": "piro791test",
    "KeyFingerprint": "XX:XX:XX:XX:XX:XX:XX:XX:ad:46:ba:b6:19:84:3b:36:65:9a:22:67"
}


 「KeyMaterial」というところに、秘密鍵ファイルの情報がガガーっと1行で記述されます。改行部分は「\n」に置き換えられているので、これを美しいフォーマットにしてファイルに保存しておく必要があります。そこで、jq とecho の出番です。こうしましょう。

[root@atago src]# echo -e `aws ec2 create-key-pair --key-name piro791key | jq '.KeyMaterial' | tr -d '"'`
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAsILSse+hGW4ioDi7yLGJFMIeluHaJ9VkMdCFmMfRZnptA24Lb379V2H/kNCN
JB0w9tQMV4XeoE2l9UgtZJDP6n5YiWjSSM64MalTISKoGdtnOSoCighb8KVXc+gzwJIeUq8EUuUq
yyS90mwZXr9GfKfD6YpSDjQjeSvWHzi37pqzvtPX/MIQcw9XK3hKzwlmCf0AjshYZ9YX3vxwwea1
(以下略)


 で、これをファイルに保存しておけば良い訳です。
 なお、必要の無くなったキーペアは削除しておきましょう。あるいは、キーペアの名前が気に入らないとかいう場合にも削除しておきましょう。削除の方法は、 aws ec2 delete-key-pair --key-name (削除したいキーペアの名前) です。

[root@atago src]# aws ec2 delete-key-pair --key-name piro791key
{
    "return": "true"
}


◎ロールをインスタンスプロファイルに割り当てる
 カラッポのロールを作成しましたが、これをインスタンスプロファイルと呼ばれる物に割り当てる必要があります。

 ・カラッポのインスタンスプロファイルを作成する
 ↓
 ・ロールを割り当てる

 という手順を踏みます。まず、カラッポのインスタンスプロファイルを作成します。

 aws iam create-instance-profile --instance-profile-name (インスタンスプロファイル名)

[root@maya tmp]# aws iam create-instance-profile --instance-profile-name piro791profile
{
    "InstanceProfile": {
        "InstanceProfileId": "AIPAIPOFVOGVSDWV2Y73A",
        "Roles": [],
        "CreateDate": "2014-08-25T04:57:13.759Z",
        "InstanceProfileName": "piro791profile",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:instance-profile/piro791profile"
    }
}


 そしたら、ここにすでに作成してあるロールを割り当てます。
 aws iam add-role-to-instance-profile --instance-profile-name (作成したプロファイル名) --role-name (割り当てるロール名)

[root@maya tmp]# aws iam add-role-to-instance-profile --instance-profile-name piro791profile --role-name piro791role
[root@maya tmp]#


 これ、何も結果を返さないんですよね。念のため 「 echo $? 」 を実行してみると0が返ってくるので大丈夫なんだと思います。タブン。

Amazon EC2 インスタンスを1からコマンドラインで立ててみる(その2:EC2インスタンスを立てる前にすること) [Amazon AWS]

 では、awsコマンドが使用出来るようになったところで、インスタンスを立てる前の準備にとりかかりたいと思います。

 詳しい事は、そのスジな書籍あるいはそのスジなblogあるいはGoogle先生等を調べてもらうとして、まっさらな状態から「やっておいた方が良い作業」にとりかかります。それは以下の2点です。

その1:「ロール」を作成しておく
 この作業は省略しても一向に差し支え有りません。その場合は「デフォルト」のロールを割り当てられることになります。しかし、後日「ロールを変更したいなあ」という事になった際に不便なので(そして、大抵は「変更したいなあ」ということになる)、デフォルトのロールとは別に最低1個、「自分用のデフォルトロール」を作成しておくと良いです。
 なお、インスタンスにロールを割り当てたり、変更したりすることが出来るのは、今のところは「インスタンスを作成するタイミングだけ」みたいです。もし、後日「他のロールを割り当てたい」なんてことになると、インスタンスを作り直すところから始めることになってしまいます。残念ながら。
 改善するといいんだけどねえ!!!

その2:「セキュリティグループ」を作成しておく
 セキュリティグループはまあ要するに「ファイヤーウォール」的な何かといったところです。どのプロトコルを通すか、あるいはそのアドレスからのアクセスは通すかといったことをここで制御することになります。これも、「自分用のデフォルトセキュリティグループ」を作成しておくと良いです。
 自分の会社・自宅からのsshだけ通す…みたいな感じで。


 というわけで、はりきって参りたいと思います。

 まずは「ロール」を新しく作成します。細かいアクセス制御は後ほど作成するとして、ひとまず「からっぽ」のロールを作成します。
 JSON型式でカラッポのロールを定義します。内容はこんな感じ。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Principal":
        {
          "Service": "ec2.amazonaws.com"
        }
    }
  ]
}


 で、これをawsコマンドに読み込ませます。

 aws iam create-role --role-name (ロールの名前) --assume-role-policy-document file://(ロールを書いたファイル名)

 てな感じです。実行して問題が無ければこんな感じになります。

[root@maya tmp]# aws iam create-role --role-name piro791_test --assume-role-policy-document file://piro791.role.json
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    }
                }
            ]
        },
        "RoleId": "XXXXXXXXXX",
        "CreateDate": "2014-08-21T06:35:24.631Z",
        "RoleName": "piro791_test",
        "Path": "/",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/piro791_test"
    }
}
[root@maya tmp]#


 現在、どんなロールが作成済みなのかを確認するのは aws iam list-roles コマンドです。

[root@lelouch src]# aws iam list-roles
{
    "Roles": [
        {
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "sts:AssumeRole",
                        "Principal": {
                            "Service": "ec2.amazonaws.com"
                        },
                        "Effect": "Allow",
                        "Sid": ""
                    }
                ]
            },
            "RoleId": "XXXXXXXXXXXXXXXXXXXXXX",
            "CreateDate": "2014-08-21T06:35:24Z",
            "RoleName": "piro791_test",
            "Path": "/",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/nakui_test"
        }
    ]
}



 続いて、セキュリティグループを作成します。まずはカラッポのセキュリティグループを新しく作成します。
 こちらはコマンド一発です。

 aws ec2 create-security-group --group-name (セキュリティグループの名前) --description (メモ)

 これ、--descriptionは省略できないぽいですね??

[root@maya tmp]# aws ec2 create-security-group --group-name sg_piro791_test --description "My Security Group"
{
    "return": "true",
    "GroupId": "sg-XXXXXXXX"
}


 こんな感じで実行できます。
 セキュリティグループの確認は aws ec2 describe-security-groups です。

[root@lelouch src]# aws ec2 describe-security-groups
{
    "SecurityGroups": [
        {
            "IpPermissionsEgress": [],
            "Description": "My Security Group",
            "IpPermissions": [],
            "GroupName": "sg_piro791_test",
            "OwnerId": "XXXXXXXXXXXX",
            "GroupId": "sg-XXXXXXXX"
        }
    ]
}


 なお、EC2インスタンスに対するアクセスは、「セキュリティグループに書いたトラフィックだけ許可」されるので、このままでは誰も何も出来ないことになってしまいます。そこで、ひとまずは少なくともsshだけは出来るようにしておく必要があります。あるいは、「特定のIPアドレスからだけアクセスを許可」的な方向でも構わないと思いますが。

 IPアドレスが固定出来ている場合は、次のようなコマンドを使用してセキュリティグループに定義を追加します。
 aws ec2 authorize-security-group-ingress --group-name (セキュリティグループ名) --protocol tcp --port 22 --cidr アクセス元のIPアドレス

[root@maya tmp]# aws ec2 authorize-security-group-ingress --group-name sg_piro791_test --protocol tcp --port 22 --cidr 123.45.67.89/32
{
    "return": "true"
}


 なお、IPアドレス帯で許可したい場合は、「--cidr」の部分を適切に変更してください。

 ご家庭などでIPアドレスを固定出来ない場合は、残念ながら「バッチコイ」状態にする必要が出てきます。ちょっと怖いですが仕方が無いので「0.0.0.0/0」とすることになります。こんな感じ。

 aws ec2 authorize-security-group-ingress --group-name sg_piro791_test --protocol tcp --port 22 --cidr 0.0.0.0/0

 ちなみに、「アドレス間違えちゃった!」とか、「IPアドレスが変わったので変更したい!」という場合は、正しい(新しい)アドレスの許可を設定した後で、誤った(古い)アドレスの許可設定を削除することになります。削除するのは次のコマンド。

 aws ec2 revoke-security-group-ingress --group-name (セキュリティグループ名) --protocol tcp --port 22 --cidr (許可を取り消したいアドレス

[root@maya tmp]# aws ec2 revoke-security-group-ingress --group-name sg_piro791_test --protocol tcp --port 22 --cidr 123.45.67.89/32
{
    "return": "true"
}


Amazon EC2 インスタンスを1からコマンドラインで立ててみる(その1:事前準備編) [Amazon AWS]

 パブリッククラウドの雄(?)であるAmazon AWS、便利ですよねー。とっても便利ですよねー。あまりにも便利すぎてインフラ屋さんとしては堕落してしまうくらい便利ですよねー。(笑)

 さて、その便利でたまらないAmazon AWSの、EC2インスタンスを1から調き…じゃない、セットアップして育ててみたいと思いますが、便利な(でもしょっちゅう改造されてイラッとさせられる)GUIをあえて使わずに、漢らしく(?)全部CLIで解決したいと思います。(笑)
 で、WindowsからでもCLI操作はできるのですが、個人的な趣味嗜好・宗教上の事情によりLinux上で操作する方向でまいります。(笑)

 あと、Amazon AWSアカウントのサインアップについてはどうしようもないのでブラウザからなんとかしてください。(笑)ここでは、Amazon AWSのアカウントが取得できており、

・AWSアクセスキー
・AWSシークレットキー

 の取得が終わっていることを前提にしています。あ、あと自分で好き勝手なことが出来るLinux環境があると言う点も大前提です。(イマドキのMacでも良いかもしんないけど。)


 手順としてはこんな感じです。なお、まずはVPCを使用しない編で参ります。VPCを使用する編は後日記事を作成したいと思います。

事前準備:
1:コマンドラインインタフェースのセットアップ

EC2インスタンスを立てる前にすること:
2:「ロール」を作成しておく
3:「セキュリティグループ」を作成する

EC2インスタンスを作成する:
4:EC2インスタンスを作成する

EC2インスタンスを作成したらすること:
5:必要な設定を入れ込む



 まずは、操作に必要なコマンドラインインタフェースをインストールします。
 「awscli」と呼ばれる物を使用しますが、これはpython 2.6以降が必要です。まあ、大抵入っていると思います。検証環境として、インストールしたばっかりのCentOS7 を使用しましたが、入っていました。
[root@maya ~]# python -V
Python 2.7.5

 「pip」というコマンドを使ってインストールするのですが、まっさらな状態だとコレが入っていないようなので、コイツのインストールから始めます。
 チョー簡単です。

 easy_install pip

 こんだけ。これでOK。easy_installはイマドキのpythonインストール済み環境なら最初から入っていると思いますが、もし入っていない場合、あるいはpythonのバージョンが古い場合、あるいはyumとかでなく手でbuildしてインストールしたような場合は、Google先生に教えを請うなり、そのスジのサイトを見るなどして自分でどうにかしてください。(笑)

[root@maya ~]# easy_install pip
Searching for pip
Reading https://pypi.python.org/simple/pip/
Best match: pip 1.5.6
Downloading https://pypi.python.org/packages/source/p/pip/pip-1.5.6.tar.gz#md5=01026f87978932060cc86c1dc527903e
Processing pip-1.5.6.tar.gz
Writing /tmp/easy_install-37JC3L/pip-1.5.6/setup.cfg
Running pip-1.5.6/setup.py -q bdist_egg --dist-dir /tmp/easy_install-37JC3L/pip-1.5.6/egg-dist-tmp-OecBVR
warning: no files found matching 'pip/cacert.pem'
warning: no files found matching '*.html' under directory 'docs'
warning: no previously-included files matching '*.rst' found under directory 'docs/_build'
no previously-included directories found matching 'docs/_build/_sources'
Adding pip 1.5.6 to easy-install.pth file
Installing pip script to /usr/bin
Installing pip2.7 script to /usr/bin
Installing pip2 script to /usr/bin

Installed /usr/lib/python2.7/site-packages/pip-1.5.6-py2.7.egg
Processing dependencies for pip
Finished processing dependencies for pip
[root@maya ~]#


 こうしてpipがインストールできたら、続いてawscliのインストールにとりかかります。これもチョー簡単です。

 pip install awscli

 こんだけ。

[root@maya ~]# pip install awscli
Downloading/unpacking awscli
  Downloading awscli-1.4.2.tar.gz (239kB): 239kB downloaded
  Running setup.py (path:/tmp/pip_build_root/awscli/setup.py) egg_info for package awscli
(以下省略)
[root@maya ~]#


 いろいろゴチャゴチャーっと出力されますが、内容は気にしなくても大丈夫。タブン。
 インストールが終わったら、awsコマンドが使用出来るかどうか確認しましょう。

 aws help

 と打ってみてヘルプが出れば今はとりあえずOK。

AWS()                                                                    AWS()



NAME
       aws -

DESCRIPTION
       The  AWS  Command  Line  Interface is a unified tool to manage your AWS
       services.

SYNOPSIS
          aws [options] <command> <subcommand> [parameters]

       Use aws command help for information on a specific command.

OPTIONS
       --debug (boolean)

(以下略)


 ただし、このままではまだawsコマンドは正常に機能しません。「アクセスキー」と「シークレットキー」を設定しなければなりません。そこで、
 aws configure

 を実行します。

[root@maya ~]# aws configure
AWS Access Key ID [None]: HOGEHOGE
AWS Secret Access Key [None]: HOGEHOGEHOGEHOGE
Default region name [None]: ap-northeast-1
Default output format [None]:


 AWS Access KEY IDとAWS Secret Access Keyは、AWSにサインアップした時に発行されているものです。Web上から確認することが出来るので確認しておいてください。上記例では「HOGEHOGE」とか「HOGEHOGEHOGEHOGE」とか書いていますが、その部分に各自のソレを当てはめてください。
 Default region name は、AWSのクラウド環境は世界各地に配置されていますが、その「どこにある環境」を使うか?という指定をするものです。ここで指定しなくても良いのですが、いちいち指定するのが面倒臭いので、日本人なら東京にあるリージョンを使うだろ!という人は、上記の通りap-northeast-1と入力しておきましょう。
 Default output format は何も指定せずにEnter一発で良いです。なお、ここで無指定だとJSON型式で結果が得られることになります。



 ところでこのJSON型式。シェルスクリプト書きには邪悪なテキストフォーマットであると思いますので、これをよろしくパースしてくれるツールが欲しくなります。一般的には

 jq

 というパーサを使うとハッピーになれますので、これが無い場合はインストールしましょう。tarballを入手してbuildしてもいいし、yumやらaptでゲットできるならそれでも構いません。

Amazon AWS ブログトップ

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