20201018のAWSに関する記事は7件です。

Djangoチュートリアル(ブログアプリ作成)④ - ユニットテスト編

前回、Djangoチュートリアル(ブログアプリ作成)③ - 記事一覧表示編では管理サイトから作成した記事を一覧表示させるために、クラスベース汎用ビューを使いました。

このままアプリ内での記事作成、詳細、編集、削除といった CRUD 処理を追加したいところではありますが、グッとこらえてユニットテストを盛り込みましょう。

Django のテストについて

どんどん機能を追加していくのは楽しいですが、普段はテストを書いているでしょうか?

各種チュートリアルなどでDjangoの簡単なアプリを作れるようになった方でも、
少し自分なりにいじった時にエラーを引き起こしてしまう場合があるかと思います。
また、Djangoをrunserver等で起動した際には特にエラーが出力されなくても
実際に画面をブラウザ経由で動かした時にエラーに気づく場合もあるかと思います。

いくつかの操作を手動でテストするという方法はもちろんありますが、毎回そういったことを行うのは無駄という他ありません。

そこで、Djangoの機能を用いてユニットテストを行うことを推奨します。
DjangoではUnitTestクラスを用いてテストを自動化することができるので、
最初にテスト用のコードだけ書いてしまえば後は何度も同じことをする必要はありません。

テストの考えることは開発コードを考えるのと同じぐらい重要であり、
テストを作ってからアプリ動作のためのコードを書くという開発手法もあるぐらいです。

これを機にテストを行えるようになり、あなたのテスト時間を節約してアプリ本体をより改善することに労力を費やしましょう。

フォルダ構成について

この時点では下記のようなフォルダ構成になっているはずです。

.
├── blog
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py # 注目
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── templates
    └── blog
        ├── index.html
        └── post_list.html

お気づきになられた方はいるかもしれませんが、blog ディレクトリ配下に tests.py というファイルが自動的に作成されています。

この tests.py の中に直接テストケースを作成していってもよいのですが、
model のテスト、view のテストとテストごとにファイルが分かれていた方が何かと管理しやすいので
下記のように tests ディレクトリを作成し、中にそれぞれ空ファイルを作成しておきましょう。
tests ディレクトリ内のファイルも実行されるように、中身はからの init.py ファイルも作成しておくのがポイントです。

.
├── blog
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   └── __init__.py
│   ├── models.py
│   ├── tests # 追加
│   │   ├── __init__.py
│   │   ├── test_models.py
│   │   ├── test_urls.py
│   │   └── test_views.py
......

なお、モジュールの名前は「test」で始めないと Django が認識してくれないので注意してください。

テストの書き方

Django では Python標準のTestCaseクラス(unittest.TestCase)を拡張した、
Django独自のTestCaseクラス(django.test.TestCase)を使います。
このクラスではアサーションというメソッドを使うことができ、返り値が期待する値であるかどうかをチェックする機能があります。

また、前述の通りテストモジュールは「test」という文字列で始まっている必要があるのと、
テストメソッドも「test」という文字列で始める必要があります(詳細は後述します)。

このルールを守ることで Django がテストメソッドをプロジェクト内から探し出し、自動で実行してくれるようになります。

test_models.py

それではまずは model のテストから作成していきましょう。
おさらいですが、blog/models.py に記述されている Post model はこのようになっています。

models.py
...

class Post(models.Model):
    title = models.CharField('タイトル', max_length=200)
    text = models.TextField('本文')
    date = models.DateTimeField('日付', default=timezone.now)

    def __str__(self): # Post モデルが直接呼び出された時に返す値を定義
        return self.title # 記事タイトルを返す

この model に対して、今回は次の3ケースでテストしましょう。

1.初期状態では何も登録されていないこと
2.1つレコードを適当に作成すると、レコードが1つだけカウントされること
3.内容を指定してデータを保存し、すぐに取り出した時に保存した時と同じ値が返されること

ではまずひとつめからです。

test_models.py を開き、必要なモジュールを宣言します。

test_models.py
from django.test import TestCase
from blog.models import Post

そしてテストクラスを作っていくのですが、必ず TestCase を継承したクラスにします。

test_models.py
from django.test import TestCase
from blog.models import Post

class PostModelTests(TestCase):

さて、この PostModelTest クラスの中にテストメソッドを書いていきます。
TestCase を継承したクラスの中で「test」で始めることで、
Django がそれはテストメソッドであることを自動で認識してくれます。
そのため、def の後は必ず test で始まるメソッド名を名付けましょう。

test_models.py
from django.test import TestCase
from blog.models import Post

class PostModelTests(TestCase):

  def test_is_empty(self):
      """初期状態では何も登録されていないことをチェック"""  
      saved_posts = Post.objects.all()
      self.assertEqual(saved_posts.count(), 0)

saved_posts に現時点の Post model を格納し、
assertEqual でカウント数(記事数)が「0」となっていることを確認しています。

さて、これで一つテストを行う準備が整いました。
早速これで一回実行していきましょう。

テストの実行は、manage.py が置いてあるディレクトリ (mysite内) で下記のコマンドを実行します。
実行すると、命名規則に従ったテストメソッドを Django が探し出し、実行してくれます。

(blog) bash-3.2$ python3 manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.....
----------------------------------------------------------------------
Ran 1 tests in 0.009s

OK

一つのテストを実行し、エラーなく完了したことを意味しています。

ちなみに、先ほどは Post 内にデータが空 (=0) であることを確認しましたが、データが1つ存在していることを期待するようにしてみます。

test_models.py(一時的)
from django.test import TestCase
from blog.models import Post

class PostModelTests(TestCase):

  def test_is_empty(self):
      """初期状態だけど1つはデータが存在しているかどうかをチェック (error が期待される)"""  
      saved_posts = Post.objects.all()
      self.assertEqual(saved_posts.count(), 1)

この時の test 実行結果は下記のようになっています。

(blog) bash-3.2$ python3 manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_is_empty (blog.tests.test_models.PostModelTests)
初期状態だけど1つはデータが存在しているかどうかをチェック (error が期待される)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/masuyama/workspace/MyPython/MyDjango/blog/mysite/blog/tests/test_models.py", line 9, in test_is_empty
    self.assertEqual(saved_posts.count(), 1)
AssertionError: 0 != 1

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (failures=1)

AssertionError が出ており、期待される結果ではないためにテストは失敗していますね(実験としては成功です)。

Django のテストではデータベースへ一時的なデータの登録も create メソッドから実行できるので、
データを登録しないと確認できないような残りのテストも実行することができます。
下記に model のテストの書き方を載せておくので、参考にしてみてください。

test_models.py(全文)
from django.test import TestCase
from blog.models import Post

class PostModelTests(TestCase):

  def test_is_empty(self):
    """初期状態では何も登録されていないことをチェック"""  
    saved_posts = Post.objects.all()
    self.assertEqual(saved_posts.count(), 0)

  def test_is_count_one(self):
    """1つレコードを適当に作成すると、レコードが1つだけカウントされることをテスト"""
    post = Post(title='test_title', text='test_text')
    post.save()
    saved_posts = Post.objects.all()
    self.assertEqual(saved_posts.count(), 1)

  def test_saving_and_retrieving_post(self):
    """内容を指定してデータを保存し、すぐに取り出した時に保存した時と同じ値が返されることをテスト"""
    post = Post()
    title = 'test_title_to_retrieve'
    text = 'test_text_to_retrieve'
    post.title = title
    post.text = text
    post.save()

    saved_posts = Post.objects.all()
    actual_post = saved_posts[0]

    self.assertEqual(actual_post.title, title)
    self.assertEqual(actual_post.text, text)

test_urls.py

model 以外にも、urls.py に書いたルーティングがうまくいっているのかどうかを確認することもできます。
おさらいすると blog/urls.py はこのようになっていました。

blog/urls.py
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('post_list', views.PostListView.as_view(), name='post_list'),
]

上記のルーティングでは /blog/ 以下に入力されるアドレスに従ったルーティングを設定しているので、
/blog/ 以下が ''(空欄) と 'post_list' であった時のテストをします。
それぞれのページへ view 経由でリダイレクトされた結果が期待されるものであるかどうかを、assertEqual を用いて比較してチェックします。

