AWS初心者が本を1冊やってみて学んだことメモ

AWSを使い始めて5日目。ググれどググれど大枠が見えないのでさっぱりわからない。
というわけで本を1冊ハンズオンでやってみました。
内容を忘れないようにメモしておきます。

やった本

『Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版』 日経BP社

アプリ開発は勉強したけど、インフラはさっぱりわからない…そんな自分にぴったりでした。
インフラエンジニアの間では常識なのだろうな(TCP/IPとかHTTPメソッドとか)…ということも丁寧に繰り返し説明してくれています。

学んだこと

IPアドレスとは

TCP/IP通信において、通信先を特定するのに使われるのがIPアドレス。ネットワーク上で互いに重複しない唯一無二の番号、いわゆる「住所」に相当する。

パブリックIPアドレス

インターネットに接続する際に用いるIPアドレスのこと。グローバルIPアドレスとも言う。重複を避けるためICANNと言う団体が一括管理している。

プライベートIPアドレス

インターネットで使われないIPアドレス。10.0.0.0 ~ 10.255.255.255など、範囲が決められている。誰にも申請することなく使える。社内LAN構築時や、自前でネットワークの実験をするときはこれを使う。

ホスト

コンピュータやルーターなどのネットワーク機器など、IPアドレスをもつ通信機器の総称。

VPC領域

VPC = Virtual Private Cloud
つまり、プライベートなネットワーク空間。
作成したユーザーが自由に扱うことができる空間で、他のユーザーからは全く見えない。
IPアドレスをCIDR表記する場合、その範囲は「CIDRブロック」と呼ばれる。
このCIDRブロックをさらに小さなCIDRブロックに細分化したものをサブネットと呼ぶ。

同書を元に作成した図。
image

パブリックサブネット:インターネットからアクセスできる
プライベートサブネット:インターネットからはアクセスできない
→セキュリティを高める時によく用いられるネットワーク構成

サブネットをインターネットに接続するには、「インターネットゲートウェイ(Internet Gateway)」を用いる。自分のネットワークにインターネット回線を引き込むイメージ。

ルートテーブル

宛先IPアドレスの値がいくつのときに、どのネットワークに流すべきか、と言う設定。

「宛先アドレス」 「流すべきネットワークの入り口となるルーター」

という書式で設定。
宛先アドレス=ディスティネーション(destination)
流すべきネットワーク先=ネクストホップ(next hop)、ターゲット(target)

TCP/IP

ポート(Port):他のコンピュータと、データを送受信するためのデータの出入り口

ポートには、以下の2種類がある。
TCP(Transmission Control Protocol):相手にデータが届いたことを保証する。
UDP(User Datagram Protocol):確認せずに送信する(その代わりに高速)

ファイアウォール

「通してよいデータだけを通して、それ以外を遮断する機能」の総称。
そのもっとも簡単な構造のものがパケットフィルタリング(Packet Filtering)。

パケットフィルタリング

流れるパケットをみて、通過の可否を決める仕組み。パケットには、「IPアドレス」のほか「ポート番号」も含まれている。パケットフィルタリングは、「IPアドレス」と「ポート番号」など、パケットに付随する各種情報を見て、通過の可否を決める。
AWSでは、インスタンスに対して構成する「セキュリティグループ」がこの機能を担当する。

インバウンドとアウトバウンド

インバウンド:外から、このインスタンスに接続する向き(例 誰かが接続しようとしているのを排除する)
アウトバウンド:このインスタンスから外に出て行く向き

NAT

NAT=Network Address Translation
「プライベートサブネット→インターネット」の向きの通信だけを許可する。

例えば、DBサーバーはインターネットからは接続されたくない。しかし、サーバーのアップデートやソフトウェアのインストールのために、DBサーバーからインターネットへは接続できるようにしたい。そういうときは、DBサーバー(プライベートサブネット)→インターネットの一方向の通信のみを許可できる。

curlコマンド

「HTTPやFTPで、ファイルをダウンロードしたりアップロードしたりするコマンド」。Amazon Linuxにはtelnetコマンドがインストールされていないため、代わりにcurlコマンドを使う。

続きを読む

AWSでExcelからPDF変換を行う

Excelの見た目のままPDFを作成するために、libreconvを使用してExcelからPDFへconvertをしてみた

環境

  • Amazon Linux
  • Ruby 2.3.0
  • Ruby on Rails 5.0.1

AWSにLibreOfficeをインストールする

$ sudo wget http://ftp.yz.yamagata-u.ac.jp/pub/tdf/libreoffice/stable/5.3.3/rpm/x86_64/LibreOffice_5.3.3_Linux_x86-64_rpm.tar.gz
$ tar xvzf LibreOffice_5.3.3_Linux_x86-64_rpm.tar.gz
$ cd LibreOffice_5.3.3.2_Linux_x86-64_rpm/
$ cd RPMS/
$ sudo yum install *.rpm
$ sudo yum install dbus-glib

gemのインストール

Gemfileに下記を追加
gem 'libreconv'

実装

  require 'libreconv'

  def convert_pdf
    Libreconv.convert('public/sample.xlsx', 'public/sample.pdf')
  end

