AWS認定ソリューションアーキテクト再認定を受けて無事合格しました

約2年まえに取得した、AWS認定ソリューションアーキテクトアソシエイツの期限がとっくに切れてしまっていたので、 再認定試験を受けて来ました。

失効から1年は再認定試験を受験できるようで、 80分40問の試験でした。

2年前と違い、リモート試験官に身分証明書をスキャンして提示したり、 2枚めの身分証明書でクレジットカードを表・裏、PCカメラに提示したり、 ちょっとしたところが色々変わっていて少し戸惑いました。

ysh.hateblo.jp

2年ぶりだけど、業務でかなりAWSを利用していることもあり、 試験当日に前回受験したときのポストを参考にしつつ、 下記の分野を中心に振り返りました。

  • EC2
  • VPC
  • EBS
  • AutoScaling
  • RDS
  • S3

さすがAWSだけあって、前に受けたときから結構差分があって、 正直知らないこともあり復習を兼ねてかなり勉強になった印象でした。

各分野をざっと振り返るのにBlackbelt Online Seminarシリーズを使いました。

キーとなる単語まとめ

EC2

VPC

  • public subnet / private subnet / protected subnetの違い
  • ストレージゲートウェイ / Natインスタンスの違いと配置場所。高可用性にする方法
  • セキュリティグループ(ステートレス)/ネットワークACL(ステートレス)の違い。特に各適用のタイミング。
  • Amazon Provided DNSVPC内のみ
  • VPN関係、仮想ネットワークゲートウェイ、ダイレクトコネクト、カスタマーゲートウェイ
  • VPCエンドポイント(DNSのレスポンスは変更ない、ルートテーブルで制御) ← 前回なかった
  • プライベートリンク ← 前回なかった

EBS

  • SnapShotの保存される場所
  • EBSはAZに依存するがSnapShotを介して、他のAZに展開かつ、ボリュームタイプ、容量を変更可能
  • エラスティックボリューム機能 → オンラインでボリュームタイプの変更、容量変更、IOPSの変更が可能 ← 前回なかった
  • ボリュームタイプ
ボリュームタイプ 特徴 用途
汎用SSD 3IOPS/GB (3000IOPSまでバーストする) 仮想デスクトップ、小、中規模のDB
プロビジョンドIOPS 予めIOPSを指定できる。 大規模なDB
スループット最適化HDD シーケンシャルファイルの扱いに向く EMR、DWH、大規模なログ分析
  • EBS最適化 ( ネットワーク帯域とIOの帯域を分断するよ)
  • スナップショットバックアップ1世代目はフル、2世代目以降は増分バックアップ。1世代目を削除下場合は、以降の世代で参照されていないもののみ、削除される。
  • バックアップと静止点
  • データボリュームの暗号化
    • 非暗号化→SnapShot→暗号化
    • 暗号化→別非暗号化EBSボリュームにコピー→暗号化解除

S3

  • ライフサイクルフック
  • スタンダート、スタンダードIAの違い。
  • Glacierを利用した場合の取り出し方法
  • S3への操作の一貫性
    • 新規追加 → Consistency Read / 登録後即時読み出し可能
    • 登録 → Eventually Consistency Read (結果整合性) / 更新後、古いデータが参照されることがある。
    • 削除 → Eventually Consistency Read (結果整合性) / 削除後、削除したデータが参照されることがある。

他によく出たところ。

  • S3のイベントフックとLambda
  • ApiGatewayの使い所
  • DynamoDB
  • S3のtransfer acceration
  • StorageGatewayの高可用性構成

↑を中心に思い出し半分、新機能はふむふむと軽く理解して。 受験・回答の感覚を思い出すために、受験の2時間前に模擬試験もうけ、いざ受験。

結果は、まあまあ、業務で使っているせいか、そんな安いものでもないので、 無事一発合格できてほっとしました。

それでは。

VagrantのプロバイダとしてEC2を利用する。

本番で利用するようなEC2インスタンスを、そのままVagrantコマンドで透過的に操作できると便利と思い、

まあ、実際のところはVirtualBoxなどからVagrantboxを作成するのが面倒になったのだけど。。。

vagrant-aws-plugin を用いて、ローカルのvagrantから指定AWS VPC内のインスタンスをupしたり、

haltしたり操作できるようにしてみる。

前提

  • Vagrant1.7.8
  • MacOS siella 10.12
  • Java1.8.0_25
  • aws cliツールはインストール済み

まずはvagrant-aws-pluginをインストールする