test_urls.py
from django.test import TestCase
from django.urls import reverse, resolve
from ..views import IndexView, PostListView

class TestUrls(TestCase):

  """index ページへのURLでアクセスする時のリダイレクトをテスト"""
  def test_post_index_url(self):
    view = resolve('/blog/')
    self.assertEqual(view.func.view_class, IndexView)

  """Post 一覧ページへのリダイレクトをテスト"""
  def test_post_list_url(self):
    view = resolve('/blog/post_list')
    self.assertEqual(view.func.view_class, PostListView)

ここまでで一旦テストを実行しておきましょう。
※先ほど、データベースが空である状態のテストをしたときと比べると
 データを登録するテストケースが増えているため
 テスト用のデータベース作成、消去の処理がメッセージに出力されていることが分かります

(blog) bash-3.2$ python3 manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.....
----------------------------------------------------------------------
Ran 5 tests in 0.007s

OK
Destroying test database for alias 'default'...

test_views.py

最後に view のテストも行いましょう。

views.py はこのようになっていました。

views.py
from django.views import generic
from .models import Post  # Postモデルをimport

class IndexView(generic.TemplateView):
    template_name = 'blog/index.html'

class PostListView(generic.ListView): # generic の ListViewクラスを継承
    model = Post # 一覧表示させたいモデルを呼び出し

IndexView のテストでは、GET メソッドでアクセスした時にステータスコード 200(=成功) が返されることを確認します。

test_views.py
from django.test import TestCase
from django.urls import reverse

from ..models import Post

class IndexTests(TestCase):
  """IndexViewのテストクラス"""

  def test_get(self):
    """GET メソッドでアクセスしてステータスコード200を返されることを確認"""
    response = self.client.get(reverse('blog:index'))
    self.assertEqual(response.status_code, 200)

何か view でメソッドを追加したときは、
どんなにテストを書く時間がなくてもこれだけは最低限テストケースとして作成する癖をつけましょう。

ListView の方もテストをしていきます。

同じく 200 のステータスコードが返ってくることの確認はもちろん、
ここではデータ(記事)を2つ追加した後に記事一覧を表示させ、
登録した記事のタイトルがそれぞれが一覧に含まれていることを確認するテストを作成します。

なお、ここで少し特殊なメソッドを使います。
テストメソッドは「test」で始めるように前述しましたがsetUptearDownというメソッドが存在します。

setUpメソッドではテストケース内で使うデータの登録をし、
tearDownメソッドでは setUp メソッド内で登録したデータの削除を行えます。
(どちらも、どんなデータを登録するかは明示的に記述する必要があることには注意しましょう)

同じテストケースの中で何回もデータの登録をするような処理を書くのは手間&テストに時間がかかる要因になるので、
共通する処理は一箇所にまとめてしまおうというものです。

これらのメソッドを使い、test_views.py を作成するとこのようになります。

test_views.py
from django.test import TestCase
from django.urls import reverse

from ..models import Post

class IndexTests(TestCase):
  """IndexViewのテストクラス"""

  def test_get(self):
    """GET メソッドでアクセスしてステータスコード200を返されることを確認"""
    response = self.client.get(reverse('blog:index'))
    self.assertEqual(response.status_code, 200)

class PostListTests(TestCase):

  def setUp(self):
    """
    テスト環境の準備用メソッド。名前は必ず「setUp」とすること。
    同じテストクラス内で共通で使いたいデータがある場合にここで作成する。
    """
    post1 = Post.objects.create(title='title1', text='text1')
    post2 = Post.objects.create(title='title2', text='text2')

  def test_get(self):
    """GET メソッドでアクセスしてステータスコード200を返されることを確認"""
    response = self.client.get(reverse('blog:post_list'))
    self.assertEqual(response.status_code, 200)

  def test_get_2posts_by_list(self):
    """GET でアクセス時に、setUp メソッドで追加した 2件追加が返されることを確認"""
    response = self.client.get(reverse('blog:post_list'))
    self.assertEqual(response.status_code, 200)
    self.assertQuerysetEqual(
      # Postモデルでは __str__ の結果としてタイトルを返す設定なので、返されるタイトルが投稿通りになっているかを確認
      response.context['post_list'],
      ['<Post: title1>', '<Post: title2>'],
      ordered = False # 順序は無視するよう指定
    )
    self.assertContains(response, 'title1') # html 内に post1 の title が含まれていることを確認
    self.assertContains(response, 'title2') # html 内に post2 の title が含まれていることを確認

  def tearDown(self):
      """
      setUp で追加したデータを消す、掃除用メソッド。
      create とはなっているがメソッド名を「tearDown」とすることで setUp と逆の処理を行ってくれる=消してくれる。
      """
      post1 = Post.objects.create(title='title1', text='text1')
      post2 = Post.objects.create(title='title2', text='text2')

この状態でテストを実行すると model, url, view で合計 8 つのテストが実行されます。

(blog) bash-3.2$ python3 manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
........
----------------------------------------------------------------------
Ran 8 tests in 0.183s

OK
Destroying test database for alias 'default'...

これで、これまで書いたコードについてユニットテストを作成することができました。
他にも期待される template が呼び出されているかどうか等、
Django 独自のテスト方法を用いたテストで冗長的にチェックする方法もありますが
コードを書く前にテストを作成する癖をつけ、後々のチェックの手間を省くようにしていきましょう。

次回はアプリ内で記事を作成できるようにします。
今回覚えたユニットテストを先に書く TDD (テスト駆動開発) スタイルでいきましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【らくちんAWS】 LightSailからはじめるAWSエンジニア (後編) 【AWS完全に理解した】

前編: 【らくちんAWS】LightSailからはじめるAWSエンジニア (前編)【EC2よりカンタン】
AWSロゴ.png

この記事について

この記事は、「AWSは難しくて嫌だ!」と感じる人の苦手意識を克服するために、
AWS LightSailという初心者向けサービスを起点にAWSを紹介させていただく記事です。
前編でLightSailの紹介をさせていただいてますので、よければ先に読んでみてください。

この記事を書いたきっかけ

2020年現在、AWSでは175を超えるサービスを提供しており、AWSの存在感は圧倒的なものとなっています。
しかし、WEBサーバーの実装すら未経験だったわたしは、
WEBサーバーを構築するための「EC2」というサービスについて理解するだけで精一杯でした。
やっとの思いでEC2を利用した練習作品を開発したあとは、HerokuやFirebaseのような、
難しいことを考えなくてもWEBアプリをリリースできるサービスのほうに興味が寄っていきました。

そんなときに知ったのが、AWS LightSailでした。
LightSailはEC2とは違い、色々調べなくてもカンタンにサーバーを借りて、SSH接続ができるそうです。
ハードルは低いのに、素のサーバーのように扱うことができるので、
SSH接続ができないHerokuやFirebaseと比べると、とても自由度が高く、魅力を感じました。

しかし、LightSailはEC2と比べると認知度が低く、情報を探してもあまり出てきません。
そのため、実際に使うべきかどうか足踏みしていました。
そんな中、AWSマンガと出会いました。
第1話で紹介されるサービスがLightSailだったので、
LightSailの使い方をより深く知ることができる!と歓喜しました。
しかし、読みすすめると、物語中の開発規模は壮大で、
LightSailにとどまらないAWSの各種サービスの使用例がたくさん説明されていました。
それは、いままで「AWSといえばクラウドサーバー」という使い方しかイメージできていなかったわたしにとって、刺激的な内容でした。
AWSマンガのおかげで、わたしの中のAWSの入り口はぐぐっと広がり、
AWSでどんなことができるのか、もっともっと知りたいと思い、ひたすら調べてメモをしていきました。

このとき調べた知識を共有することで、
わたしと同じようにAWSに苦手意識を持っていた駆け出しエンジニアのみなさんも、
AWSの扉を開くことができたらいいなと思い、記事にまとめました。

長い内容になりますが、小分けにしながら読み進めていただければと思います。
よろしくお願いいたします!