出力されるpdfはxlsxで指定した印刷イメージで作成されるようだが、指定のフォントがない場合は、多少印刷イメージがずれることがある。
印刷イメージがずれる場合は適宜フォントをインストールする必要がある。

続きを読む

:beginner: Amazon EC2 Simple Systems Manager (SSM) エージェントのインストール

:beginner:
Amazon EC2 Systems Managerを使用するためのエージェントを導入するまでの手順です。
内容としては初心者向けになっています。

前提条件

SSMエージェントの導入対象インスタンスからS3へのアクセス(HTTPS)が出来る必要があります。

Simple Systems Manager 用の管理ポリシーを追加

SSMを使用したいインスタンスに割り当てているIAMロールへSSMの管理ポリシーをアタッチする。

ロールがない場合は作成する。
2017-06-21-14-20-20.png

「AmazonEC2RoleforSSM」を選択し「ポリシーのアタッチ」を実施する。
2017-06-21-14-23-37.png

2017-06-21-14-26-28.png

Simple Systems Manager エージェントのインストール

:warning: Amazon Linux、RHEL、および CentOS 64 ビット の 東京リージョンの場合の手順

新規インスタンスの場合はユーザーデーターに以下を追加で定義する。

#!/bin/bash
cd /tmp
sudo yum install -y https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm

既に稼働中のインスタンスの場合はログイン後に以下のコマンドを実行する。

sudo yum install -y https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm
[ec2-user@ip-10-0-2-141 ~]$ sudo yum install -y https://amazon-ssm-ap-northeast-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm
Loaded plugins: priorities, update-motd, upgrade-helper
amazon-ssm-agent.rpm                                            | 6.0 MB  00:00:00
Examining /var/tmp/yum-root-Mncwuv/amazon-ssm-agent.rpm: amazon-ssm-agent-2.0.822.0-1.x86_64
Marking /var/tmp/yum-root-Mncwuv/amazon-ssm-agent.rpm to be installed
Resolving Dependencies
amzn-main/latest                                                | 2.1 kB  00:00:00
amzn-updates/latest                                             | 2.3 kB  00:00:00
--> Running transaction check
---> Package amazon-ssm-agent.x86_64 0:2.0.822.0-1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=======================================================================================
 Package                Arch         Version             Repository               Size
=======================================================================================
Installing:
 amazon-ssm-agent       x86_64       2.0.822.0-1         /amazon-ssm-agent        17 M

Transaction Summary
=======================================================================================
Install  1 Package

Total size: 17 M
Installed size: 17 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : amazon-ssm-agent-2.0.822.0-1.x86_64                                 1/1
amazon-ssm-agent start/running, process 7104
  Verifying  : amazon-ssm-agent-2.0.822.0-1.x86_64                                 1/1

Installed:
  amazon-ssm-agent.x86_64 0:2.0.822.0-1

Complete!
[ec2-user@ip-10-0-2-141 ~]$

Simple Systems Manager エージェントの起動確認

[ec2-user@ip-10-0-2-141 ~]$ sudo status amazon-ssm-agent
amazon-ssm-agent start/running, process 7104
[ec2-user@ip-10-0-2-141 ~]$

ちなみにAmazon Linux の場合 Upstartでの管理になります。

[ec2-user@ip-10-0-2-141 ~]$ sudo initctl list |grep amazon-ssm-agent
amazon-ssm-agent start/running, process 7104
[ec2-user@ip-10-0-2-141 ~]$

Simple Systems Manager への登録確認

EC2 の「SYSTEM MANAGER共有リソース」の「マネージドインスタンス」を選択します。

エージェントをインストールしたインスタンスが登録されていることが確認できます。
2017-06-21-15-11-56.png

続きを読む

AmazonECRとEC2を使って手元でビルドしたDockerイメージをAWS上でサクッと動かす

ECR(EC2 Container Registry)に登録したDockerイメージをEC2上でコンテナとして起動するまでの一通りの流れを書いてみた
ECSも一通り検証終わっていて、サービスではそちらを使う予定だが、基礎を振り返るという意味でのまとめ。

Docker

ここ一ヶ月ひたすらdockerを触っているが、やはり手元の開発環境で動いたものが、別の環境でそのまま動くというのは他にないメリット。
これまでだと、開発環境でOK→STでまた一から作る→本番でも同じくみたいなことしてたけど、ホスト側にDockerエンジン入れるだけで、実際のプロセスは開発環境のものをそのまま移植出来るというところはかなり熱い。といった印象。

やること

  • ECRを使う準備
  • ECRへのDockerイメージの登録
  • EC2作成
  • EC2上にECRからpullしたDockerコンテナを立てる

ECRとは

正式名称 EC2 Container Registry
Amazonが提供するフルマネージドのDockerコンテナレジストリ。
Dockerイメージを管理して、ECS(EC2 Container Service)やEB(Elastic Beanstalk)に簡単にデプロイすることが出来るソリューション

ECR使うと何がうれしい

  • EC2インスタンスにIAMroleを付与するだけ、EC2側で面倒な認証をせずにdockerイメージを使える
  • S3がバックエンドなので、可用性高い
  • 自動的に暗号化されたり、https通信されるのでセキュリティも安心

ECRを使う準備(ローカルマシンで実施)