$ vagrant plugin install vagrant-aws

Vagrantファイルは以下のようになる

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "dummy"
  config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
  config.ssh.pty = true
  config.vm.provider :aws do |aws, override|
    aws.access_key_id = ENV["AWS_ACCESS_KEY"]
    aws.secret_access_key = ENV["AWS_SECRET_KEY"]
    aws.ami = "{AMI-id}"
    aws.instance_type="t2.micro"
    aws.security_groups=["{セキュリティグループ}", "{セキュリティグループ}"]
    aws.keypair_name = "{キーペア名}"
    aws.region = "ap-northeast-1"
    aws.associate_public_ip = true
    aws.subnet_id = "{subnet id}"
    override.ssh.username= ENV['AWS_USER_NAME']
    override.ssh.private_key_path = '~/.ssh/id_rsa'
  end
  config.vm.synced_folder "../web", "/var/www/web", create: true, owner: "apache", group:"apache", mount_options: ["dmode=775", "fmode=664"]
  • config.vm.providerには:awsを指定

  • AWSキーなどべた書きにしたくないので以下のようにして、環境変数から取得する

macなら ~/.bashrcなんかに

export AWS_ACCESS_KEY=xxxxxxxxx
export AWS_SECRET_KEY=xxxxxxxxx
export AWS_USER_NAME=xxxxx

を記述する。

そして上記がととのったら

$ vagrant up

Bringing machine 'default' up with 'aws' provider...
==> default: Warning! The AWS provider doesn't support any of the Vagrant
==> default: high-level network configurations (`config.vm.network`). They
==> default: will be silently ignored.
==> default: Starting the instance...
==> default: Waiting for instance to become "ready"...
==> default: Waiting for SSH to become available...
==> default: Machine is booted and ready for use!
==> default: Rsyncing folder: xxxx
==> default: Rsyncing folder: xxxx
==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision`
==> default: flag to force provisioning. Provisioners marked to run always will still run.

これでVirtualBoxなどローカルでイメージを作る場合と同じ要領で、カジュアルにEC2インスタンスVagrantとしてつかえるので便利です。

試しに、vagrant status

$ vagrant status
Current machine states:

default                   running (aws)

The EC2 instance is running. To stop this machine, you can run
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.

vagrant ssh

$ vagrant ssh
Last login: Fri Nov 25 07:34:49 2016 from x.x.x.x
[xxxxxx@ip-192-168-11-186 ~]$

Vagrantの共有フォルダ(ローカル<-->Vagrant)の扱い

EC2をVagrantのプロバイダとして利用する場合の、同期フォルダの扱いはrsyncとなる。

  • ローカル → rsync → EC2

気をつけなくてはいけないのは、EC2の変更はローカルに反映されない。

同期が発生するタイミングは、vagrant upを実行したときと手動で vagrant rsync を実行したタイミングとなる。

$ vagrant rsync

==> default: Rsyncing folder: ローカルフォルダ/ => リモートフォルダ/

ローカルに変更がある場合、自動でリモートに反映する

自動で反映するには、$ vagrant rsync-autoを実行する。

$ vagrant rsync-auto
==> default: Doing an initial rsync...
==> default: Rsyncing folder: ローカルフォルダ => リモートフォルダ
==> default: Watching: ローカルフォルダ
==> default: Watching: ローカルフォルダ

...

VagrantでEC2をプロバイダとすると、VirtualBoxなどをプロバイダとしてローカルに環境を構築する場合と同じ要領でインスタンスを操作できて、 非常に便利です。 例えば、本番で利用するamiを元にVagrant→EC2で開発をやれば、本番にしたとき環境の差異で動かない問題など解決するのではないでしょうか。

(・∀・)イイネ!!

MacでVagrant1.8.7にしたらvagrant box add / initがうまくできなくなった話

MacでVagrant1.8.7にしたらvagrant box add / initがうまくできなくなった。 vagrantを開発・検証環境用に多用していて困るので、なんとか解決した話。

環境は。

Vagrant 1.8.7

ホストOS

OS X 10.11.6(El Capitan)

作成したvagrant boxを追加しようと。

vagrant box add package.box --name <box名>

といつものようにコマンドを打つと。

An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.

なるエラーがでるじゃないですか。

なんだと思いつつvagrantデバッグログを出力設定。

export VAGRANT_LOG=DEBUG

再度同じようにコマンドを入力すると。

DEBUG subprocess: Selecting on IO
DEBUG subprocess: stderr: dyld: Library not loaded: @rpath/libcurl.4.dylib
  Referenced from: /opt/vagrant/embedded/bin/curl
  Reason: Incompatible library version: curl requires version 9.0.0 or later, but libcurl.4.dylib provides version 7.0.0
DEBUG subprocess: Waiting for process to exit. Remaining to timeout: 32000
DEBUG subprocess: Exit status: 5
 WARN downloader: Downloader exit code: 5
ERROR downloader: Exit code: 5

...


/opt/vagrant/embedded/gems/gems/vagrant-1.8.7/plugins/commands/box/command/add.rb:78:in `execute'
/opt/vagrant/embedded/gems/gems/vagrant-1.8.7/plugins/commands/box/command/root.rb:61:in `execute'
/opt/vagrant/embedded/gems/gems/vagrant-1.8.7/lib/vagrant/cli.rb:42:in `execute'
/opt/vagrant/embedded/gems/gems/vagrant-1.8.7/lib/vagrant/environment.rb:308:in `cli'
/opt/vagrant/embedded/gems/gems/vagrant-1.8.7/bin/vagrant:189:in `<main>'
 INFO interface: error: An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.