記事のコンセプト

記事のターゲット層について
この記事は、フロントエンドからデビューした駆け出しエンジニアをメインターゲットとしております。
「自身でAWSのサービスの取捨選択ができるくらいまで知る」ということを最優先に考えているため、
記事の中には、極端な表現があるかもしれません。

この記事の内容を理解したあとは、
他の情報や、記事のコメントなどを参考にして、より知識を深めていただければと思います。

記事タイトルについて
記事タイトルで掲げている「AWSエンジニア」というのは「AWSが使えるエンジニア」という意味であり、
「AWSのプロフェッショナル」という意味ではありません。

紹介するサービスについて

この記事では、LightSailから使い方を連想しやすいサービスを選んで、
サービスの認知度順に各サービスを説明します。
選ぶサービスや認知度はわたしの個人的主観にもとづいて選んだものです。
紹介しなかったサービスの中でも有用なサービスはたくさんありますので、
この記事は、あくまでAWSへの入り口を広げるだけという、ざっくりした気持ちで読んでください。

認知度は、下記のようなイメージです。

認知度 ☆☆☆
LightSailを使わないでAWSを扱うのであれば、まず知っておいたほうがいいレベル。

認知度 ☆☆★
知っていると、よりAWSを使いこなせるレベル。

認知度 ☆★★
そんな事もできるのか!AWSおもしろい!と思えるレベル。
(AWSはサーバー関連の機能ばかり提供しているわけではないということを理解していただくための、
おまけ程度の紹介です。)

認知度 ☆☆☆

EC2

LightSailと同じように、SSH接続ができるサーバーを作るサービスです。
AWSの基本中の基本なので、「AWSを使う=EC2を使う」と言っても過言ではありません。


LightSailとの違いは、カスタマイズ性がとても高いことです。
スペックのバランスやセキュリティの条件をはじめとする、あらゆる項目を自由に設定することができます。
(逆に言うと、設定しなければいけません。)
そのため、インスタンスの作成画面や管理画面は、かなり複雑な見た目になっています。

LightSailもEC2も、サーバーを使って出来ることは全て実現可能です。
WEBサーバーや、その中で使うフレームワークやライブラリ等の機能は、EC2にインストールして使うことになりますし、
データベースをはじめ、他のAWSのサービスで実現すべき機能も、EC2サーバーに導入することは可能です。

しかし、他のサービスで実現できる機能は、できるだけ他のサービスとEC2を組み合わせて使った方がいいというのがAWSの基本になります。
これはなぜかというと、全ての機能をサーバー1台に任せてしまうと、
サーバーにトラブルがあったときに、全ての機能・データがサーバーの道連れになる危険性があるからです。
サーバーのトラブルの例としては、下記のような感じです。
  • 操作ミスによるサーバーのシャットダウンや、データの消去
  • サイバー攻撃や不正アクセス、ハッキングなどの被害
  • アクセスが爆発的に増えてしまった場合、サーバーのスペックが足りなくなる

このため、EC2を使ってインフラ環境を構築する場合は、
他のあらゆるAWSサービスをできるだけ学習していくべきというのが基本です。

しかしLightSailの場合は、他のサービスを組み合わせるための学習に時間を使わなくても、
使いたい機能を管理画面で利用設定するだけでカンタン&固定料金で導入できますので、
これがLightSailが分かりやすさに特化してると言える、ひとつの理由になります。

RDS

データベース専用のサーバーを作成するサービスです。


RDSにデータベースを隔離しておくことで、以下のようなメリットを得ることができます。
  • EC2になにかしらのトラブルがあっても、データの消去や漏洩などのトラブルを回避することができる。
  • EC2を酷使してしまい、サーバーが重くなっても、データベースだけは高速で動かしつづけることができる。
  • 定期的な自動バックアップ機能や、スナップショット(ある時点のバックアップデータを保存しておく)機能が用意されているので、万が一のトラブルへの対処もカンタンにできる。

ただし、EC2にDBを導入したほうが費用は安いという情報もあるので、
安全性と費用、どちらを優先するかは検討する必要があります。

LightSailの場合は、データベース機能(有料)があらかじめ用意されているので、
そちらの機能を利用することになります。

S3

EC2に連携できるストレージを作成するサービスです。
圧倒的に価格が安いうえに、耐久性は99.999999999%と公言している、非常に優秀なサービスです。


通常のストレージであれば、何GBでいくら、のような単位で購入する形態が一般的ですが、
S3の場合、容量は無制限で、容量が増えるたびに使用料金が増えていくようなサービスとなります。

USBメモリや外付けハードディスクのように
保存してあるデータを直接読み込んで編集・保存することはできず、
FTPサーバーのように、ファイルを取り出して編集してから保存するような使い方になります。

また、S3ならではの重要な機能として「静的ファイルのホスティング」があります。
ホスティングとは、サーバー上のファイルにインターネット経由でアクセスできるようにすることです。
静的ファイルとは、サーバーの処理で内容を書き換えるような「動的ファイル」ではない、
あらかじめ内容が決まっているファイルのことです。
S3のメイン機能はあくまでデータの保存ですが、
静的ファイルであれば、別途WEBサーバーを用意しなくてもこれだけで配信できてしまうのです。
先程もいったように、S3は圧倒的に価格が安く、耐久性はほぼ100%なので、
低コストで、アクセスが増えても落ちないページの配信が可能になります。
近頃、WEBサーバーを用意しないで開発を行う「サーバーレス開発」が流行っているのは、
このような素晴らしいサービスが世に誕生してきたからなんだろうな〜と思わされます。

S3のタイプ(ストレージクラス)にも色々な種類がありますが、
S3 Glacier DeepArchiveというタイプが特に気になりました。
データを取得するのに12~48時間かかり、保管するファイルを気軽に削除することもできないかわりに、
それでも構わないようなファイルの保管が目的であれば、また一段とびっくりするような安価で使うことができるそうです。

LightSailの場合は、ストレージの追加オプション(有料)があらかじめ用意されているので、
そちらの機能を利用することになります。


ですがこれは、S3と同様の機能とは言えないので混同しないよう気をつけてください。
たとえばLightSailでは容量をあらかじめ決めておく必要があったり、
静的ファイルの配信機能がなかったりします。
S3 Glacier DeepArchiveのような個性的なストレージクラスも存在しません。

Route53

さきほど紹介したEC2やS3、このあと説明するELBやCloudFrontのような
ユーザーにコンテンツを配信するサービスに、独自ドメインを適用するサービスです。
※「独自ドメインの適用」=「オリジナルのURL(アドレス)でアクセスできるようにする」という事です。


独自ドメインを使う権利を得るためには、お名前.comムームードメインなどのドメイン管理会社(=レジストラ)に年額を支払ってドメインを取得してもらうのですが、
Route53ではこれも一緒に対応してもらうことが可能です。

Route53で取得したドメインはもちろんのこと、
他社で取得したドメインであっても、AWSの各サービスと連携できるように管理してくれます。

LightSailの場合、ドメインを管理してサーバーへ割り当てる機能はあらかじめ用意されています。
ただし、ドメインの取得はできないので、Route53や他社レジストラを利用する必要があります。

認知度 ☆☆★

WAF

Webアプリケーションファイアウォールです。
名前のとおり、サーバーに対する攻撃から、サーバーを守るためのセキュリティ機能です。


どのようなルールでサーバーを守るかは、手動で設定することもできますが、
AWS Marketplaceというサービス上で販売されている有料のセキュリティールールを利用することで、
より手軽に強力なルールを適用することもできます。

AWSは標準で「セキュリティグループ」と呼ばれるセキュリティ機能が用意されていますので、
WAFはそれに追加でセキュリティ機能をつけたい人のためのサービスになります。
(たとえば、日本以外または特定の国からのアクセスをブロックするなどです。)

WAFを利用するためには、後述のCloudFrontまたはELBというサービスを利用する必要があります。
EC2などのサービスに直接適用することはできませんので、
WAFを利用する場合は上記どちらかのサービスの利用料もかかってきます。