AWS Command Line Interface のインストール を参考にAWS CLIを手元のマシンにインストールしておく。

基本的には、AWS CLIで操作する。

1.リポジトリの作成&確認

$aws ecr create-repository --repository-name tst-shnagai
{
    "repository": {
        "registryId": "xxxxx",
        "repositoryName": "tst-shnagai",
        "repositoryArn": "arn:aws:ecr:ap-northeast-1:xxxxx:repository/tst-shnagai",
        "createdAt": 1496229520.0,
        "repositoryUri": "xxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai"
    }
}

リポジトリは、GUIから見ると、ECSサービスの中の[リポジトリ]に出来る

Amazon_EC2_Container_Service.png

2.ecrにログイン

セッションは12時間なので、感覚的に翌日には切れてる感じ。

## これで一発

$ $(aws ecr get-login --region ap-northeast-1)
Flag --email has been deprecated, will be removed in 17.06.
Login Succeeded

## $()の式展開を使わない場合

$ aws ecr get-login --region ap-northeast-1
docker login -u AWS -p eyJwYXlsb2FkIjoicURLTkxCTFhobUJuSTRxSDRNSUFBOEprc0txSnVuTVgrdzRzNkl4NU5rRDUxM0N...
### 標準出力の結果を貼り付けてログイン
$ docker login -u AWS -p eyJwYXlsb2FkIjoicURLTkxCTFhobUJuSTRxSDRNSUFBOEprc0txSnVuTVgrdzRzNkl4NU5rRDUxM0N...
Login Succeeded

ECRへのDockerイメージの登録(ローカルマシンで実施)

手元にある何かしらのDockerイメージをECRにpushする手順
手元で、Dockerイメージに対して、ECR用のタグづけを行ってから、ECRにpushする

1.docker tagコマンドでタグづけをする

今回は例として元々手元にある[apache_td]というdockerイメージに対して、ECRのルールに沿った名前でタグ付け(aliasつけるようなもの)する

## 元々のイメージ
$ docker image list |grep apache_td
apache_td                                                         latest              2c42dd3f5e5c        13 days ago         1.4GB

## タグ付けを実施
$ docker tag apache_td:latest  xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest

## imageIDは変わらないので、下記のような検索するとapache_tdがECRに対応したイメージとしてタグ付けされたことがわかる
$ docker image list |grep 2c42dd
xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai     latest              2c42dd3f5e5c        13 days ago         1.4GB
apache_td                                                         latest              2c42dd3f5e5c        13 days ago         1.4GB

2. 1でタグづけしたDockerImageをECRにpushする

$ docker push xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest
The push refers to a repository [xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai]
47d1cbb6b480: Layer already exists
...
latest: digest: sha256:14b7a5d491fa694c00f026bbc6c6cd09e0ddc63d0e586569a0de42a8ce7ec5d1 size: 2411

GUIで、タグ名とプッシュされた日時を確認して無事イメージがアップされていることを確認する

Amazon_EC2_Container_Service.png

ここまでで、ECRへのDockerイメージの登録は完了!!

EC2インスタンスの作成

1.通常通りEC2インスタンスを作成する(OSはデフォルトでawscliが入っているamazon linuxだと楽)

ポイントは、IAMRoleに[AmazonEC2ContainerRegistryReadOnly]ポリシを付与しておくことのみ

IAM_Management_Console.png

2. dockerのインストール

AWSの公式ドキュメントに沿ってやるだけなので、コマンドだけ羅列
Docker のインストール

ec2-userでdockerコマンドがsudoなしでうてるとこまでやっておく。

$ sudo yum update -y
$ sudo yum install -y docker
$ sudo service docker start
### ec2-userでsudoなしでdockerコマンドを打てるようにするため
$ sudo usermod -a -G docker ec2-user
###再ログイン
$ docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 17.03.1-ce

EC2上にECRからpullしたDockerコンテナを立てる(EC2上で実施)

1. ECRへのログイン

IAMRoleがついていない場合は、ログインで弾かれる

$ $(aws ecr get-login --region ap-northeast-1)
Login Succeeded

2. ECRからDockerイメージをpullする

## ECRにアップロードしたイメージをpull
$ docker pull xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest
latest: Pulling from tst-shnagai
996fe98f55d8: Pull complete
...
e6b377ddca6e: Pull complete
Digest: sha256:14b7a5d491fa694c00f026bbc6c6cd09e0ddc63d0e586569a0de42a8ce7ec5d1
Status: Downloaded newer image for xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest

## 手元のイメージとして登録されたことを確認
$ docker image ls
REPOSITORY                                                      TAG                 IMAGE ID            CREATED             SIZE
xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai   latest              2c42dd3f5e5c        13 days ago         1.4 GB

3. dockerコンテナを起動する

pullしてきたイメージからコンテナを起動する

## ホストの8080ポートにマッピングするtestという名前のコンテナを起動する
$ docker run -d --name test -p 8080:80 xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest
dbbb74b6ebe95666d356250de8310c19403078f53e020069e9a6d10e479b2873