An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.


 INFO interface: Machine: error-exit ["Vagrant::Errors::DownloaderError", "An error occurred while downloading the remote file. The error\nmessage, if any, is reproduced below. Please fix this error and try\nagain.\n\n"]

ということで、

incompatible library version: curl requires version 9.0.0 or later, but libcurl.4.dylib provides version 7.0.0

curlの互換性の問題っぽい。

github.com

↑を参考にして、回避策が議論されていたので。以下を実行。

sudo ln -nsf /usr/bin/curl /opt/vagrant/embedded/bin/curl

そして、再度 vagrant box add package.box --name <box名> を実行。

...

 INFO interface: success: Successfully added box 'centos67_lamp' (v0) for 'virtualbox'!
 INFO interface: success: ==> box: Successfully added box 'centos67_lamp' (v0) for 'virtualbox'!
==> box: Successfully added box 'centos67_lamp' (v0) for 'virtualbox'!
 INFO warden: Calling OUT action: #<Vagrant::Action::Builtin::BoxAdd:0x000001020752d0>
 INFO environment: Running hook: environment_unload
 INFO runner: Preparing hooks for middleware sequence...
 INFO runner: 1 hooks defined.
 INFO runner: Running action: environment_unload #<Vagrant::Action::Builder:0x0000010329f050>

ということで無事に、vagrant box addが成功しました。

めでたしめでたし(・∀・)イイネ!!

お久しぶりのrsyncメモ(中身で比較、ディレクトリを除外など)

久しぶりにrsyncを使う場面があり、実際つかってみると、やらかしてしまうことが多いrsync。 よく使うオプションの記述方法をまとめてみました。

rsync / と の違い

間違えるとえらいことになるので注意。

  • → 自体も同期対象
  • / → 配下が同期対象

中身を比較して差分を同期する。

$ rsync -avzc <SRC DIR>/ <DST DIR>/

  • -a / あれこれオプションのまとめ。(--recursive --links --perms --times --group --owner --devices)
  • -v / 詳細表示
  • -c / チェックサムを常に使う(中身の比較となる)
  • -z / 圧縮転送

いきなりやるまえに、dry-runしましょう。

$ rsync -avnc <SRC DIR>/ <DST DIR>/

  • -n / dry-run

これやっておけば、更新対象のファイルを事前に確認できる。

除外ディレクトリ(--exclude)を指定する。.gitなど

$ rsync -avz --exclude '.git' --exclude '.project' <SRC DIR>/ <DST DIR>/

ハマりどころの1つ、除外ディレクトリが複数ある場合は、--excludeの指定を複数繰り返せばいいが、 指定方法が、 <SRC DIR> からの相対パス での指定となります。

除外ディレクトリをファイルで指定する。

$ rsync -avz --exclude '.git' --exclude '.project' <SRC DIR>/ <DST DIR>/

は、

ex.lstファイルが以下の中身とすると。

.git
.project

$ rsync -avz --exclude-from=ex.lst <SRC DIR>/ <DST DIR>/

とシンプルに記述できる。

<SRC DIR>にないファイルは削除する

$ rsync -avz --delete <SRC DIR>/ <DST DIR>/

  • --delete / ソースディレクトリにないファイルは削除する

と簡単によく使う備忘録でまとめてみました。

それでは(・o・)

CLIでCloudWatchをまとめて設定する