LightSailの場合、ファイアウォール機能が予め用意されているので、基本的な設定はそちらで行うことになります。


しかし、これはWAFというよりセキュリティグループ的な立ち位置の機能になるので、
セキュリティ機能を追加したい場合はWAFの利用が必要になります。

※LightSailではIP制限が出来ないという情報が出回っていますが、2020年5月から対応可能になっています。
※LightSailでWAFが利用できるのかについては、調べても詳しい情報が見つけられませんでした。
こちらのQ&Aにて、LightSailのロードバランサー機能を利用すればWAFの利用ができるかのような記述がありますが、
実際にやってみたことはないので、やってみて出来たらこの記事に追記します。
詳しくご存知の方は、情報提供いただければ嬉しく思います。
(上記Q&Aの時点ではLightSailのCDN配信機能が未実装でしたので、CDN機能とWAFの連携ができるかについては一切言及されていません。)

Cloud9

サーバー上のソースコードに対してIDE(統合開発環境)を利用できる、無料(※)
のサービスです。
IDEというのはVSCodeやPhpStormのような、機能が豊富なエディタのことです。
※Cloud9で接続するためのサーバーを新規作成する場合、その費用は発生します。


サーバー上で開発を行うことにより、複数人で開発する場合もOSやバージョンが違うことによるトラブルや説明の手間を省くことができます。
また、ソースコードをリアルタイムで共有しながら一緒にプログラミングできる機能もあります。(VSCodeでいう「LiveShare」のような機能です。)