## -lオプションで最後に起動したコンテナを表示
$ docker ps -l
CONTAINER ID        IMAGE                                                                  COMMAND                  CREATED             STATUS              PORTS                  NAMES
dbbb74b6ebe9        xxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/tst-shnagai:latest   "/bin/sh -c '/bin/..."   4 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp   test

## 動作確認として、ホストの8080に対してcurlでリクエストしてみる
$ curl localhost:8080
version 1.2

まとめ

オーソドックスな、AWSでECRを使ってdockerコンテナを起動する一通りの流れをやってみた。dockerを手元で触ってる人だったら、特に躓くことなくやれる内容だと思う。
ECSは、基本オペレーション(この投稿でいうEC2以降の話)を抽象化して、クラスタというEC2集合体の上で、ELB,AutoScaling等を付加して使えるサービスなので、ココら辺をちゃんと理解してやるとやらないでは進みがだいぶ違うという印象を受ける。
裏で何が行われてるのかなという道理を理解することは大事。

続きを読む

AWS LambdaからEC2上のPythonを実行(Run Command)する際の注意点

http://qiita.com/tf_qiita/items/90b4ec315d179b5d9b9c

上記の問題を解決したのでメモ。

手順1:実行バージョンの指定

LambdaからEC2 Run Commandを利用するとき、Run Commandは対象のEC2インスタンスで有効となっているPythonの実行ファイルではなく、そのインスタンスの初期状態で設定されているバージョンを実行します。(Amazon Linux系ならば今日現在は2.7.12)

そのため、標準と異なるバージョンのPythonを実行する場合は、下記のようにLambdaに記述するRun Commandで実行ファイルをフルパスで指定します。
下記の例ではpyenvに構築した環境を指定しています。
Lambdaはroot実行となるため、pyenvをrootで構築していますが、直接指定して実行するのであれば実行用のユーザを構築するで良いと思います。

lambda.py
ssm.send_command(
    InstanceIds = instances,
    DocumentName = "AWS-RunShellScript",
    Parameters = {
        "commands": [
            "/root/.pyenv/versions/anaconda3-4.4.0/bin/python /work/hoge.py", 
        ],
        "executionTimeout": ["3600"]
    },
)

手順2:ライブラリパスの追加

手順1では環境変数に実行するPythonのパスを追加せずに所要のバージョン(環境)を実行するため、そのままではライブラリのimportができません。
そのため、Lambdaから呼ばれるEC2側のスクリプトの先頭でsite-packagesのパスを追加することで、ライブラリを読み込むことができるようになります。
下記の例では手順1で指定した環境配下のsite-packagesを指定しています。

ec2.py
import sys
sys.path.append("/root/.pyenv/versions/anaconda3-4.4.0/lib/python3.6/site-packages/")

感想

当初からパス周りの問題と想定はしていましたが、Lambda側とEC2側で原因の切り分けに手間取ってしまいました。
また、バージョンが指定が機能として提供されているのか調査することに無駄な労力を使ってしまうといった、マネージドサービスならでは?の失敗がありました。
今後も同様な低レイヤでのつまづきが予見されますが、その際はこの経験を思い出して基本に立ち返って考えたいです。

続きを読む

パーティションされていないマウントされている EBS をオンラインで拡張する(XFS編)

Amazon EBSのアップデートで 「エラスティックボリューム」の発表 でずっと試してみたいなと思っていたのをテストしてみたので記事にします。

Qiitaを見ると既に一杯記事が上がっています。

1.まずボリュームサイズの変更
EBSボリュームのサイズ変更をやってみる – Qiita
 –>この記事ではボリュームサイズの変更のみ

2.ルートデバイス以外の場合
Amazon LinuxにアタッチされているEBSのボリュームサイズを拡張する。 – Qiita
 –>スクリーンショット付きで分かりやすいです。初心者向け

3.ルートデバイスのEBSでは一手間必要です
オンラインでEC2のルートディスクを拡張する – Qiita
 –>そのまま、resize2fs ではダメなようです
   sudo growpart /dev/xvda 1を追加作業しています

4.結論だけとっととみたい人向け
rootにmountされているEBSを、mountしたまま拡張する手順 – Qiita
 –>いきなり、growpart /dev/xvda 1 してます

5.Ubuntuでも同様にリサイズ可能です
AWS EBSのルートディスク拡張した際のサイズ拡張のやりかた – Qiita
 —>Ubuntu 14.04です

6.再起動すると適用されます
EC2のボリューム(EBS)容量拡張方法検証 (AmazonLinux) – Qiita
 —>実は再起動したときに自動的に拡張されるようです。
   再起動可能で手間を省きたい人向け

7.最後は自動でリサイズされるスクリプトです
AWS EBSのリサイズをシェルスクリプトにまとめてみた – Qiita
 –>費用を最小限に抑えられますね。

他にも記事がありましたが、ボリュームをデタッチしたりしていたので除外しました。

で、今さら感は非常にあるのですが、XFSでやってみた人がいないので書いてみます。
作業した OS は CentOS-7.3 Official Image です。

1. ボリュームを用意

今回は、ルートボリューム以外の場所をNFSデータ領域としてつかってみることにしたので、10GiBほどEBSを作ってみました。

image.png

アタッチが終了したので Diskの状況はこんな感じです