CloudWatchをGUIから1つづつ設定すると面倒なので、 AWS CLIからまとめて設定するシェルを作成した。

アラートの通知にはSNSを利用しるので、通知先SNSトピックを予め作成して、ARNを取得します。

を設定します。

DISK使用率 / プロセス存在チェックはAWSの基本のメトリクスでは取得できないので、 カスタムメトリクスとして設定します

ysh.hateblo.jp

SERVER_SIGNATURE は識別該当のInstanceIdのインスタンスに対して、識別し易い名前をつけます。

よく使うので、ざっとまとめてみました。 それでは(´ω`)

Laravel5.1でのEloquentORMをCRUDでまとめてみた

Laravel5.1たぶん5.2もそんなに変わらないと思うんですが、よく自分でも忘れてしまうことがあるのでまとめ。

Eloquentを利用するときは、そもそも利用する前提のモデルを設計することがこつ。

登録、参照、更新、削除のメモをする前に、前提のモデル。

massassignでの登録をしたいので、 対象のフィールドを $fillable で宣言しています。モデルの登録で記述している例だと、massassignを使っているので、 $fillableを宣言していなくて、はまることがよくある話なので注意。

class User extends Eloquent {
    
    protected $primaryKey = 'id';
    
    protected $fillable = [
        'name',
        'age'
    ];
}
  • CRUD
    • 登録
    • 参照
    • 更新
    • 削除

モデルの登録

単純に登録(Insert)

User::create([
    'name' => 'テスト太郎',
    'age' => 25
]);

モデルがPersistenceレイヤーにない場合登録、あれば更新する

nameが'テスト太郎'さんがいれば、name'テスト次郎', age'28'で更新。 いなければ登録。

User::updateOrCreate([ ['name' => 'テスト太郎'], ['name' => 'テスト次郎', 'age' => 28] ]);

モデルの参照

Persistenceレイヤーから取り出しModelにマッピングする。

  • その1
$user = User::find(1);

Persistence層に該当のレコードが存在しない場合は null が返却される。

  • その2
$user = User::findOrFail(1);

該当のレコードが存在しない場合は、Illuminate\Database\Eloquent\ModelNotFoundException が発生する。 JavaなんかのORMではこっちのパターンが多い気がする。 これはこれで、catchしてそのまま404返すとか使いどころ次第で便利だと思う。

尚、Modelのプロパティは

$user->nameで取り出せる。

モデルの更新

参照するモデルを作ってから更新するのが王道でしょうか。

//更新対象のモデルをオブジェクト化
$user = User::find(1);

$user->name = 'テスト次郎';
$user->save();

モデルの削除

//削除対象のモデルをオブジェクト化
$user = User::find(1);

$user->delete();

ざっと、よく使うものをメモ程度にまとめてみました。

それでは(´ω`)

SSHポートフォワーディングのまとめ

普段何気なく利用しているSSHのポートフォワード。

よくコマンドを忘れてしますのでまとめてみました。 ひとえにポートフォワードといっても、

  • ローカルフォーワード
  • リモートフォワード

があります。

SSHローカルフォワード

<Local> port:8080 --- via SSH --------
              ------------>>> <Remote Host> ----->>> <Target Host> port:80

ローカルホストの特定ポートへの情報をターゲットホストの特定のポートへ転送する技術です。 ローカルホストの特定のポートを、SSHトンネルを介してリモートホストへ接続して、接続先のリモートホストから接続が可能なターゲットの特定のポートにマッピング。 上の例だと、ローカルホストのポート8080を、ターゲットホストのポート80にマッピングしています。

ローカルフォワーディングのコマンド

$ ssh -N -f -L <Local Port>:<Target Host>:<Target Port> <Remote Host>

上のコマンドで-N、-fオプションはそれぞれ。

  • -N : コマンドを発行しない
  • -f : バッググランド実行

SSHリモートフォワード

<Local> port:9000 <<<--- via SSH --------
              ------------- <Remote Host> <<<----- <Target Host> port:9001

リモートホストの特定ポートへの情報をローカルホストの特定のポートへ転送する技術。 ローカルホストのポートとターゲットホストのポートのマッピングはローカルホストと同じ、コマンドオプションが違うだけ。

SSHリモートフォワーディングのコマンド

$ ssh -N -f -R <Target port>:<Target Host>:<Local Port> <Remote Host>

xdebugなど、ターゲットホストからローカルホストへ接続する必要があるものなどで役に立ちます。

簡単にまとめて、それでは。