通常サーバー上のソースコードを編集するためには、
サーバーにSSH接続して「vim」というターミナル画面用のエディタを使って編集するか、
手元のPCでソースを編集してからサーバーにアップロードするという手順を踏む必要がありますので、この必要がなくなるのは非常に楽です。
ただし、手元のPCにサーバーをたてて開発(=ローカル環境で開発)をする場合、上記のようなメリットはありません。(Cloud9を利用する事自体は可能のようです。

LightSailの場合もCloud9との連携が可能ですが、するかどうかは検討が必要です。


検討が必要な理由は以下です。
通常、すでにネットに公開しているサービス、つまり本番環境のソースコードを直接いじる機会は少ないと思います。
テスト環境としてのサーバーを用意するなら、サーバーの起動時間によって料金が増減するEC2のほうがお得かもしれません。
(噂では、EC2の最安プランであれば料金は1時間あたり1円程度とのこと。)
しかし、本番環境とテスト環境の構成が違うことはトラブルの原因にもなります。
そのあたりも含め、何を優先するかを検討してから選択していただければと思います。

CloudFront

CDN配信機能です。
WEBサーバーから配信しているファイルを、AWSが持っている全国各地のサーバーにキャッシュさせておくことで、
アクセスしてきたユーザーの現在地から一番近い場所にあるサーバーからファイルを配信することができます。


CDNを利用する主なメリットは2つあります。
  • ユーザーがページを表示する速度が早くなる。
  • ファイルを配信する機能を自分のサーバーではなくファイルをキャッシュしているサーバーが担当することになり、自分のサーバーの負担を軽くすることができる。

LightSailの場合は、CDN配信機能(有料)があらかじめ用意されているので、
そちらの機能を利用することになります。
※LightSailにCDN配信機能がついたのは、2020年7月です。それより古い情報に惑わされないよう気をつけてください。

ELB

ロードバランサー機能です。

1台のPCでWEBサービスを運用していると、バズったりしてアクセスが増大したときに、サーバーがパンクして落ちてしまうことがあります。
そうならないように、同じWEBサービスを配信するサーバーを複数台用意しておくことで、サーバーダウンを回避する方法があります。
ロードバランサーは、そのとき用意した複数台のサーバーと、ユーザーのアクセスの間に設置して、
各サーバーの状態を考慮して適切なサーバーにアクセスを振り分けます。


上述のCDNとの使い分け方ですが、
サーバーサイドレンダリングを使ってページを作成するような構成の場合、
ファイルをキャッシュしておくCDN機能では対応できません。
そのため、そのような場合はロードバランサーを使う必要があります。

ちなみに、ロードバランサーはあくまで「各サーバーへの振り分け」を行う機能ですので、
「同じ機能を有する複数のサーバーを用意する」という部分は、こちらで費用や作業を負担して構築する必要があります。

LightSailの場合は、ロードバランサー機能(有料)があらかじめ用意されているので、
そちらの機能を利用することになります。

Lambda

関数をクラウド上に保管して、実行できる状態にしておけるサービスです。
つまるところ「バッチ処理」を管理してくれるということです。


料金は、関数を100万回実行するまでは無料で、それを超過すると従量課金になります。
なんでもかんでもLambdaに頼るような、サーバーレスな使い方をしなければ、
基本的に無料でいけるだろうという値段設定なのが、魅力的です。

実行時間が15分までの関数であれば、Lambdaでの実行が可能です。
それよりも長い時間がかかる場合は、AWS Batchというサービスを利用する必要があるようです。

LightSailとLambdaの連携はそれなりに手間がかかるようなので、
バッチ処理が必要ならばLightSailサーバー上に作成したほうがスッキリするかと思います。

認知度 ☆★★

Marketplace

構築済みのEC2のマシンイメージ(AMI)や、WAFのセキュリティルールなど、
AWSのサービス上で使用できるイメージを売買できる市場です。

Workspaces

クラウド上の仮想PCを使用できるサービスです。
EC2やLightSailと違いGUIが利用できるため、サーバーとしてではなく、
仮想環境や、遠隔操作できるPCのような使い方がメインになります。

Connect

自動電話受付窓口を作成するサービスです。
「◯◯のご用の方は◯番を押してください」みたいなやつです。

SES

メールの送受信サービスです。
メールマガジンの配信などができます。

Athena

AWSのストレージ上にあるファイル(主にCSVやEXCELのような形式のファイル)の中に書いてあるデータを、
データベースと同じ言語(SQL)を使って検索することができるサービスです。

おわり

いかがでしょうか?
記事の前編と後編を読んでいただいた方は、いままでよりグッとAWSの理解度が深まったのではないでしょうか?
過去の自分とおなじように、AWSに苦手意識を持っていた方々が、
AWSをなんとなく理解できるようになっていけたら、嬉しく思います。

紹介しなかったサービスについて

この記事に載っていない他サービスのことも広く知りたい場合は、
クラスメソッド社のAWS全サービスまとめを読んでみてください。
クラスメソッド社はAWSの研究意欲が高く、ブログでの知識共有を積極的に行ってくださっているすごい会社です。
AWSをより深く突っ込んでいくことになった場合、こちらのブログにお世話になることは少なくないかと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS SOA】ELBに関するログやメトリクスの備忘録

はじめに

私はAWS SOAを勉強しています。SOAですとログやメトリクスについての問題の出題が多いため、今回はELBのログやメトリクスについて簡単にQ&A形式でまとめていきたいと思います。

Q&A

Q.ロードバランサーのメトリクスを見たい時、どうするか?
A.EC2>ロードバランサー>モニタリングで、CloudWatchメトリクスを見ることができる。

スクリーンショット 2020-10-18 17.31.53.png

また「すべてのCloudWatchメトリクスを表示」をクリックすると、CloudWatchのメトリクスを見ることができる。そこでApplicationELBを選択すれば、詳細にELBのメトリクスを見ることが可能。
スクリーンショット 2020-10-18 17.36.15.png

Q.ターゲットグループのメトリクスを見たい時、どうするか?
A.EC2>ターゲットグループ>モニタリングで、メトリクスを見ることが可能。
スクリーンショット 2020-10-18 17.43.26.png

Q.ロードバランサーのアクセスログが取りたい時、どうするか?
A.EC2>ロードバランサー>説明>属性で、属性の編集を選択する。
スクリーンショット 2020-10-18 17.48.12.png
S3の場所で任意の名前を入力する。この場所の作成にチェックをして保存する。
スクリーンショット 2020-10-18 17.53.39.png
S3に行き、ログができているか確認する。
スクリーンショット 2020-10-18 17.56.46.png
該当の箇所まで行き、ダウンロードするとアクセスログが確認できる。
スクリーンショット 2020-10-18 18.00.25.png

ログの中身
・タイム
・クライアントIPアドレス
・遅延時間
・リクエストパス
・サーバーリスポンス
・トレースID
など

参考
Ultimate AWS Certified SysOps Administrator Associate 2020
https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-access-logs.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【忘備録】EC2内にDockerでPython3環境を構築する

概要

内容

  • AWSのEC2にDockerを用いてPython環境を構築する
    • 今回はseleniumでのブラウザ自動操作のパッケージを含めてコンテナ化する

環境

  • OS:AWS Linux2
  • サービス:AWS(EC2)
  • タイプ:t2.micro

前提

  • 自分のアカウントから上記環境のEC2が立てられている状態

参考資料

この辺から一部抜き出して履行。

必要なファイル

  • Dockerfile
  • docker-compose.yml

工程

  • EC2インスタンスへ接続
  • インスタンスでインストールされているパッケージとパッケージキャッシュを更新
$ sudo yum update -y
  • 最新の Docker Community Edition パッケージをインストール
$ sudo amazon-linux-extras install docker
  • 次はDocker Composeをcurlでインストール。
$ sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version

バージョンが表示されていたら成功

  • Dockerサービスを開始
$ sudo service docker start
  • ec2-user をdockerグループに追加し、今後コマンドで入力するsudoを省略する
$ sudo usermod -a -G docker ec2-user
  • 反映させるために一旦ログアウトし、再びEC2にログインする
  • ec2-user が sudo を使用せずに Docker コマンドを実行できることを確認
$ docker info

2.Dockerhubに登録

  • DockerHubにアカウント登録

  • リポジトリを作成

  • EC2でDockerHubにログインする

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: アカウント名
Password: パスワード
Login Succeeded

3.Dockerイメージを作成するためのファイルを作成

  • 必要なファイル

    • Dockerfile
    • docker-compose.yml
  • Dockerfileを作成。

$ touch Dockerfile
  • vimで中身を編集
$ vim Dockerfile
  • 今回はpython3とブラウザの自動操作をするためのパッケージが入ったイメージコンテナを作成する。
Dockerfile
FROM python:3
USER root

RUN apt-get update
RUN apt-get -y install locales && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
ENV TZ JST-9
ENV TERM xterm

#各種パッケージをインストール
RUN apt-get install -y vim less
RUN pip install --upgrade pip
RUN pip install --upgrade beautifulsoup4
RUN pip install --upgrade chromedriver
RUN pip install --upgrade chromedriver-binary
RUN pip install --upgrade datetime
RUN pip install --upgrade pandas
RUN pip install --upgrade pyyaml
RUN pip install --upgrade requests
RUN pip install --upgrade selenium
  • 上記をコピーし:wqで保存する

  • 次はdocker-compose.ymlを作成

touch docker-compose.yml
  • これもvimで中身を編集。 vim docker-compose.yml
docker-compose.yml
version: '3'
services:
  python3:
    restart: always
    build: .
    container_name: 'scrayping'
    working_dir: '/root/'
    tty: true
    volumes:
      - ./opt:/root/opt
  • 上記をコピーし:wqで保存する

3.Dockerイメージを作成

  • docker-compose.ymlの内容に基づいてイメージを作成する
    • このとき「-t」でdockerhubでつけるアカウント名/イメージ名にタグを命名しておかないとDockerHubにpush出来ない。注意
$ docker-compose build -t {dockerhubのアカウント名/イメージ名}
  • イメーシを作成できたかチェック
$ docker images

REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
shunsukenashiki/scrayping   latest              ed6df28c956e        About an hour ago   1.15GB

こんな感じで作られていればOK

4.Dockerイメージを元に、コンテナを作成

  • 作成したDocker imageを元にコンテナを作る
    • 「-d」をつける理由は、-dをつけないとバックグラウンドでコンテナが起動しないから
$ docker run -d --name #{任意のコンテナ名} -d -it {REPOSITORY名}
  • コンテナが作成され、起動されているかチェック。作成できていたら完了
$ docker ps

CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS               NAMES
b42460c71e9c        shunsukenashiki/scrayping   "python3"           5 seconds ago       Up 4 seconds                            scrayping

5.作成したコンテナを実行する

  • 作成したコンテナを実行する
$ docker exec -it #{任意のコンテナ名} bash
  • Dockerfileに指定したバージョンが入っていれば完了
$ pip3 list

Package         Version
--------------- ---------
beautifulsoup4  4.9.1
certifi         2020.6.20
chardet         3.0.4
chromedriver    2.24.1
DateTime        4.3
idna            2.10
numpy           1.19.1
pandas          1.1.0
pip             20.2.1
python-dateutil 2.8.1
pytz            2020.1
requests        2.24.0
selenium        3.141.0
setuptools      49.2.1
six             1.15.0
soupsieve       2.0.1
urllib3         1.25.10
wheel           0.34.2
zope.interface  5.1.0

Doekerhubにアップロードする

  • 動作確認できたら、Dockerhubにpushしていく
$ docker push shunsukenashiki/{dockerhubのアカウント名/イメージ名}:latest
  • Dockerhubにちゃんと紐づけられていれば完了。あとはここからimageをpullすれば使いまわせる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【0からAWSに挑戦】EC2とVPCを使ってRailsアプリをAWSにデプロイする part2

EC2とVPCを使ってRailsアプリをAWSにデプロイする part1

前回の続きです。
↓↓↓↓前回の記事はこちら↓↓↓↓↓
①EC2とVPCを使ってRailsアプリをAWSにデプロイする part1

環境

・Ruby on Rails 6.0
・Ruby 2.6.6
・dbはmysqlを使用
・アプリケーションサーバはpumaを使用
・webサーバーはnginxを使用

手順

前回は③までいきました。なので今回は④からやります
 ①VPCを作成
 ②VPC内にサブネットを作成
 ③インターネットゲートウェイ・セキュリティグループ・ルートテーブルの設定
 ④EC2を作成
 ⑤EC2にrails環境を構築、gitからアプリをpullする

④EC2を作成

EC2の設定

前回作成したサブネットの中にEC2(Elastic Compute Cloud)サーバーを構築しましょう。このEC2で作成した仮想サーバーにwebサーバーやアプリケーションを入れることで、デプロイができるようになります。

ではさっそくEC2を作成しましょう。まずはAWSのサービスメニューからEC2で検索します。そうしたらEC2の画面がでてきますので、左のサイドメニューからインスタンスを選択しましょう。(※ちなみにEC2で作成した仮想サーバーをインスタンスといいます。)

インスタンスを選択すると、右上にインスタンス起動のボタンがあるのでそれをクリックし、EC2の作成をはじめます。インスタンスの設定までには6ステップあるので順にみていきましょう。

1.最初のステップはAMIの設定です。簡単にいうとEC2上の仮想サーバーにどんなOSをいれるかです。ここは一番上のAmazonLinux2を選択します。
スクリーンショット 2020-10-18 1.12.27.png

2.インスタンスタイプは無料枠のものがt2.microしかないのでそれを選択します。
3.インスタンスの詳細設定は少し量が多いですが、必要なところだけ抽出してみていきましょう。
スクリーンショット 2020-10-18 1.21.28.png
- ネットワークは先程作成したVPCを選択してください
- サブネットも先程作成したサブネットを選択してください
- 自動割当パブリックは有効に設定します。これはインターネットからアクセスするのに必要な設定です
- ネットワークインターフェイスのプライマリIPを10.0.1.10に設定します。この設定はプライベートIPの設定です。サブネット(10.0.1.0/24)のなかの好きなIPアドレスにインスタンスを配置できます。
- 上記以外は空欄でOKです。

4.ストレージの追加はそのままでOKです。無料枠が30Gまでなのでそれを超えなければストレージ上げても問題ないです。
5.タグの追加もそのままでOKです。ただ複数インスタンスを作る場合は、{キー:NAME,値:WEBサーバー}みたいに設定しておくと便利です。
6.セキュリティグループは前記事で紹介しましたが、実はサーバー単位でも設定できます。もちろん前回サブネットに設定したセキュリティグループも適応できるので、今回は既存のセキュリティグループ(前記事で作成したもの)を使います。

以上で設定は完了です。確認画面のあと、起動ボタンを押すとインスタンスが生成されます。また生成と同時に鍵が生成されます。新しいキーペアを作成し、ダウンロードしましょう。ダウンロードしたファイルはSSH通信の際に必要になるのでなくさない用にしてください。
スクリーンショット 2020-10-18 9.54.37.png

ElasticIPの設定

現状でもEC2の起動は問題ありませんが、EC2を起動するたびにIPアドレスが変わってしまいます。そこでElasticIPというものを使って、IPアドレスを固定化しましょう。EC2の左サイドメニューからElasticIPを選択し、ElasticIPの割り当てをクリックしてください。その後設定画面に行きますが、設定はデフォルトのままでよいので、そのまま割当ボタンを押します。あとはElasticIPとEC2の関連付けが必要ですので、右上にあるアクションボタンからElasticIPの関連付けを選択し、先程作成したEC2を選んでください。

SSHで接続する

SSH(secure shell)とは簡単にいうとローカル(Macだとターミナル)からEC2サーバーを操作できるようにすることです。SSHに接続するには先程EC2の起動時に作成した鍵が必要です。ターミナルで下記の様に打つことでSSH接続ができます。

ターミナル
#ホームディレクトリ
user@usr ~ % ssh -i key.pem ec2-user@18.777.12.17 
  • 「ssh」の箇所でsshを使うことを宣言しています。
  • 「-i」は秘密鍵ファイルを意味します。なので先程EC2作成と同時に生成したファイルを指定します。おそらく「(自分で設定した名前).pem」というファイルがダウンロードフォルダにあると思うので、それをホームディレクトリに移します。
  • 「ec2-user」はEC2がデフォルトで用意しているユーザー名です。
  • そのあとの数字はElasticIPです。 要約すると「先程作成した秘密鍵を使って指定したIPアドレスにec2-userというユーザー名でSSH接続します」という意味になります。以上でSSHログインできると思います。ログインできると下記の画面のようになります。
ターミナル
Last login: Sat Oct 17 08:24:35 2020 from 210.28.31.150.dy.iij4u.or.jp

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
No packages needed for security; 1 packages available
Run "sudo yum update" to apply all updates.
[user@ip-10-0-1-10 ~]$ 

また上記コマンド打った際に、鍵ファイルのパーミッションエラーが起こることがあります。これは鍵ファイルが他人にも閲覧できる状態のために起こるエラーです。下記コマンドで鍵ファイルの権限を変更しましょう。

ターミナル
user@usr ~ % chmod 400 key.pem

上記のコマンドや権限に関しては、こちらの記事がわかりやすかったのでご参照ください。

これでEC2サーバーに入ることだできたので、あとはこの中に環境構築していくだけです。ちなみに自分はこのまま「ec2-user」で作業を進めたのですが、複数人で作業を行う場合などは作業用userを作ったほうがよいです。作業用ユーザー作成はこちらの記事に書いてあります。
※参照に書いていた「世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで」にも書いてありますね。もしかしたら1人の場合も作成したほうがよいかもしれません。


ちなみに現状の構成は下記のような感じです。
subnet (2).png

この記事で完結しようと思ったら環境構築が長くなりそうなので、一旦ここで切ります。

感想・まとめ

EC2の構築は結構簡単そうに見えて意外と時間を要しました。というのも最初から難しいことをやろうとしていたからです。具体的にはサブネットをDB用とWEBサーバー用に分割してEC2を踏み台サーバーにしてアクセスする方法やRDSやAWSのロードバランサーを使う方法を一気にやろうとしてました。そのためEC2構築あたりからぐちゃぐちゃしてしまい、無駄に時間を食ってしまいました。
このことから自分のような初学者は最初は無理せず、基本的で簡単な方法をまずこなすことを第一にし、その後で機能を積み重ねるというやり方を特に意識してやるべきかと実感しました。

参考

  • 「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版 著 大澤文孝,玉川憲,片山暁雄,今井雄太」 
    →おすすめの本です。AWSだけでなくネットワーク知識についても触れているので、初学者にとっては神技術書です。

  • (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
    →こちらもわかりやすくてよかったです。AWSの内容は「Amazon Web Services 基礎からのネットワーク&サーバー構築」とほとんど同じです。なのでこちらだけでAWSやってみるのもありかと思います。ただネットワーク知識が浅い人やインフラ初心者は最初に「Amazon Web Services 基礎からのネットワーク&サーバー構築」にやってネットワーク知識補充しながらやらないと苦労すると思います

※本記事は上記2つを参考にさせていただきながら実装しています。
なので実装に関しては類似箇所も多いかと思いますが、WEBサーバーの種類・DBのバージョンなどの構成などはもちろん自分なりにアレンジしています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【0からAWSに挑戦】①EC2とVPCを使ってRailsアプリをAWSにデプロイする part1

背景

未経験から自社開発系企業の就職を目指します。良質なポートフォリオ作成のためAWSを勉強することにしました。

現状の知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。自分の忘備録かつ、同じくらいのレベルでこれからAWSに挑戦してみようと思っている方に向けて少しでも役に立てればと思います。

最終目標

AWSのEC2とVPCを使ってアプリケーションを本番環境で動かすことが目標です。

環境

・Ruby on Rails 6.0
・Ruby 2.6.6
・dbはmysqlを使用
・アプリケーションサーバはpumaを使用
・webサーバーはnginxを使用

手順

今回は下記手順で進めたいと思います。
 ①VPCを作成
 ②VPC内にサブネットを作成
 ③インターネットゲートウェイ・セキュリティグループ・ルートテーブルの設定
 ④EC2を作成
 ⑤EC2にrails環境を構築、gitからアプリをpullする

では早速はじめましょう。
※大前提ですが、すでにAWSの登録は完了しているという前提で進めます。

EC2とVPCを使ってRailsアプリをAWSにデプロイする part1

①VPCを作成

そもそもVPCとは何かというと、(Virtual Private Cloud)の略で、ユーザー専用のクラウド環境を作ることができるものです。VPCの領域を定義することで、そのVPC内で好きなようにネットワークを構成したり、サーバーを立ち上げることができます。

AWS内のサービスメニューで「VPC」と検索するとすぐ出てくると思います。検索したら左のメニューバーからVPCを選択し、VPCの作成を選びましょう。そうしたら下記画面が出てくるはずです。
※リージョンは「東京」を選択しています。リージョンとはデータセンター群のある地域のことで、右上のヘッダーから選択できます。
vpc.png
簡単に説明します

  • 名前タグに関しては、vpcの名前の名前になるのでわかりやすい名前を設定しましょう。
  • CIDRブロックとは、VPCのIPアドレスの範囲に関する設定です。VPCで使うのはプライベートIPですので、ある程度自由にIPの範囲を設定できます。入力欄に見本として「10.0.0.0/24」書かれていますが、「/24」の部分はCIDER表記になります。IPアドレスはネットワーク部とホスト部の2つ、合計32ビットで表記されます。CIDER表記の、「/24」はそのうちのネットワーク部の占めるビット数の割合です。ホスト部が多いほど任意に設定できる値が増えます。基本は「/24」か「/16]でよいでしょう。今回は「10.0.0.0/16」で進めます。
  • その他はデフォルトのままで問題ありません。

これだけでVPC空間出来上がりです。

②VPC内にサブネットを作成

サブネットとはVPCのCIDRブロックを細分化したものです。もっと砕けていうと、VPCの内にいくつかの部屋を作るイメージです。例えばWEBサーバー用の部屋、データベース用の部屋みたいな感じです。通常VPCはサブネットを使って、細分化して運用します。下記のようなイメージです。
subnet.png

ではサブネットをつくりましょう。
左側のサイドメニューからサブネットを選択し、サブネットの作成をクリックしましょう。そうすると下記のような画面がでるはずです。

スクリーンショット 2020-10-17 21.00.09.png

  • 名前タグはサブネットの名前になります。わかりやすい名前をつけましょう。
  • VPCは先程作ったVPC領域が選択できるようになっていると思うのでそれを選択してください。
  • アベイラビリティゾーンとはリージョンの中に存在するデータセンターのことです。リージョンには複数のデータセンター(アベイラビリティゾーン)があります。今回で言えば東京リージョンのどのデータセンターを使うか指定します。ただ指定なしを選択すると勝手に適切なアベイラビリティゾーンを選択してくれるので、今回は指定なしでいきます。
  • そして最後に再び、CIDRブロックがでてきましたが、これはVPC領域「10.0.0.0/16」の中のIPアドレスの範囲を指定します。今回は「10.0.1.0/24]を指定します。