[root@ ~]# lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  200G  0 disk
└─xvda1 202:1    0  200G  0 part /
xvdg    202:96   0   10G  0 disk

xvdg として接続されています。

2. XFSでフォーマットする

NFSのデータ領域として使うのでXFSを選択しました。
パーティションを作るとボリューム拡張した時にパーティションも拡張しないといけないので、パーティション無しでXFSをフォーマットします。

[root@ ~]# mkfs.xfs /dev/xvdg
meta-data=/dev/xvdg              isize=512    agcount=4, agsize=655360 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=2621440, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

3. マウントします

マウントしてみますが、とりあえずテスト用のディレクトリにマウントしてみます。

[root@ ~]# mkdir /test_mount
[root@ ~]# mount /dev/xvdg  /test_mount/
[root@ test_mount]# df -h
Filesystem      Size  Used Avail Use% Mounted on
  <<<中略>>>
/dev/xvdg        10G   33M   10G   1% /test_mount

大丈夫のようです

4. ボリュームを拡張する

ボリューム拡張の方法は記載しませんが、以下のように20GiBに拡張されました。
image.png

以下のように増えています。

[root@ ~]# lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
  <<<中略>>>
xvdg    202:96   0   20G  0 disk /test_mount

5. ファイルシステムをリサイズする

この状態では、ファイルシステムは以下のままです。

[root@ test_mount]# df -h
Filesystem      Size  Used Avail Use% Mounted on
  <<<中略>>>
/dev/xvdg        10G   33M   10G   1% /test_mount

xfs_growfs コマンドでXFSファイルシステムを拡張します

[root@ test_mount]# xfs_growfs /dev/xvdg
meta-data=/dev/xvdg              isize=512    agcount=4, agsize=655360 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=2621440, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2621440 to 5242880

6. 拡張されたか確認する

確認してみます。

[root@ test_mount]# df -h
Filesystem      Size  Used Avail Use% Mounted on
  <<<中略>>>
/dev/xvdg        20G   33M   20G   1% /test_mount

増えてますね。

7. まとめ

パーティションを切らずにファイルシステムを作れば簡単にファイルシステムを拡張出来ることが分かりました。ますます、AWSが便利に使えそうです。

#この記事を書く前は、「パーティションを切らずにファイルシステムをフォーマットできる」と言うことを知らず、ボリューム全体を一つのパーティションにする方法ばかり調べていました。ボリュームをそのままファイルシステムでフォーマットすればいいということを知ったので書いてみました。

続きを読む

AWSでWebサイトを作りますか。

AWSのEC2でWordPressを使ってサイトを作った備忘録。変な所でハマったので。
EC2上にAmazon Linux AMI乗っけてその上でApache起動させてそこにWordPress乗せるという回りくどいことをやっているのであんまり参考にならないかも……。

AWSへの登録

AWS公式の「まずは無料で登録」から。日本語だからわかりやすい。

使えるクレジットカードが必要なのは要注意。
AU WalletはMastercardなはずなんだけどダメでした。

EC2インスタンスの作成

認証が終わったら、左上の「サービス」をクリック。
使うことの出来るサービス一覧がずらりと並んでます。
その中で左上の「EC2」を選択。
170617.PNG

青い「インスタンスの作成」ボタンを押すとインスタンスが作成できる……のだが、その前に自分が今どこのリージョンを使っているのかを確認する。
これは右上、自分の名前の横に書いてある。
170617-1.PNG
自分の場合はバージニア北部ですね。

AWSでは、作成したインスタンスは「(アカウント名)が(リージョン名)に作ったインスタンス」ではなく「(リージョン名)に保管されている(アカウント名)が作ったインスタンス」みたいな感じで管理されているみたいです。
なので、インスタンスを作ってから右上を弄ってリージョンを変えると見た目上作成したインスタンスが消えます
あくまで見た目上なので、当然リージョンを移動すればまた見えるようになります。よいこのみなさんはわたしみたいに「き、消えた!?」と焦らないようにしてください。
逆に、インスタンスが消えた!?と思ったらまずは自分のいるリージョンを確認しましょう。

この時参考にしたブログ

リージョンを確認したらインスタンスを作っていきます。
とは言っても、画面に表示されるものを読みながらやっていけばできます。
自分はこのあたりを参考にしつつやりました。

この時、下の青いボタンを押すとその後の設定をすっ飛ばしてインスタンスを作ってくれます。
親切なんだか不親切なんだかわからん……。

自分はここでAMIにAmazon Linux AMIを入れてしまいましたが、実はここで直にWordPressが選べるみたいです。左メニューの「AWS Marketplace」をクリックしてから検索窓に「WordPress」と入れて検索してみてね!

最後に公開鍵と秘密鍵のキーペアを作成します。プルダウンから「新しいキーペアの作成」を選び、適当な名前を付けてDL。これは後で必要になるので、どこに保存したか忘れないようにしておきましょう。

セキュリティグループ

無事にインスタンスが作成出来たらインスタンスの管理画面になります。
インスタンスの状態が「Running」になったら(大体一分位?)、SSH接続に必要なセキュリティグループの設定をします。
インスタンスを選択して「説明」タブを見ると、今使っているセキュリティグループがわかります。
これをクリックするとセキュリティグループの設定へ飛べます。

