読者です 読者をやめる 読者になる 読者になる

humangas's blog

自分の振り返りを適当に書いてます。書きっぷりはそん時の気分によって変わります。

RHEL6.2にANSIBLEを導入する

テクノロジー RHEL インフラ ANSIBLE

今回やりたいこと

ANSIBLE使ってみたい。
理由:サーバ管理を何でやろうかと思ってた時に、ANSIBLEは、Agentレス(sshだけでOK)でシンプルぽいというのと、前行ったヌーコンで、 ヌーラボさんはANSIBLEでやってると言っていたため興味があった。あと、Chefはちょっとやったことあるが、ラーニングコスト高めと感じていたのと、いまイチ楽になってる気がしていない?。。ので、それに変わる何かを求めてた。

で、その環境はお仕事環境になるべく合わせて実験してみることにする。
お仕事用ですが、もちろん一般的なことしか書いてません。

環境

RHEL6.2(EC2上にVagrantで建てた

事前準備

もっとシンプルに出来ますが、自分に必要なメモなので。

ANSIBLEインストール

前述リンクの事前準備で持ってきた依存関係含むRPMパッケージ群を同じディレクトリに配置しておいて、丸ごとインスコするだけですね。

# rpm -ivh /tmp/ansible/*

ついでなので、そのDLしたパッケージをSCPするコマンドも書いておきます。

$ scp -r ~/Downloads/ansible root@test-server:/tmp/ansible/

r オプションを使うのがポイントですね。r つけるとディレクトリ毎送れます。 scp は、scp [送り元] [送り先] と書きます。そらで書けるようにしとくと何かと便利です。

忘れてましたが、インストールにはPython2.6以上が必要です。ですが、今回試したRHEL6.2にはデフォで入っていたので省略しています。
以下で確認できます。

# python --version
Python 2.6.6

簡単な検証をしてみる

今回は、EC2上に建てた2台のサーバ間でPING・cat /etc/redhat-release を打つ実験です。

秘密鍵の設定

その前にEC2上のサーバなので、デフォルトだと鍵認証です。
関係ある構成だけ言うと、どちらのサーバも同じキーペアを使ってる。命令出す側のサーバだけANSIBLE導入済み。当然、2台はSSH通信が許可されてる。こんなもんです。
なので、ローカルPC(Mac)にあった秘密鍵を命令を出す側のサーバに置いてあげます。

$ scp ~/keys/test-keys.pem root@test-server:/root/.ssh/id_rsa
$ cd ~/vagrant/test-server
$ vagrant ssh
[root@ip-XXX-XXX-XXX-XXX ~]# chmod 600 /root/.ssh/id_rsa

ANSIBLE動作検証

ANSIBLEの動作検証自体は、以下を参考にさせて頂きました。今回はセットアップメインなので、基本動作のみです。

事前準備:hosts

ANSIBLEは、hostsで設定されてるホストにのみアクションするようです。
で、先にそれを定義しておきます。定義するのは自分と操作テストするサーバの2台。

# echo "127.0.0.1" > /root/ansible/hosts
# echo "XXX.XXX.XXX.XXX" > /root/ansible/hosts

このhostsというファイルは、ANSIBLEのコマンド実行時に指定します。 ただし、ansible.cfgというファイルにhostsファイルへのパスを定義しておけば省略できるようです。

ということで、定義しますが、まずはインストール時に用意されているそのファイルをコピーして編集することにします。

# cp -p /etc/ansible/ansible.cfg .
# vi ansible.cfg

・・・ヘッダ省略・・・

[defaults]

# some basic default values...

#hostfile       = /etc/ansible/hosts
hostfile       = /root/ansible/hosts
library        = /usr/share/ansible
remote_tmp     = $HOME/.ansible/tmp

・・・以下略・・・

ANSIBLEは、以下の順序で環境設定ファイルであるansible.cfgをロードするようです。なので、上記手順だとコピーしたところをansibleコマンドの発行元(カレントディレクトリ)にしようとしています。
参考情報元:3. Ansible の疎通確認

  1. カレントディレクトリ
  2. 環境変数の ANSIBLE_CONFIG or ~/ansible.cfg
  3. /etc/ansible/ansible.cfg

pingを打ってみる

おぉ。。分かりやすい。もちろん、hostsファイルを指定してもOKです。ansible all -i hosts -m ping

# ansible all -m ping
127.0.0.1 | success >> {
    "changed": false,
    "ping": "pong"
}

XXX.XXX.XXX.XXX | success >> {
    "changed": false,
    "ping": "pong"
}
  • all でhostsの全体がターゲット
  • -i でhostsファイルパスを指定
  • -m でANSIBLEの内蔵コマンドを指定

という感じです。-m で使えるコマンド群に何があるかは、Webマニュアルか以下で参照することが出来ます。

# ansible-doc -l
acl                  Sets and retrieves file ACL information.
add_host             add a host (and alternatively a group) to the ansible-playbo
airbrake_deployment  Notify airbrake about app deployments
alternatives         Manages alternative programs for common commands
apache2_module       enables/disables a module of the Apache2 webserver
apt                  Manages apt-packages
apt_key              Add or remove an apt key
apt_repository       Add and remove APT repositores

・・・略・・・

また、個別のコマンドについて調べたい時は以下です(ansibleのyumコマンドを調べているところ)。

# ansible-doc yum
> YUM

  Installs, upgrade, removes, and lists packages and groups with the
  `yum' package manager.

Options (= is mandatory):

- conf_file
        The remote yum configuration file to use for the transaction.

- disable_gpg_check
        Whether to disable the GPG checking of signatures of packages
        being installed. Has an effect only if state is `present' or
        `latest'. (Choices: yes, no)

・・・略・・・

OSコマンドを実行してみる

出た出た。最終的には、何でも出来るということか。。。それにしてもシンプル。

# ansible testserver -a "cat /etc/redhat-release"
XXX.XXX.XXX.XXX | success | rc=0 >>
Red Hat Enterprise Linux Server release 6.2 (Santiago)
  • -a でOSコマンドを打つことができます。
  • testserver: 実はhostsファイルをグルーピングし、グループだけコマンド実行なんていうことができます。以下のようにhostsを書きます。
[local]
127.0.0.1
[testserver]
XXX.XXX.XXX.XXX

今回は、ココまで。
シンプルで、レシピ(ANSIBLEでは、Playbookと言うらしい)書かなくてもちょっとした運用用途に色々使えそうです。

参考:読んでおいたよさそうなサイト

まだまだ自分はコレからお勉強ですが。。

すごい良さそう! コレにしたい。

  • Chefよりエージェント気にしないので楽だし、使い方もシンプル
  • レシピなくても、コマンド拡張で色々便利なことが出来る。
  • → たとえば、ANSIBLEのhostsに書いたグループ単位にファイル送るとかバージョン見るとか、ping打つとか。だけでも。
  • ドキュメントがChefよりシンプル:Chefは多すぎる。
  • 進化は中々早そう(ヌーラボのtypetalk用のコマンド(ANSIBLE→typetalk通知)もあってちょっと驚いた)
  • さらに、homeblewコマンドもある。自分Macの環境管理用とかに使えるかもしれない。。
  • 拡張は、Python で無くて良い。レシピ(Playbook)もyaml形式で分かりやすい。
  • 意外と日本語の情報も出てくる。
  • 5000台運用とかの実績? もあるらしいのでお仕事でも使えそう。並列実行するらしいし。

ということで、もうちょっと勉強していきます。

Vagrantで AWS EC2インスタンス(RHEL6.2)を作成する

テクノロジー インフラ RHEL Vagrant

以前、QiitaにVagrantで AWS EC2インスタンス(RHEL5.5)を作成する という記事を書いたが、それからしばらく技術に触れることもなくすっかり忘れていたころに、また技術検証しないといけない要件が発生したのでやってみたところ、 記事を書いていたころより、大分バージョンが上がっており、試すOSも違ったので、2014/06/16時点で最新のバージョンでやってみることにした。

使い方は、前述の記事と大差ないと思うので割愛。

まず、Vagrantのバージョンアップ

前のバージョンを消すことなく、サイトからDLしてインストールしたら自動で上書きされた。

インストール後のバージョン確認(バージョン確認は2つやり方があり、普通のやつと、Latest Version も出してくれるやつがある)

$ vagrant --version
Vagrant 1.6.3

$ vagrant version
Installed Version: 1.6.3
Latest Version: 1.6.3
 
You're running an up-to-date version of Vagrant!

プラグインのアップデート

今回は、vagrant-aws プラグインを使ってEC2インスタンスを建てたいのでアップデートする。

$ vagrant plugin update
Updating installed plugins...
All plugins are up to date.

$ vagrant plugin list
sahara (0.0.16)
unf (0.1.4)
vagrant-aws (0.4.1)
vagrant-login (1.0.1, system)
vagrant-share (1.1.0, system)

IAMでユーザ作っておく

Vagrantfileにaws.access_key_idaws.secret_access_keyが必要だが、IAM作らないとキーが発行できないようになったので、ユーザを作っておく。 取り敢えず今回は、ADMIN権限を持つユーザを作っておく。

  • IAM Management Consoleのサイトにアクセス
  • 「Create a New Group of Users」を押下すれば、後は画面見れば分かります。
  • → その時、上記のキーが参照できるので控えておく。

Vagrantfileを書く

こんな感じです。vagrant-aws + vagrant-configspecでEC2をプロビジョニングするを参考にさせて頂きました。
独り言:へぇ、dummy.boxは、URL直指定でも良いのかぁ。。

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

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ec2"
  config.vm.box_url = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box"
  config.vm.synced_folder ".", "/vagrant", disabled: true

  config.vm.provider :aws do |aws, override|
    aws.access_key_id = '<YOUR_ACCESS_KEY_ID>' 
    aws.secret_access_key = '<YOURE_SECRET_ACCESS_KEY>'
    aws.keypair_name = '<YOURE_KEYPAIR_NAME>'

    aws.region = 'ap-northeast-1'

    aws.ami = 'ami-9526a894'
    aws.instance_type = 't1.micro'
    aws.security_groups = ['<YOURE_SECURITY_GROUPS>']

    aws.tags = { 
      'Name' => 'test-RHEL62'
    }

    override.ssh.username = 'root'  
    override.ssh.private_key_path = '<YOURE_SSH_PRIVATE_KEY_PATH>'
  end

end

YOURからはじまる箇所を適宜埋めます。
ここに埋まってる後のデータを参考までに書いておくと。。

  • ap-northeast-1: Tokyo リージョン
  • ami-9526a894: RHEL6.2
  • t1.micro: 最小インスタンスタイプ(無料期間であれば750H起動まで無料)
  • root: RHEL6.2だとrootでした。RHEL6.4起動した時はec2-userがいた記憶が。。

あとは使うのみ

操作対象サーバのVagrantディレクトリにcdしたら、以下で起動したりSSH接続したりする。

  • vagrant up : start
  • vagrant ssh : ssh接続
  • vagrant halt : stop
  • vagrant destroy:terminate
vagrant ssh-config >> ~/.ssh/config

をすると、簡単にSSH接続(ssh <Hostに定義されている名前>)できるので便利。
ちなみに、これはvagrantではなく、sshの機能です。

インストール対象のRPMが依存しているパッケージを丸ごとダウンロードする

テクノロジー RHEL インフラ

なんでそんなことをするのかというと。。。
自分はインフラエンジニアやってますが、お仕事だと、ネットに出れないサーバがいたり、そもそもインストールは環境管理側のセンターに任せろ。でも、そのための手順とモノは用意してね。ということが結構ある。
なので、依存パッケージごと丸ごとDLできればすげぇ楽なんです。で、今回の方法が大いに役に立つ。

やり方の結論は、yum downloadonly(yum の依存関係ファイルを全てダウンロードだけしてくれるコマンド)を使うです。

環境

  • RHEL6.2(EC2上に立ててる。Vagrantで立ててますが、その手順はまた別記事で)

やり方

downloadonlyをyumで導入

デフォだとそもそもこれが入ってないので入れる。

  • # yum -y install yum-plugin-downloadonly

実際ダウンロードしてみる

  • # yum install --downloadonly --downloaddir=<directory> <package>

以下はANSIBLEの場合(実は、ANSIBLEをRHEL6.2に入れたくて、その過程で書いてる。ANSIBLE記事は別記事で。)

# yum install --downloadonly --downloaddir=/tmp/ansible ansible
・・・ログ略・・・

# ls -l /tmp/ansible/
合計 3860
-rw-r--r--. 1 root root  161120  4月 27 16:18 2012 PyYAML-3.10-3.el6.x86_64.rpm
-rw-r--r--. 1 root root  836712  5月 24 12:21 2014 ansible-1.6.2-1.el6.noarch.rpm
-rw-r--r--. 1 root root   53452  3月 29 11:52 2014 libyaml-0.1.6-1.el6.x86_64.rpm
-rw-r--r--. 1 root root 1494848  4月 16 17:54 2014 python-babel-0.9.4-5.1.el6.noarch.rpm
-rw-r--r--. 1 root root  543156  3月 14 23:37 2014 python-crypto2.6-2.6.1-1.el6.x86_64.rpm
-rw-r--r--. 1 root root   72164  1月  7 12:10 2013 python-httplib2-0.7.7-1.el6.noarch.rpm
-rw-r--r--. 1 root root  477156  6月 11 22:47 2014 python-jinja2-2.2.1-2.el6_5.x86_64.rpm
-rw-r--r--. 1 root root  224124 12月 27 13:38 2012 python-keyczar-0.71c-1.el6.noarch.rpm
-rw-r--r--. 1 root root   71700  4月 16 17:54 2014 python-pyasn1-0.0.12a-1.el6.noarch.rpm

バッチリぽいですね。これをSCPとかでローカルに引っ張れば手元で管理しとけます。
ちなみに、DL先のディレクトリが無い場合は勝手に作ってくれるので、事前に用意しておく必要なし。

ちなみに、今回はEPELからDLしてます。

EPELというのは、RPMの拡張パッケージで、デフォルトのリポジトリに無いやつがあったりします。 その導入手順はコチラに書きましたので良ければ。

で、EPELの続きですが。。そもそも、EPELに入ってるRPMはどうやって知る?

いろいろ、あるかもしれませんが、WEBで見るのが楽かと。
EPELのルートから辿って、ブラウザ上で検索するのが楽です。自分はそうしてます。
で、メジャーバージョン> CPUアーキテクチャ とディレクトリを辿れば、RPMのページに辿りつけます。

今回のRHEL6.2だと、以下の具合で該当のRPMページに辿り着きます。 1. EPELのルートにアクセス 1. メジャーバージョンと用途(Clientと被るパッケージもあります):6Server 1. CPUアーキテクチャ:Intel x86_64 1. RPMの一覧ページで「例)ANSIBLE(目的のRPM)」で検索

該当のパッケージがあれば、EPELも含めて上記の方法でDL出来ます。
まぁ、一度リポジトリを登録してしまえば、yum コマンド発行時にどこにどのパッケージがあるか意識しないですけど。。

自分の使い方

この記事の冒頭で書いたように、そもそもネットアクセスできないサーバでこの手順を試してもダメです。当たり前ですが。 なので、一台ネットに出れる自由に触れる自分用のRHEL6.2サーバ(本番となるべく同じバージョンのサーバ)を用意しておいて、 そこで、この手順を試す。→ DLする。 → 本番サーバにSCPとかで持っていく。とかいう手順を踏みます。

自分の場合は、自由に触れるサーバはEC2で用意します。さらに、Vagrantで起動を組み合わせとけば、バージョン違いはami-idだけ調べれば良いので非常に楽と。
EC2使ったらダメということであれば、VirtualBoxかVMWare Player上でやるかな。

ちなみに、このVagrantで、RHEL6.2を建てるという手順は別記事で書きます。 以前に、QiitaでVagrantで AWS EC2インスタンス(RHEL5.5)を作成するという記事を書きましたが、今回バージョン違いとかでそのままでは上手く動かなかったので、焼き直しというイメージです。

参考にさせて頂いた記事

EPELリポジトリの導入方法(ANSIBLEをyumで入れるために。。):RHEL6.2

RHEL インフラ テクノロジー

EPELとは、YUMとかRPMみたいなリポジトリのこと。
RedHat標準リポジトリだと枯れたもんしかなく、最近流行りのモノとかは無かったりする。 なので、このEPELから取ってくる感じになる。

正確には以下(公式?ページ)を参照。

EPEL
エンタープライズ Linux 用の拡張パッケージ(EPEL) は、 Red Hat Enterprise Linux (RHEL) 向けの高品質なアドオンパッケージであり、CentOS や Scientific Linux (SL) のような RHEL からスピンオフしたディストリビューションと互換性のある、Fedora プロジェクトで有志によって作成されたパッケージになります。Fedora は RHEL のアップストリームであり、EPEL のアドオンパッケージは主に RHEL 向けにビルドされた Fedora リポジトリをソースとしています。
引用元: https://fedoraproject.org/wiki/EPEL/ja

ちなみに、今回はサーバプロビジョニングツールのANSIBLEを入れたかった。

試した環境

  • RHEL6.2(EC2上の)
  • ちなみに、このサーバはVagrantで立ててる。その手順は別記事で。

このブログに書いてあること

  1. EPELリポジトリをRHEL6.2に導入
  2. EPELリポジトリの導入前、導入後のリポジトリの比較

導入のイメージは、EPELリポジトリ情報が定義してあるrpmファイルをインストールすると、自サーバが参照するyumリポジトリに追加されるというシンプルなもの。
独り言:そっか。。リポジトリ自体もRPMで設定されるのか。。

では、やります

EPELリポジトリ(URL or RPM)準備

  1. EPELリポジトリにアクセス
  2. Packages という下にEPELリポジトリ設定用のRPMファイルリンクがある(2014/06/16現在だと、epel-release-6-8.noarch だった)ので、そのURLをコピー or そのままRPMをダウンロードする(※)

※ ダウンロードする場合は、当然そのファイルをサーバにSCPとかで送る必要がある。
この後で行うリポジトリ導入コマンドで、rpm -ivh EPELリポジトリRPMのURLという感じでURL指定もできるので、対象サーバがネットアクセス出来るか否かでやり方を選択すれば良い。ネットアクセスできるなら、URLでそのままやるほうが楽。

EPELリポジトリ設定導入

  1. EPELリポジトリを設定した対象のサーバ(RHEL6.2)にログインしてrootになっとく
  2. 以下どっちかのやり方でEPELリポジトリ設定のRPMをインストール

EPELリポジトリ設定のRPMインストール

  • # rpm -ivh http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
  • # rpm -ivh epel-release-6-8.noarch.rpm

ちなみに、epel-release-6-8.noarch の noarch の意味は、アーキテクチャに依存しないの意味。アーキテクチャとは、x86とかi386とかのCPUアーキテクチャを表してる。つまり、ざっくりHWはどれでもいいぜ。の略と思っとけばいい。

独り言:rpmてURLから直接叩けたのか。。。知らんかった。。

あと、EPELに望みのパッケージがあるか確認するであれば、URLから直接見ればいい。 http://dl.fedoraproject.org/pub/epel/ 今回の記事、RHEL6.2用(64bit)であれば、ココ。ANSIBLEがあるでしょ。

YUMリポジトリ導入確認

EPEL導入前

[root@ip-XXX-XXX-XXX-XXX ~]# yum repolist
Loaded plugins: amazon-id, downloadonly, rhui-lb, security
repo id                                                                                     repo name                                                                                                 status
rhui-ap-northeast-1-client-config-server-6                                                  Red Hat Update Infrastructure 2.0 Client Configuration Server 6                                                2
rhui-ap-northeast-1-rhel-server-releases                                                    Red Hat Enterprise Linux Server 6 (RPMs)                                                                  12,602
rhui-ap-northeast-1-rhel-server-releases-optional                                           Red Hat Enterprise Linux Server 6 Optional (RPMs)                                                          7,112
repolist: 19,716

EPEL導入後

下記の通りepelが追加されている。

[root@ip-XXX-XXX-XXX-XXX ~]# yum repolist
Loaded plugins: amazon-id, downloadonly, rhui-lb, security
repo id                                                                                     repo name                                                                                                 status
epel                                                                                        Extra Packages for Enterprise Linux 6 - x86_64                                                            10,939
rhui-ap-northeast-1-client-config-server-6                                                  Red Hat Update Infrastructure 2.0 Client Configuration Server 6                                                2
rhui-ap-northeast-1-rhel-server-releases                                                    Red Hat Enterprise Linux Server 6 (RPMs)                                                                  12,602
rhui-ap-northeast-1-rhel-server-releases-optional                                           Red Hat Enterprise Linux Server 6 Optional (RPMs)                                                          7,112
repolist: 30,655

これで、EPELにあるANSIBLE導入準備一段回目が整った。ANSIBLE導入は別記事で。

UITableViewの線を消す

iOS テクノロジー

デフォルトだとこうなってます。線があります。
画像は開発途中のモノなので、背景の色とか他の部品が写ってますが気にしないで下さい。

f:id:Humangas:20140522032452p:plain

それをこうしたい(線なし)。

f:id:Humangas:20140522032428p:plain


やり方

2つあって、コードでやる場合とInterfaceBuilderでやる場合です。

1:コードでやる場合

UITableViewのseparatorColor を クリアカラー(透明)に設定します。

self.tableView.separatorColor = [UIColor clearColor];

2:InterfaceBuilderでやる場合

  1. 対象のTableViewを選択
  2. Attributes Inspector を選択
  3. Separator > None を選択

f:id:Humangas:20140522032457p:plain

これで線が消えてます。

「ViewController ・・・ this class is not key value coding-compliant for the key XXX」の対処方法

iOS テクノロジー

ずっと、このエラーが出てハマった。

アプリをビルド&Runすると、return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));で止まる。

ログには以下とある。最後のkey aaa というのが、テストで取り敢えず作ったゴミ臭い。。

'[<ViewController xxxxxxxxx> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key aaa.'

原因

storyboardのゴミが原因らしい。 storyboard上でソースと接続したあとに削除してもMain.storyboardにゴミが残る場合がある。

直し方

ソースから直接ゴミを消す。

Main.storyboard > Open As > Source Code

f:id:Humangas:20140521170609p:plain

ゴミ(今回は、aaa というのがゴミに辿る鍵)をソース内から検索(Command+F)して、ゴミを行ごと削除

f:id:Humangas:20140521170546p:plain

この後、Command+R(Build+Run)すると、ちゃんと動くようになった。

2014-05-20_JAWS-UG東京-第21回-AWS-User-Group-Japan-東京勉強会に行ってきた

イベント AWS テクノロジー

色んなスタートアップ企業のCTOの方々が、ウチはこんなイケてるAWSの使い方してるよ。のLT大会。
イベント情報はコチラ


先にまとめ

よく出たプロダクト

  • fuluented:ログ収集
  • Chef:レシピでサーバ簡単構築
  • NewRelic:監視サービス
  • serverspec:サーバ状態テスト

コミュニュケーションツール

  • Qiita Team
  • ChatWork

一言感想

正直、あまりAWSの深い話はなかった。冒頭で書いたようなどの会社もよく使ってるプロダクトなどが知れて良かった。


01:スケールする開発組織の作り方、もしくは暗黙知を知らない組織、運営の仕方@伊藤直也氏

  • 現KAIZEN platform アドバイザー
  • プレゼンタイトル

資料

スケールする開発組織の作り方

結論

  • AWSでも手作業でやってたらいっしょでしょ
  • インフラをソフトウェア的に使う
  • 暗黙知から形式知へ

AWS、便利ですよね

  • 従量課金
  • S3、RedShiftとか使うだけでも意味ある(自前は大変)

EC2の構築どうしてますか?

  • 手作業、手順書、AMI スナップショットから復元・・・
  • インフラあるある:後で発覚→ SSHログイン→ 手で直しちゃう→ 作業ログ残すの忘れてる。。→ 暴力事件に発展w

なぜ、手作業はダメ?

  • 暗黙知化するから
  • → 暗黙知とは?: 特定の人間だけが知っていて言語化されてないなノウハウ
  • → 暗黙知を形式知(言語化された情報)にしよう

暗黙知を形式知へ

  • シッカリ手順書を書く?
  • いいえ、 Infrastructure as Code

インフラも、GitHubで。

  • ただ、コードで書けば良いわけというわけではなく、
  • コードで書けるってことは、インフラもアプリの開発スタイルが適用できる。てこと。
  • → つまり、業務フローが変わる。ということ。
  • → コードレビュー、変更履歴可視化、誰が実行しても同じ(=冪等なインフラ)

自動化はさほど重要ではない

  • 「属人化して不明なこと」 を減らす
  • → 暗黙知(分からないことへの不安や恐怖)→ 結果、保守的になる ← コレが良くない

組織論に拡大して考える

  • 組織のスケールアウトを阻害するのは「暗黙知」

形式知化へのプラクティス、例えば・・・

  • The Tweleve-Factor App
    • → クラウドに合わせたアプリのデザインパターンの緩めのやつみたいなもの
    • → Heroku にデプロイしまくってた人が何か気づいてまとめたらしい
    • 伊藤さんが、Immutable Infrastructure の話をする時によく出てくるらしい

現在のAWSやプロビジョニングFWに出来てないこと

  • メンタルモデルのコードへの反映
    • e.g. 野生動物を人間が見た時の危険と思う反応
  • 現状は「なぜ」が暗黙知化されがちなことを意識する必要
    • ドキュメント化?
    • 「なぜ」を理解しなくても使えるアーキテクチャ?
  • → こういう、「なぜ」そうしたのか。という部分はドキュメント化(文章にする)必要がある(今は)

まとめ

  • AWSでクラウドしたなら、業務フローもそれに合わせよう
  • Infrastructure as Code
  • 暗黙知から形式知へ
  • スケールする開発組織の作り方

質問

  • Qiita Teem以外で使ってるツールは?
  • → 今はQiita Teemで事足りてる。
  • → 前はWikiみたいなので仕様をまとめようとしていたが、自然に書かなくなる。
  • → 緩いコミュニュケーションの土台の上で発言しやすい空気を手伝うツールが良い感じ

02:WANTEDlyではどうAWS使ってるのか?@川崎氏

  • フロント: heroku、裏がAWS
  • サービス開始から2年間、Heroku使ってる

Herokuの継続的開発がしやすい

  • プロダクション環境:過去2年間、1日5回はデプロイしてた
  • ステージング環境:本番前に本番DBデータでテスト
  • QA環境:開発用とか外部の人のテストとかに使う

開発基本スタイル

  • Github + Wercher + heroku

Herokuの他の良い所

  • 気軽にスケールできる
  • 分単位課金
  • 30秒でインスタンス増やせる

言いたいこと

  • 最新テクノロジー使いたいと思うけど、グッと堪える
  • その技術を使う事自体を目的にしない

03:Sansan(Eight事業部)では、とことんAWSを使い倒す方針@宍倉氏

何してる会社?

  • あの名刺のアプリ

AWS肝

  • Amazon SWF使ってる
  • RDS + DynamoDB
  • 現在12のAWSサービス使ってる

KPIに求められること

  • 1イテレーション=1週間でPDCA回してる
  • 分かりやすい結果、情報共有、柔軟な分析が出来るツール

分かりやすい結果(メール配信)

  • Web/Batch→ FlyData → RedShift→ SESでメール配信(1回/日)

情報共有:Dashboard

  • DUCKSBOARD から見れるようにしてる

柔軟な分析が出来るツール

  • fulented→ SLASH-7というツールで分析

まとめ

  • AWSを使って開発に集中できる体制を作ってる

04:スマート エディション on AWS@谷川氏(@hiroyukky)

何してる会社?

  • 幼児向けの教育コンテンツ
  • スマートデバイス向けアプリ(Webサービスではない)
  • こどもモード、Gocco、KITS

AWS使いどころ

  • 世界へ配信しているのでS3+CloudFront
  • ピーク時間がはっきりしてるので、ウォーミング的なインフラ準備をしっかりCLIツールでやってる

まとめ

  • AWSはベーシックな構成
  • CLI使わないとAWS意味なしと思ってる

05:ChatWork AWSのおはなし@山本氏

何してる会社?

  • クラウド型ビジネスチャットツール
  • チャット+タスク管理
  • ブラウザ+モバイル
  • 現在:39万ユーザ、メッセージ数:3億、チャットルーム数:2000万
  • AWS規模:EC2:60、データサイズ:21TB

アーキテクチャ

f:id:Humangas:20140521161014j:plain

検索エンジン

  • mroonga 使ってた。いいんだけど、1億件しかむりなので。。
  • → elasticsearch 検証してたけど。。
  • → CloudSearch 日本語版でたので ← 今ココ(3億件さばけるか)
  • あと、Scalaはじめました

06:nanapi@和田氏

何してる会社?

  • ハウツーをまとめたサービス
  • 2000万UU/月間

サービス

  • nanapi、answer、IGNITioN

インフラ管理

  • 全部Chefでやってる
  • fluentdでlog集約
  • elasticsearch + kibana ← いい感じで見れるので、elasticsearch使ってる
  • newrelicで監視(iOSのアプリも良く出来てる)

07:BASE@渡邉氏

何してる会社?

  • ネットショップを誰でも簡単に作れるサービス
  • 特に書くことが。。。
  • 取り敢えず、スピーカーの方のトークは面白かった

08:ランサーズ@田邊氏

何してる会社?

  • クラウド型お仕事マッチングサービス運営
  • 毎月補修を得ている:4000人
  • 生活出来ている人:200人

今後は。。Immutable Infrastructureで。

  • Docker、Ansible、serverspecとかで。

まとめ

  • AWSをお安く使うためにスポットインスタンス有効活用しよう

09:アカツキ@田中氏

何してる会社?

  • ソーシャルゲームの会社

環境構築

  • CloudFormation + Chef + Capistrano
  • CloudFormation 公開してる

監視

  • CloudWatch→ アラートをチャットに流す
  • → そのままチャットに参加者の対応状況とか書けるのが良い

10:KAIZEN platform@石橋氏

何してる会社?

  • 元リクルートでエンジニアの石橋氏(調整さん作った)
  • 最初からグローバルで本社はサンフランシスコ
  • リモートワークを初めから考えてる
  • planBCD:A/Bテストが簡単に出来る
  • 最初から全部AWS使ってる

開発プロセスの改善

  • Developer Productivity Team
  • 自分達の働き方・仕事の仕方に感心を持つ

11:ビズリーチ@竹内氏

何してる会社?

  • BIZREACH、codebreak、LUXA(ルクサ)など やってる。

今日はルクサのことを話します

  • いわゆるグルーポン、ポンパレの類似サービス
  • 2000万PV/月
  • 250万UU/月
  • 会員数70万人
  • メール配信数:約1億通/月

とうことで:1億通のメールはどう送ってる?

  • SES使いたかったけど、始めお金なかったのでAWSで自前で作った

f:id:Humangas:20140521161226j:plain


12:イベントレジスト@池田氏

何してる会社?

  • 来場者10万人を超えるイベントプラットフォーム
  • 誰でもイベント告知が出来て、事前集金できる
  • BtoB(リード管理とか)に強い。ちなみに、AWS Summit Tokyo 2014でも採用

環境

  • fuluented、NewRelic etc..
  • Transifex:言語翻訳のWebサービス
  • AWSはオーソドックスなもの

xcodeでiosアプリのカスタムキーボードを作成する方法(UITextfieldのinputViewを独自UIに置き換える)

テクノロジー iOS

ググれば色々出たけど、欲しい情報が散らばっていたので自分用に纏めました。

やりたいことは、別ファイルで今後使い回したいUI部品を作成しておいて、それをコントローラから呼び出す形で使いたい。です。しかも、今回はカスタムキーボードを使いたいので、その部品をデフォルトで表示されるキーボードと置換えます。

Objective-C的に言えば、InterfaceBuilderで作成したUI部品(xibファイル)に対応する実装クラスをViewControllerの初期化時(viewDidLoad)にNewして、それをUITextFieldのキーボードを保持するinputViewプロパティに置き換える。という感じです。

完成形

こんな感じになります。
ちなみに、このキーボードはボタンのイメージ画像は作成しておらず、カラーとテキストのみで作成しています。

f:id:Humangas:20140519184117p:plain

なぜ、やりたい?

デフォルトの数値キーボードもあるんですが、キーボードを閉じるボタン(return)がありません。
はじめは、閉じるボタンを付けるために色々調べていてそれはそれで出来たのですが、その内全部オリジナルのキーボードが表示したくなったのでやることにしました。

そうすると、今度は全部コードでやるのはUIのレイアウトとか辛いのでInterfaceBuilderでUI部品作って、それを気軽に使えないか? ・・・と調べるうちにココまで来た感じです。

ちなみに、デフォルトの数値キーボードはこんな感じですね。 コード上でkeyboardType = UIKeyboardTypeNumberPadとすれば、これが表示されます。

f:id:Humangas:20140519184222p:plain

試した環境

  • Xcode:5.1.1
  • iOS SDK:7.1

ポイント

以下は、自分が調べた・ハマったところです。
このポイントを抑えれば、後はSingle View Application とかで普通にアプリを作る時のやり方でいけました。

  • カスタムキーボード.xibファイルとそれに対応するカスタムキーボード実装クラスを作成
    • → で、カスタムキーボード実装クラスの初期化処理で作成したxibファイル(UINib)をロードし、selfに置き換えればそのViewを使える
    • → で、メイン側(ViewControllerとか)で、そのカスタムキーボードインスタンスを作成すれば使える
  • カスタムキーボード.xibファイルのAutosizingを横調整のみに設定する
    • →そうしないと、デフォルトキーボードサイズ(縦が)になってしまう
  • UITextFieldのinputViewプロパティをカスタムキーボードクラスに置き換える
    • → コレで、キーボードを置き換えられる。

やり方

前述のポイントのところだけ書いてます。

カスタムキーボード作成

New File> iOS> User Interface> View でxibファイルを作成します。

f:id:Humangas:20140519193401p:plain

New File> iOS> Cocoa Touch> Objective-C class で、先に作成したxibファイルに対応する実装クラスを作成します。
ただ、この時点ではxibファイルと実装クラスはまだ紐ついていません。その設定は次に示します。

f:id:Humangas:20140519195917p:plain

作成するクラスは、UIViewを継承したクラスにします。

f:id:Humangas:20140519195854p:plain

作成したxibファイルを適当にいじってお好きなキーボードを作成します。
ここでのポイントは特にありませんが、この記事の始め(最終形)に示した私が作成しているキーボードの場合は、カラーを最近の流行りのフラットデザインカラーにしています。

このサイト:http://paletta.mrk1869.com/でカラーを選択して、16進数をこのサイト:http://www.peko-step.com/tool/tfcolor.htmlでRGBに変換して、InterfaceBuilderの各カラー設定に反映しました。

ちなみに、ボタンの大きさは、width:63px、height:63pxで、ボタンとボタンの間は1px空けています。 また、それぞれのカラーは以下の通りです。

  • キーボード背景:R17,G15,B23(#110f17)
  • ボタンテキスト:R239,G238,B244(#efeef4)
  • 数値ボタン背景:R60,G57,B70(#3c3946)
  • 数値ボタンフォントサイズ:20(「return」と「◁☓」のみ15)
  • 数値以外のボタン背景:R39,G38,B40(#272628)

カスタムキーボード.xibと実装クラスの紐付け設定(InterfaceBuilder)

Custom Class を作成した実装クラス名にします。

f:id:Humangas:20140519195445p:plain

いらないBar は、Noneにしておきます。

f:id:Humangas:20140519195946p:plain

Autosizing を横のみ自動設定にします。
これをしておかないと、inputViewを置換えてもデフォルトのキーボードサイズの縦サイズになってしまいます。

f:id:Humangas:20140519195443p:plain

カスタムキーボード.xibと実装クラスの紐付け設定(ソースコード)

CustomNumKeyboard.m(前述で作成したカスタムキーボード実装クラス)のinitでxibファイルをロードして自身(UIView)にセットします。
これで、xibファイルとそれに対応する実装クラスが関連づけられました。

-(id)init{
    
    self = [super init];
    if (self) {
        // UINibで作成したxibファイルを取得
        UINib *nib = [UINib nibWithNibName:@"CustomNumKeyboard" bundle:nil];
        // 0番目の要素(一番最初に置いたUIView)を取得して自分自身にセット
        // ※ self は、initメソッド内であれば代入できる
        self = [nib instantiateWithOwner:nil options:nil][0];
    }
    return self;
}

カスタムキーボードのボタン押下時アクション(メソッド)

対応付けただけでは、当然動かないので、各ボタンのアクションをCustomNumKeyboradクラスに実装します。

各アクション(メソッド)はIBActionで実装し、CustomNumKeyborad.xibファイルの各ボタンとInterfaceBuilder上で紐付けます。
数値キーボード押下時の処理とキーボードを閉じる処理だけ抜粋しておきます。

この実装では、各キーボードボタンのタグに数値ボタンに対応する数値を設定しておき、そのままテキストフィールドに表示するようにしています。

/**
 * 数値ボタン押下時処理
 *
 * @param sender 押下されたUIButton
 */
-(IBAction)numButton:(UIButton *)sender{
    NSString *numtag = [NSString stringWithFormat:@"%d", sender.tag];
    self.activeTextField.text = [self.activeTextField.text stringByAppendingString:numtag];
}

/**
 * return ボタン押下時処理
 * このViewに設定されたTextFieldのキーボードを閉じる
 */
-(IBAction)closeKeyboard:(id)sender{
    [self.activeTextField resignFirstResponder];
}

ここで、self.activeTextFieldというプロパティにアクションしていますが、これが処理したいUITextFieldです。
このUITextFieldは、CustomNumKeyboardのインスタンス生成時にプロパティに設定しておきます。設定できるように以下のようにヘッダクラスにプロパティを宣言しておきます。

@property (nonatomic, retain)UITextField *activeTextField;

コントローラからカスタムキーボードを利用

作成したカスタムキーボードは、以下のようにコントローラからインスタンス生成し、テキストフィールドのinputViewに設定すれば利用できます。InterfaceBuilder上でMain.stroyboardにテキストフィールドを接続しておいて下さい。

@implementation ViewController
{
    IBOutlet UITextField *kingakuTx;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    CustomNumKeyboard *cnkb = [CustomNumKeyboard new];
    cnkb.activeTextField = kingakuTx;
    kingakuTx.inputView = cnkb;
}

だぁーと書いたけど、説明がわかりづらいので気が向いたらちゃんと書きなおそう。いつか。。

AWSソリューションアーキテクト:アソシエイト 合格への道

AWS

2014/03/30に受かりました。総合スコアは70%(65%で合格)。

1回目であればまぁ良いかもしれませんが実は2回目です。1回目は、AWSトレーニング(※1)受けてからまだ勉強してないけど一回行ってみよと試しに受けてみて63%(おしい)。

で、今回も何やかんや当日までまともに勉強せず、一夜漬けになってしまったのですが、その一夜漬けのおかげで受かったところもあるので、その勉強法を書いておきます。

一夜漬け勉強方法

私の勉強方法はシンプルです。Amazonさんが毎週水曜日にやっているWeb講座マイスターシリーズの資料を試験登場頻度が高いサービスから読み倒す(「マイスターシリーズ EC2」とかでググるとすぐ引っ掛かります)。で、腹落ちしない事だけググって深ぼる(だいたいクラスメソッドさんの記事に行き当たります)。です。やったのはコレだけ。

あ、私のエンジニア属性としては、インフラエンジニア歴4年ぐらい(AWS半年ぐらい)。中途半端に全体的にポイントを理解している。アプリエンジニア歴4-5年(主にJavaを触っていた)ぐらいで、中途半端に知っている。という感じで、あまりバリバリ技術が詳しいと感じではないです。そういうエンジニアが試験合格までに勉強した方法だと思って下さい。

試験登場頻度の高いAWSサービス

なので、試験によく出るAWSサービスを抑えておかないといけません。あくまで自分が試験を受けた感覚値を書きますが。。。

  • めっちゃ出る:EC2、S3、VPC(Subnet、SG、NACL、NAT、IGW)
  • その次に出る:ELB、AutoScaling、EBS、IAM、RDS、CloudWatch
  • 各2−3問:SQS、SWF、SNS、ElastiCashe、Route53、CloudFormation, DynamoDB:
  • 1問ぐらい:Elastic MapReduce、CloudFront、Elastic BeansTalk、Glacier

以下のAWSサービスは今回出題されなかったですが、多分ランダムでこの辺のサービスも何かは出るかもしれません。試験の感じは、1回目試験受けた時とほぼ同じような気がする。。。

  • Direct Connect
  • Storage Gateway
  • RedShift
  • DataPipline
  • OpsWorks
  • CloudSearch
  • Elastic Transcoder
  • SES
  • etc...

試験内容の雰囲気

単にサービスの特徴だけ抑えていても合格は厳しいと思います。そういう問題もありますがほとんど無いです。そういう問題はサービス問題と捉えチャチャッと解答出来るようにしとくと確実に稼げます。問題数が55問と少なめなので、そういう問題を確実に抑えるのは重要です。

ほとんどは、「こういうアーキなんだけど、どーしたらいい?(最適?・動く?・効率良い?)」的な問題で、各サービス同士や設定の組合せ、既存のオンプレ知識(SSH、SSL、DNSとか)との組合せなどを問われます。

参考: マイスターシリーズ受講方法

毎週水曜日 18:00-19:00にAWSのソリューション・アーキテクトの方が、AWSの各種サービスなどについてオンラインセミナーを開いてくれてます。事前申し込みをしておけば、誰でも受講できます(無料)。

試験当日、会場でアタフタしないために

試験会場でいるものは、2つあります。

  1. 2種類の身分証明書
  2. 受験者認証コード

身分証明書は、私の場合、免許証とクレジットカード(署名済)を提示してOKでした。 これは、普段も持ってるので焦りはしませんが、問題は「受験者認証コード」です。

これは、6桁のアルファベットで表現されてるコードなんですが、受験申し込みをKRYTERIONで行った後、送付されてくるメール文中の真ん中ぐらいにシレっと書いてあります。忘れがちなので控えておいたほうが良いでしょう。もし、試験会場で気がついてしまったら、自分のメールを「認証コード」というワードで検索すれば出てくると思います。

※1:AWSトレーニング

私は、試験前にAWSのトレーニングArchitecting on AWSを受けていました。全3日間で講師はSAの方でした。このトレーニングすごい勉強になりますので会社でお金出してくれるとかなら受けたほうが良いと思います。値段は高いですが($1950なので個人ではシンドイ)。

特に、トレーニング中のグループワークでやった、要件定義書的な文章を読んで、Webアーキと、バッチアーキを書いてみよう。というのが面白く、かつ勉強になりました。自分が勉強すべき課題が見つかる。トレーニング方法としても面白かったので、社内勉強会でもそのアイデアを参考にさせてもらいました。

入門Chef Solo:17-レシピ落ち穂拾い ー run_list,ファイル分け,include_recipe

テクノロジー 入門Chef Solo

入門Chef Solo - Infrastructure as Code

入門Chef Solo - Infrastructure as Code

JSONファイル(Node Object)へのrun_listの書き方について、default.rb以外のレシピをどう書いて実行するのか。また、他のレシピ内容を取り込むinclude_recipeについても解説している。

run_listの書き方

{     
    "runt_list":[  
        "nginx::default",  
        "apache2",  
        "apache2::mod_ssl",  
    ]  
}  

この場合、以下がそれぞれ実行されます。

  • nginxクックブックのrecipes/default.rb
  • apache2クックブックのrecipes/default.rb
  • apache2クックブックのrecipes/mod_ssl.rb

run_listに渡しているものがレシピであることを明示するため

{
    "run_list":[
        "recipe[nginx::default]",
        "recipe[apache2]",
        "recipe[apache2::mod_ssl]"
    ]
}

とも書ける。

適用したいレシピをグルーピングするのにRoleという機能が使えて、run_listにはRoleを渡すこともできる。

{  
    "run_list":[  
        "recipe[yum::epel]",  
        "role[webserver]",  
    ]  
}  

レシピのファイル分け

レシピファイルを複数用意したいのはどういった場合なのか?→ 明示的なポリシーはChefにはない模様。
Opscode Communityで配布されているクックブックを見ることでなんとなくの方針が見える。

例えばapache2は、以下のように定義されている。

  • Apache本体・・・default.rb
  • mod_ssl・・・mod_ssl.rb

ファイル分けがなされていると、run_listを書くユーザーは「Apache本体は使いたいけど、mod_sslは不要」といったNode Objectを定義することができて便利。レシピをより汎用的に書くために、いういったファイル分けを意識する必要が出てくる。

include_recipe

あるレシピから、別のレシピの内容をそのまま取り込みたい場合、
include_recipeを使用してレシピに、

include_recipe "bulid-essential::default"  

と記載することで、build-essentialというレシピを取り込む。 (build-essentialクックブックがcookbook pathの通ったディレクトリに配置されている前提)

include_recipeを使いたいというケースはあまり多くない。
サードパーティのクックブックを利用したりする場合に、include_recipeすることを前提に書かれていることがあり使う必要に迫られるかもしれない。

include_recipeに似た概念として、レシピ内に他のクックブックとの依存関係を記述する dependencyというシンタックスもあるが、Chef Soloでは利用しない。