以上でサブネットの構築は完了です。

③インターネットゲートウェイ・セキュリティグループ・ルートテーブルの設定

インターネットゲートウェイ

インターネットゲートウェイとはその名の通り、インターネットでやり取りするための出入り口です。VPCはプライベートな空間なので、VPC内でやり取りはできるものの、そのままではインターネットに接続できません。なのでインターネットでやり取りができるような設定が必要です。左側のサイドメニューからインターネットゲートウェイを選択しましょうスクリーンショット 2020-10-17 21.24.32.png
こちらは名前を設定するだけで大丈夫です。これでインターネットゲートウェイは作成できたのですが、この作成できたインターネットゲートウェイをVPCと結びつける必要があります。ただ紐付けは簡単です。作成後の画面の上の方にアクションボタンをクリック→VPCにアタッチをクリック→先程作成したVPCを選択→インターネットゲートウェイのアタッチ。
これで完了です。

ルートテーブル

これはrails勉強した人なら、「AWS界のルーティング」といえばわかると思います。送られてきたデータはルートテーブルを基に振り分けられます。
もう少し具体的な内容で説明すると、インターネットで使われる「TCP/IP」(ネットワークをする際の規格・ルール)ではパケットという単位でデータのやりとりをします。そのパケットには宛先IPアドレスの情報が書かれています。その宛先IPアドレスを基にルーターが次々に宛先に近いネットワークへとパケットを転送することで、最終的に目的地までデータを届けることができるのです。逆にルーターが、どの宛先IPアドレスがきたときどこに転送すればいいかわからないと困りますよね。そこでルートテーブルに設定を記載するのです。すなわちルートテーブルとは、「どの宛先IPアドレスがきたとき、どこにデータを送るかを記したメモ」です。