170617-2.PNG

セキュリティグループの設定ページで「インバウンド」タブを選択するとこんな感じ。
最初は「HTTP」しか無いと思うので、「編集」→「ルールの追加」でSSHを作ってやりましょう。
170617-3.PNG

本当はソースをちゃんと指定してあげたほうがいいんですが、使ってる回線が可変IPなので……。
固定IPを持っているよいこのみなさんはちゃんと指定しましょうね。

SSH接続

さっき作った秘密鍵をPuTTYごった煮版内のPuTTYgenから「読込」してやってPuTTY用の秘密鍵ファイルを作ります。
「全てのファイル(*.*)」で探すのを忘れずに。じゃないと見えません。
そして.ppk形式で保存。パスワードはかけておいたほうが良いでしょう。

PuTTYの設定は下記の通り。

フィールド
セッション>ホスト名 ec2-user@(パブリック DNS (IPv4))
セッション>ポート 22
セッション>接続タイプ SSH
接続>SSH>認証>認証のためのプライベートキーファイル (上で作った.ppkファイル)

セッション一覧で適当な名前をつけて「保存」したら「開く」で接続を始めます。
初回はダイアログが出ますが「OK」でスルー。
秘密鍵のパスワードの入力を求められたら入力。
AMIの起動画面が出たら成功です。

この辺の話は公式のガイドページが詳しいです。

Apacheのインストール

インストール。

# sudo yum -y install httpd

起動。

# sudo service httpd start

わーいらくちーん。
この時点でブラウザからhttp://(パブリック DNS (IPv4))を見てみるとテストページが見れます。

WordPressのインストール

まずはWordPressに必要なPHPとMySQLをインストール。

# yum install httpd mysql-server php php-mysql wget

/etc/php.iniを弄ってタイムゾーンの設定をしときます。

# vi /etc/php.ini
 ; Defines the default timezone used by the date functions
 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
 date.timezone = "Asia/Tokyo"

ここを参考にしつつMySQLの設定。
このページに沿ってやるとwpという名前のデータベースとwpという名前のユーザが出来上がっています。

WordPress本体を落としてきて解凍。
さらにApacheがWordPressを読み込めるようにしておく。

# cd /tmp
# wget http://ja.wordpress.org/wordpress-4.8-ja.tar.gz
# tar zxvf wordpress-3.5.1-ja.tar.gz 
# cp -r wordpress /var/www/
# chown -R apache.apache /var/www/wordpress

/etc/httpd/conf/httpd.confを弄って、

  • DocumentRootをWordPressにし、
  • DocumentRootのディレクトリに対して.htaccessによる上書きを許可しておく。
# vi /etc/httpd/conf/httpd.conf
 DocumentRoot "/var/www/wordpress"
 (中略)
 <Directory "/var/www/wordpress"> ←ここをちゃんとDocumentRootと同じにしておく
     AllowOverride All

WordPressの設定ファイルを作る。
予めサンプルファイルが用意されているので、それをコピーして……

# cd /var/www/wordpress
# sudo cp wp-config-sample.php wp-config.php

書き換え。

# vi wp-config.php

 // データベース情報を設定します。
 define('DB_NAME', 'wp');
 define('DB_USER', 'wp');
 define('DB_PASSWORD', 'password');
 define('DB_HOST', 'localhost');
 define('DB_CHARSET', 'utf8');

 // 「put your unique phrase here」を 適当な文字列に置き換えます。
 define('AUTH_KEY',         'put your unique phrase here');
 define('SECURE_AUTH_KEY',  'put your unique phrase here');
 define('LOGGED_IN_KEY',    'put your unique phrase here');
 define('NONCE_KEY',        'put your unique phrase here');
 define('AUTH_SALT',        'put your unique phrase here');
 define('SECURE_AUTH_SALT', 'put your unique phrase here');
 define('LOGGED_IN_SALT',   'put your unique phrase here');
 define('NONCE_SALT',       'put your unique phrase here');

自分はここでPuTTYの文字コードをUTF-8にしていなかったため、viでwp-config.phpを開いた瞬間に画面を文字化けしたものが覆うという大惨事になってしまいました。
その時にwp-config.phpが壊れてしまったようで、ファイルの上半分が消失するという事態に……。
バックアップって大事だね!(もう一度cp wp-config-sample.php wp-config.phpしながら)

ここで再びhttp://(パブリック DNS (IPv4))を覗いてみるとWordPressの初期設定画面が開きます。
もしも「データベース接続確立エラー」と出るならwp-config.phpのデータベース情報のどこかが間違ってます。
もしもwp-config.phpの中身が表示されているようならSyntax Errorです。直しましょ。

独自ドメイン設定

サイト自体は完成したので次はドメインとパブリックDNSを紐付けてやります。

これを参考にしてElastic IPを作成、ついでRoute53を設定。Whoisが更新されたのを確認してからドメインをブラウザに入れてみると……。

動かない。何故だ。

正確に言うと、動いてはいるっぽいけどサイトのテキストしか表示されない。
その状態で色々弄っていたら、あることに気づく。

管理画面に遷移しようとすると新たに設定したElastic IPではなく以前のパブリックDNSが出る。

ちょっと調べてみたらこんなページが。
なるほど、DBには前のパブリックDNSしか登録されてないからこうなるのね。
変えてやったら無事動きましたー!よかったー。

さて、あとはサイト本体を作るだけだ……。

続きを読む

EC2上にhubotを設置してslackと連携させる

最近ChatOpsに興味が出てきたので、とりあえずEC2上にhubotが動作する環境を作り、slackと連携出来るようにしました。

前提

以下の環境が既にあること。

  • EC2
  • slack

環境構築

  • nvm〜hubotの起動までは全てEC2上での作業です。

nvmのインストール

  • curlでインストールします
sudo curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
  • .bash_profileに以下を追記します
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
  • nvmコマンドが実行できることを確認します
nvm help

nodejsのインストール

  • nvmでnodejsのv6.11.0をインストールします
  • 公式サイトを見ると includes npm 3.10.10 と書いてあるのでnpmも一緒にインストールされます
nvm install 6.11.0
  • インストールされたことを確認します
node -v
npm -v

redisのインストール

  • elasticacheは使わずAmazon Linux上にredisをインストールします
  • epelだとバージョンが古いようなのでremiを利用します
sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
sudo yum --enablerepo=remi install redis
  • redisを起動させます
sudo service redis start

hubotのインストール

  • hubotの環境を構築します
  • npmでhubot,coffescript,redis,yo,generator-hubotをインストールします
npm install -g hubot coffee-script redis yo generator-hubot
  • hubotをインストールします
mkdir -p ~/deploy-sushi
cd deploy-sushi
yo hubot
  • 対話式で色々聞かれるので自身の環境に合わせて入力してください
? ==========================================================================
We're constantly looking for ways to make yo better!
May we anonymously report usage statistics to improve the tool over time?
More info: https://github.com/yeoman/insight & http://yeoman.io
========================================================================== Y/no


省略


? Owner (User <user@example.com>)
? Bot name (deploy-sushi)
? Description (A simple helpful robot for your Company)
? Bot adapter (campfire)
  • 今回は?4つに以下のように答えました
? Owner {MY_EMAIL}
? Bot name deploy-sushi
? Description this is deploy boy
? Bot adapter slack
  • hubotを立ち上げて動作確認をします
bin/hubot
  • いろんなメッセージが出た後にEnterを押せば deploy-sushi> という対話が始まります
deploy-sushi> deploy-sushi ping
deploy-sushi> PONG
  • hubot-slackをnpmでインストールします
npm install hubot-slack

slackと連携させる

  • slack上の操作に変わります
  • slackのサイドメニューを開き Configure Apps を開きます

スクリーンショット 2017-06-17 14.12.32.png

  • 画面上部に Hubot を入力し、検索結果をクリックします

スクリーンショット 2017-06-17 14.16.11.png

  • Installボタンをクリックします

スクリーンショット 2017-06-17 14.17.17.png

  • hubotの名前を入力して Add Hubot Integrationをクリックします

スクリーンショット 2017-06-17 14.18.21.png

  • 作成が完了したらhubotの詳細画面に遷移するので画面上部の Setup Instructions のところに記載されている HUBOT_SLACK_TOKEN={YOUR_API_TOKEN} をコピーしておきます
  • 画像を変更する・・・など何か編集を加えた場合、画面下部の保存ボタンをクリックして更新してください

  • EC2に戻り以下の環境変数をexportします

echo 'export HUBOT_SLACK_TOKEN={YOUR_API_TOKEN}' >> ~/.bash_profile
source ~/.bash_profile
  • アダプタを指定してhubotを起動します
bin/hubot --adapter slack
  • slackのどこかのチャンネルにhubotをinviteして動作確認します

スクリーンショット 2017-06-17 14.29.14.png

  • 動作確認ができたらEC2起動時に自動でhubotが立ち上がるようにします

hubotの永続実行

  • foreverをnpmでインストールします
npm install -g forever
  • bin/hubot を書き換えます
以下を追記
forever start -w -c coffee node_modules/.bin/hubot --adapter slack


以下をコメントアウト
exec node_modules/.bin/hubot --name "deploy-sushi" "$@"

  • バックグラウンドで動くことを確認します
bin/hubot
ps aux | grep hubot

EC2起動時のスクリプト作成

sudo vi /etc/init.d/start_deploy_hubot
#!/bin/bash
#chkconfig: 2345 99 10
#descpriction: start deploy hubot
DIR="/home/ec2-user/deploy-sushi"
cd $DIR
bin/hubot
  • 実行権限を付与します
sudo chmod 755 /etc/init.d/start_deploy_hubot
  • サービスに追加します
sudo chkconfig --add start_deploy_hubot
  • EC2インスタンスを再起動してhubotが立ち上がっていることを確認してください

hubotが起動しなかった・・・

  • npm,foreverのパスがec2-userにしか通っていないかったのでrootでnpm,foreverするとコマンドが見つからない。
  • トークンもec2-userの .bash_profile に記述していたので見つからない。
  • とりいそぎ bin/hubot に以下を追記しました
    • npm install よりも前に追記してください