それではルートテーブル作成しましょう。左のサイドメニューからルートテーブルを選択しましょう。するとすでにルートテーブルが存在しています。実はサブネットを作成したときに、デフォルトのルートテーブルが作成されるのです。ちなみにデフォルトのルートテーブルの意味は「送信先(宛先IPアドレス)が10.0.0.0/16(VPC領域)であれば、ローカルのネットワークにデータを転送する」という意味になります。(下記参照)
スクリーンショット 2020-10-17 22.54.47.png

ただこのままではインターネットと通信ができません。そこでインターネットゲートウェイへ転送する設定のルートテーブルを作成しましょう。ルートテーブル作成ボタンをクリックしてください。ここは名前を入力しと先ほど作ったVPCを選択して完了です。
スクリーンショット 2020-10-17 22.52.38.png

そして次に作成したルートテーブルの設定と先程作ったサブネットを紐付けが必要です。先程作ったルートテーブルを選択すると下の方にそのルートテーブルの詳細メニューが表示されます。まずはルートを選択しルートの追加ボタンを押しましょう。そして送信先を0.0.0.0/0にし、ターゲットをINTERNET GATEWAYにすればOKです。(INTERNET GATEWAYを選択するとidが勝手にでてきます)
スクリーンショット 2020-10-17 22.47.39.png

次にサブネットの関連付けです。サブネットの関連付けを選択し、サブネットの関連付けの編集ボタンを押しましょう。先ほど作成したサブネットを選択肢完了です。
スクリーンショット 2020-10-17 22.47.06.png
以上でインターネットと通信できるルートテーブルの設定が完了しました。

セキュリティグループ

セキュリティグループはその名の通りセキュリティに関する設定です。通信の種類によって通信するか、拒否するかを設定できます。早速作成しましょう。左のサイドメニューからセキュリティグループを選択肢、セキュリティグループを作成を選択します。そうすると下記画面がでてくると思います。スクリーンショット 2020-10-17 23.12.17.png

  • セキュリティグループ名・説明はわかりやすい名称を入れてください。
  • VPCは先程作成したものを選択してください。
  • インバウンドルールは簡単にいうと受信の設定です。ここには{タイプ:SSH 送信先:マイIP}、{タイプ:HTTP 送信先:任意の場所}を選択してください(※それ以外の欄は自動入力されます)。これでSSHとHTTPの通信が受信できるようになりました。
  • アウトバウンドルールは簡単にいうと送信の設定です。ここはデフォルトのままでOKです

以上でセキュリティグループの設定完了です。


少し長くなってしまったので④と⑤は次回の記事に書きます。(④と⑤が重いので、、、、)
ここまででネットワークの構成は下記の用になっているはずです。※ヘタですいません
subnet.png
次回はサブネットの中にEC2を作成していきたいと思います。

感想・まとめ

ここに関しては、「Amazon Web Services 基礎からのネットワーク&サーバー構築」という図書をみながらやった結果非常にスムーズにいきました。ネットワークの知識もつけたし、AWSでネットワークやサーバー構築する際の流れもなんとなくわかりました。ただネットワーク関連はまだ知識が浅いので別途勉強が必要だなとも思いました。

参考

  • 「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版 著 大澤文孝,玉川憲,片山暁雄,今井雄太」 
    →おすすめの本です。AWSだけでなくネットワーク知識についても触れているので、初学者にとっては神技術書です。

  • (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
    →こちらもわかりやすくてよかったです。AWSの内容は「Amazon Web Services 基礎からのネットワーク&サーバー構築」とほとんど同じです。なのでこちらだけでAWSやってみるのもありかと思います。ただネットワーク知識が浅い人やインフラ初心者は最初に「Amazon Web Services 基礎からのネットワーク&サーバー構築」にやってネットワーク知識補充しながらやらないと苦労すると思います

※本記事は上記2つを参考にさせていただきながら実装しています。
なので実装に関しては類似箇所も多いかと思いますが、WEBサーバーの種類・DBのバージョンなどの構成などはもちろん自分なりにアレンジしています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【0からAWSに挑戦】EC2とVPCを使ってRailsアプリをAWSにデプロイする part1

背景

未経験から自社開発系企業の就職を目指します。良質なポートフォリオ作成のためAWSを勉強することにしました。

現状の知識レベルとしては、Ruby on railsを使って簡単なアプリケーション開発、gitを使ったバージョン管理、herokuを使ってデプロイできるレベルです。自分の忘備録かつ、同じくらいのレベルでこれからAWSに挑戦してみようと思っている方に向けて少しでも役に立てればと思います。

最終目標

AWSのEC2とVPCを使ってアプリケーションを本番環境で動かすことが目標です。

環境

・Ruby on Rails 6.0
・Ruby 2.6.6
・dbはmysqlを使用
・アプリケーションサーバはpumaを使用
・webサーバーはnginxを使用

手順

今回は下記手順で進めたいと思います。
 ①VPCを作成
 ②VPC内にサブネットを作成
 ③インターネットゲートウェイ・セキュリティグループ・ルートテーブルの設定
 ④EC2を作成
 ⑤EC2にrails環境を構築、gitからアプリをpullする

では早速はじめましょう。
※大前提ですが、すでにAWSの登録は完了しているという前提で進めます。

EC2とVPCを使ってRailsアプリをAWSにデプロイする part1

①VPCを作成

そもそもVPCとは何かというと、(Virtual Private Cloud)の略で、ユーザー専用のクラウド環境を作ることができるものです。VPCの領域を定義することで、そのVPC内で好きなようにネットワークを構成したり、サーバーを立ち上げることができます。

AWS内のサービスメニューで「VPC」と検索するとすぐ出てくると思います。検索したら左のメニューバーからVPCを選択し、VPCの作成を選びましょう。そうしたら下記画面が出てくるはずです。
※リージョンは「東京」を選択しています。リージョンとはデータセンター群のある地域のことで、右上のヘッダーから選択できます。
vpc.png
簡単に説明します

  • 名前タグに関しては、vpcの名前の名前になるのでわかりやすい名前を設定しましょう。
  • CIDRブロックとは、VPCのIPアドレスの範囲に関する設定です。VPCで使うのはプライベートIPですので、ある程度自由にIPの範囲を設定できます。入力欄に見本として「10.0.0.0/24」書かれていますが、「/24」の部分はCIDER表記になります。IPアドレスはネットワーク部とホスト部の2つ、合計32ビットで表記されます。CIDER表記の、「/24」はそのうちのネットワーク部の占めるビット数の割合です。ホスト部が多いほど任意に設定できる値が増えます。基本は「/24」か「/16]でよいでしょう。今回は「10.0.0.0/16」で進めます。
  • その他はデフォルトのままで問題ありません。