export PATH="/home/ec2-user/.nvm/versions/node/v6.11.0/bin:$PATH"
export HUBOT_SLACK_TOKEN={YOUR_API_TOKEN}
  • EC2を再起動して、hubotが立ち上がっていることを確認してください

    • プロセスの確認をします
ps aux | grep hubot
  • slackのチャンネルでもpingして返答があることを確認してください

おわり

hubotがサーバ上で動き続けるようになったので、次回はslackからgit操作を出来るようにしようと思います。

続きを読む

AWS ECSを使用する前にDockerを理解しなきゃ

◎はじめに

・Amazon EC2 Container Service (ECS)ってなんじゃらほい?
というわけでざっくり調べてみたところ、Dockerコンテナを管理するものとのこと。
『えっ、、Dockerってクジラさんのアイコンのヤツでしょ。VMの一つの。。』
とまたまたITリテラシーの低さを露呈した私、
ECSを触る前にまずDockerを理解する必要が出てきました。

1. Dockerとは

docker.png

Wikipediaより

Docker(ドッカー)はソフトウェアコンテナ内のアプリケーションのデプロイメントを自動化するオープンソースソフトウェアである。
Linuxカーネルにおける「libcontainer」と呼ばれるLinuxコンテナ技術とaufsのような特殊なファイルシステムを利用してコンテナ型の仮想化を行う。

はい。まだよくわかりません。。コンテナってなんなのさ。。。

1-1. コンテナとは

■目的
・デプロイ作業を簡易にする
→ 開発環境をそのまま本番環境として利用できる
→ アプリケーション開発環境(ライブラリ、環境変数など)をまるごとパッケージングし本番環境にデプロイすることで環境に依存することがなくなる。

■仮想化との差異

タイプ    概要
仮想化 複数のオペレーティングシステムが単一のシステム(ゲストOS)で同時に実行できるようになる
コンテナ 同じオペレーティング・システム・カーネルを共有し、アプリケーションプロセスをシステムの他の部分から独立させる

▽補足
・Hypervisor上に複数のOSを実行する仮想化は負荷が大きい。
一方、コンテナはホストOS、ライブラリを共有している。
そのため少ディスクかつ少メモリでビルドもデプロイも高速、オーバーヘッドも少ない。
それでいて仮想化のためプラットフォームやハードウェアからは隔離された環境となっている。

・1コンテナ=1プロセス

▽参考サイト:
今からでも間に合うDockerの基礎。コンテナとは何か、Dockerfileとは何か。Docker Meetup Tokyo #2

1-2. 取り敢えず触ってみよう

■参考サイト
・公式サイト
https://docs.docker.com/

・Docker ドキュメント日本語化プロジェクト
http://docs.docker.jp/index.html

■環境
・最新のAmazon linux AMIからlaunchしたインスタンスに導入してみました。

[ec2-user@mitzi_dev02 ~]$ uname -r
4.9.27-14.31.amzn1.x86_64

■余談
・amzn linuxへのインストール方法が公式サイト上で見つからなかったため、CentOSの手順でやってみたところ
ライブラリが足りないなどのエラーが多発し撃沈。。そこで上述の日本語化されたサイトを見たところAWS公式DocumentationのECSの項にDockerの説明・導入方法の記載がありました。親切ね

Docker の基本

■インストールそしてHello World

・パッケージとパッケージキャッシュを更新
$ sudo yum update -y

・Dockerをインストール
$ sudo yum install -y docker

・Dockerサービスを開始する
$ sudo service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:  .                                  [  OK  ]

・ Dokerの環境情報表示でコマンド実行できることを確認
$ sudo docker info
・Hell world コンテナを実行

[ec2-user@mitzi_dev02 ~]$ docker run ubuntu:14.04 /bin/echo 'Hello world'

docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.27/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
See 'docker run --help'.
[ec2-user@mitzi_dev02 ~]$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
Unable to find image 'ubuntu:14.04' locally
14.04: Pulling from library/ubuntu
1d8592394ba1: Pull complete
01aa7f61ccd1: Pull complete
5dd2552a960e: Pull complete
7cbe941c5e3e: Pull complete
2549ecfb14c6: Pull complete
Digest: sha256:30204139c6ab96ebd75d72f34db390f28c4decd5e563488b4e485bf979397b67
Status: Downloaded newer image for ubuntu:14.04
Hello world

公式サイトより、ここでやっていることの説明を引用

  • docker run でコンテナを実行。
  • ubuntu は実行するイメージです。この例では Ubuntu オペレーティング・システムのイメージです。イメージを指定したら、Docker はまずホスト上にイメージがあるかどうか確認します。イメージがローカルに存在していなければ、パブリック・イメージ・レジストリである Docker Hub からイメージを取得(pull)します。
  • /bin/echo は新しいコンテナ内で実行するコマンドです。

コンテナを起動するとは、Docker が新しい Ubuntu 環境を作成し、その中で /bin/echo コマンドを実行し、その結果を出力します。

なんとなくイメージが湧いてきました。
ここでは簡単なコマンドを実行しただけですが、これを応用していくことで前述の目的を達成するんだろうな。という何となくなイメージが

とりあえず今回はココまでになります。
引き続きDockerを触ってゆき、その先にあるECSを使いこなせるようにしていきたく思います。

続きを読む