これだけでVPC空間出来上がりです。

②VPC内にサブネットを作成

サブネットとはVPCのCIDRブロックを細分化したものです。もっと砕けていうと、VPCの内にいくつかの部屋を作るイメージです。例えばWEBサーバー用の部屋、データベース用の部屋みたいな感じです。通常VPCはサブネットを使って、細分化して運用します。下記のようなイメージです。
subnet.png

ではサブネットをつくりましょう。
左側のサイドメニューからサブネットを選択し、サブネットの作成をクリックしましょう。そうすると下記のような画面がでるはずです。

スクリーンショット 2020-10-17 21.00.09.png

  • 名前タグはサブネットの名前になります。わかりやすい名前をつけましょう。
  • VPCは先程作ったVPC領域が選択できるようになっていると思うのでそれを選択してください。
  • アベイラビリティゾーンとはリージョンの中に存在するデータセンターのことです。リージョンには複数のデータセンター(アベイラビリティゾーン)があります。今回で言えば東京リージョンのどのデータセンターを使うか指定します。ただ指定なしを選択すると勝手に適切なアベイラビリティゾーンを選択してくれるので、今回は指定なしでいきます。
  • そして最後に再び、CIDRブロックがでてきましたが、これはVPC領域「10.0.0.0/16」の中のIPアドレスの範囲を指定します。今回は「10.0.1.0/24]を指定します。

以上でサブネットの構築は完了です。

③インターネットゲートウェイ・セキュリティグループ・ルートテーブルの設定

インターネットゲートウェイ

インターネットゲートウェイとはその名の通り、インターネットでやり取りするための出入り口です。VPCはプライベートな空間なので、VPC内でやり取りはできるものの、そのままではインターネットに接続できません。なのでインターネットでやり取りができるような設定が必要です。左側のサイドメニューからインターネットゲートウェイを選択しましょうスクリーンショット 2020-10-17 21.24.32.png
こちらは名前を設定するだけで大丈夫です。これでインターネットゲートウェイは作成できたのですが、この作成できたインターネットゲートウェイをVPCと結びつける必要があります。ただ紐付けは簡単です。作成後の画面の上の方にアクションボタンをクリック→VPCにアタッチをクリック→先程作成したVPCを選択→インターネットゲートウェイのアタッチ。
これで完了です。

ルートテーブル

これはrails勉強した人なら、「AWS界のルーティング」といえばわかると思います。送られてきたデータはルートテーブルを基に振り分けられます。
もう少し具体的な内容で説明すると、インターネットで使われる「TCP/IP」(ネットワークをする際の規格・ルール)ではパケットという単位でデータのやりとりをします。そのパケットには宛先IPアドレスの情報が書かれています。その宛先IPアドレスを基にルーターが次々に宛先に近いネットワークへとパケットを転送することで、最終的に目的地までデータを届けることができるのです。逆にルーターが、どの宛先IPアドレスがきたときどこに転送すればいいかわからないと困りますよね。そこでルートテーブルに設定を記載するのです。すなわちルートテーブルとは、「どの宛先IPアドレスがきたとき、どこにデータを送るかを記したメモ」です。

それではルートテーブル作成しましょう。左のサイドメニューからルートテーブルを選択しましょう。するとすでにルートテーブルが存在しています。実はサブネットを作成したときに、デフォルトのルートテーブルが作成されるのです。ちなみにデフォルトのルートテーブルの意味は「送信先(宛先IPアドレス)が10.0.0.0/16(VPC領域)であれば、ローカルのネットワークにデータを転送する」という意味になります。(下記参照)
スクリーンショット 2020-10-17 22.54.47.png

ただこのままではインターネットと通信ができません。そこでインターネットゲートウェイへ転送する設定のルートテーブルを作成しましょう。ルートテーブル作成ボタンをクリックしてください。ここは名前を入力しと先ほど作ったVPCを選択して完了です。
スクリーンショット 2020-10-17 22.52.38.png

そして次に作成したルートテーブルの設定と先程作ったサブネットを紐付けが必要です。先程作ったルートテーブルを選択すると下の方にそのルートテーブルの詳細メニューが表示されます。まずはルートを選択しルートの追加ボタンを押しましょう。そして送信先を0.0.0.0/0にし、ターゲットをINTERNET GATEWAYにすればOKです。(INTERNET GATEWAYを選択するとidが勝手にでてきます)
スクリーンショット 2020-10-17 22.47.39.png

次にサブネットの関連付けです。サブネットの関連付けを選択し、サブネットの関連付けの編集ボタンを押しましょう。先ほど作成したサブネットを選択肢完了です。
スクリーンショット 2020-10-17 22.47.06.png
以上でインターネットと通信できるルートテーブルの設定が完了しました。

セキュリティグループ

セキュリティグループはその名の通りセキュリティに関する設定です。通信の種類によって通信するか、拒否するかを設定できます。早速作成しましょう。左のサイドメニューからセキュリティグループを選択肢、セキュリティグループを作成を選択します。そうすると下記画面がでてくると思います。スクリーンショット 2020-10-17 23.12.17.png

  • セキュリティグループ名・説明はわかりやすい名称を入れてください。
  • VPCは先程作成したものを選択してください。
  • インバウンドルールは簡単にいうと受信の設定です。ここには{タイプ:SSH 送信先:マイIP}、{タイプ:HTTP 送信先:任意の場所}を選択してください(※それ以外の欄は自動入力されます)。これでSSHとHTTPの通信が受信できるようになりました。
  • アウトバウンドルールは簡単にいうと送信の設定です。ここはデフォルトのままでOKです

以上でセキュリティグループの設定完了です。


少し長くなってしまったので④と⑤は次回の記事に書きます。(④と⑤が重いので、、、、)
ここまででネットワークの構成は下記の用になっているはずです。※ヘタですいません
subnet.png
次回はサブネットの中にEC2を作成していきたいと思います。

感想・まとめ

ここに関しては、「Amazon Web Services 基礎からのネットワーク&サーバー構築」という図書をみながらやった結果非常にスムーズにいきました。ネットワークの知識もつけたし、AWSでネットワークやサーバー構築する際の流れもなんとなくわかりました。ただネットワーク関連はまだ知識が浅いので別途勉強が必要だなとも思いました。

参考

  • 「Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂3版 著 大澤文孝,玉川憲,片山暁雄,今井雄太」 
    →おすすめの本です。AWSだけでなくネットワーク知識についても触れているので、初学者にとっては神技術書です。

  • (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
    →こちらもわかりやすくてよかったです。AWSの内容は「Amazon Web Services 基礎からのネットワーク&サーバー構築」とほとんど同じです。なのでこちらだけでAWSやってみるのもありかと思います。ただネットワーク知識が浅い人やインフラ初心者は最初に「Amazon Web Services 基礎からのネットワーク&サーバー構築」にやってネットワーク知識補充しながらやらないと苦労すると思います

※本記事は上記2つを参考にさせていただきながら実装しています。
なので実装に関しては類似箇所も多いかと思いますが、WEBサーバーの種類・DBのバージョンなどの構成などはもちろん自分なりにアレンジしています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む