Help us understand the problem. What is going on with this article?

【AWSハンズオン】Nuxt + Golang構成のWebアプリをAWSへデプロイしよう!

みなさん、こんにちは!
学生サーバサイドエンジニアのくろちゃんです。

今日はAWSを題材に、自分で作ったWebアプリケーションをデプロイできるようになることを目指して記事を書かせていただきます!

この記事を最後まで読むことで、下記のようなことができるようになります!

  • 自分のWebアプリケーションを公開できるようになる
  • AWSの下記のサービスを使えるようになる
    • VPC
    • EC2

ぜひ最後まで一緒に手を動かしながら楽しんでいってくださいね👍

なお、この記事はCA Tech Dojo/Challenge/JOB Advent Calendar 2019(22日目)の記事になります!

前日の@yawn_yawn_yawn_さんのUbuntu + nginx + LetsEncryptでSSL/TLSを設定するからバトンを引き継いでお送りしています。まだ見てないよって方はそちらも合わせてどうぞ!

では、早速ハンズオン始めていきましょう〜!!


前提条件

これらはできることを前提として話を進めていきますのでご了承ください。

※なお、本ハンズオンはOS Xを対象ユーザとして定めていますので、Windowsその他OSを使用している皆さんにつきましては適時読み替えて頂きますようにお願いします。

目次

本ハンズオンでは下記のような流れでWebアプリケーションの公開〜自動デプロイの構築までを行っていきます。

0. 事前準備
1. VPCを構築しよう!
2. EC2インスタンスを起動しよう!
3. Webアプリをデプロイしよう!

0. 事前準備

本ハンズオンでは私が事前に作っておいたアプリケーションを使用します。
下記の手順に従ってアプリケーションをダウンロード&動作確認してみましょう!

GitHubリポジトリをforkしてこよう!

下記のGitHubリポジトリから自分のリポジトリへforkしてきましょう!

▼まずはアクセス▼
https://github.com/Takumaron/AWS_tutorial

スクリーンショット_2019-12-21_14_28_09.png

フォーク先を指定して、きちんとフォークできていれば下記のような画面になります。(Qiita-test-aws-tutorialの部分は皆さんのGitHubアカウント名になります。)

スクリーンショット 2019-12-21 14.26.38.png

続いて、Forkしてきたリポジトリを自分のPCにクローンしてきます。

スクリーンショット_2019-12-21_14_31_25.png

ターミナルを開いて下記のコマンドを入力してください。

git clone [コピーしたURL]

下記のような出力結果が得られれば正常にクローンできています。

$ git clone git@github.com:Qiita-test-aws-tutorial/AWS_tutorial.git
Cloning into 'AWS_tutorial'...
remote: Enumerating objects: 55, done.
remote: Counting objects: 100% (55/55), done.
remote: Compressing objects: 100% (45/45), done.
remote: Total 55 (delta 9), reused 49 (delta 5), pack-reused 0
Receiving objects: 100% (55/55), 155.68 KiB | 484.00 KiB/s, done.
Resolving deltas: 100% (9/9), done.

アプリケーションが正常に動作するかチェックしよう!

クローンまでできたら、自分の環境で正しく動作するか検証しましょう。
下記のコマンドを入力してください。

$ cd AWS_tutorial
$ make start
docker-compose up -d
Building api_server
Step 1/4 : FROM golang:1.12.4-alpine
 ---> b97a72b8e97d
Step 2/4 : COPY ./ /go/aws_tutorial
 ---> 4fda45b3bf59
Step 3/4 : WORKDIR /go/aws_tutorial
 ---> Running in 421be46cf16b
Removing intermediate container 421be46cf16b
 ---> 032f324638b8
Step 4/4 : RUN apk update   && apk add --no-c

---- 中略(少し時間がかかります。少々お待ちください。) -----

Creating aws_tutorial_api_server_1 ... done
Creating aws_tutorial_client_1     ... done

Dockerコンテナが正常に立ち上がったら、お好みのWebブラウザを開いて http://localhost:3000/hello へアクセスしてください。
下記のような画面が表示されていれば、OKです!お疲れ様でした。

スクリーンショット 2019-12-22 9.01.53.png

1. VPCを構築しよう!

さっそく、先ほどローカル上で動作確認したアプリケーションをAWSに乗せていきます!

まずはVPCというサービスを使って、グローバルなWebの世界に自分の領域を作っていきます。下記の手順に従って一緒に設定していきましょう!

まずは、AWSマネジメントコンソールへサインインします。

https://console.aws.amazon.com/console/home?region=us-east-1

サインインが完了したら、左上の「サービス」をクリックして下記の画像のようにVPCを検索します。

スクリーンショット_2019-12-22_9_06_50.png

このような画面は開けましたか?

スクリーンショット_2019-12-22_9_12_41.png

今回構築するVPCの全体像

Untitled Diagram.png

出た!訳のわからない図!!って言って諦めないでくださいw
システム構成図も理解できればそんなに大したものではありません。

まず押さえていただきたいポイントは、VPCのなかにパブリックサブネットっていう奴があって、その中にEC2っていうものが動いているというざっくりしたイメージです。

分かりやすい例えがないかなと一生懸命考えて思いついた「家の例え」でこの構成を説明していきます。

まずはこの対応表を頭にいれてください。

サービス名 家に例えると?
VPC 🏠 家
インターネットゲートウェイ 🚪 玄関
サブネット 🛋 部屋
EC2 👨‍🦱 住人

イメージとしては、

家(VPC)に外部から人がやってきたときには、玄関(インターネットゲートウェイ)を通して家に入ります。そして、部屋(サブネット)へ案内をして、住人(EC2)がおもてなしします。

という一連の流れで理解するとそれぞれの役割が明確になるのではないでしょうか?

それぞれのサービスの役割が理解できたところでハンズオンに戻っていきましょう!

VPCを作成する

スクリーンショット_2019-12-22_9_54_49.png

スクリーンショット_2019-12-22_10_03_58.png

サブネットを作成する

スクリーンショット_2019-12-22_10_10_46.png

スクリーンショット_2019-12-22_10_14_24.png

インターネットゲートウェイを作成する

スクリーンショット_2019-12-22_10_22_04.png

スクリーンショット_2019-12-22_10_24_51.png

スクリーンショット_2019-12-22_10_26_43.png

スクリーンショット_2019-12-22_10_31_47.png

ルートテーブルを編集する

サブネット(部屋)やインターネットゲートウェイ(玄関)がバラバラに存在している状態なので、それぞれの対応づけをしていきます。
スクリーンショット_2019-12-22_10_38_45.png

スクリーンショット_2019-12-22_10_45_37.png

スクリーンショット_2019-12-22_10_48_08.png

スクリーンショット_2019-12-22_10_50_49.png

スクリーンショット_2019-12-22_10_53_16.png

VPCの構築はここまでで完了となります!お疲れ様でした!
次は、VPCの中で動作するEC2インスタンスを作成していきます。

2. EC2インスタンスを起動しよう!

Webアプリケーションを動かすための場所作りは1. VPCを構築しよう!にて完了したので、実際に作ったWebアプリケーションを動かしてくれるマシーンを構築していきましょう!

【補足】
EC2インスタンスとは、仮想サーバーのようなものです。
AWSが事前に用意しているOSや独自で作成したOSイメージを使ってサーバを立てることができます。
今回は無料枠で利用できるAmazon Linux 2 AMIを利用します。

スクリーンショット_2019-12-22_11_08_31.png

スクリーンショット_2019-12-22_11_12_01.png

スクリーンショット_2019-12-22_11_14_05.png

スクリーンショット_2019-12-22_11_15_48.png

【変更点】のみ入力内容を修正して「次のステップ」へ

スクリーンショット_2019-12-22_11_21_08.png

スクリーンショット_2019-12-22_11_23_53.png

スクリーンショット_2019-12-22_11_25_25.png

スクリーンショット_2019-12-22_11_29_29.png

スクリーンショット_2019-12-22_11_34_29.png

スクリーンショット_2019-12-22_11_38_37.png

キーペアは後ほどEC2にローカルからつなぎに行くときに必要になるファイルですので、ダウンロード後も無くさないようにしてくださいね!

ダウンロードが完了したら、「インスタンスの作成」をクリックすればEC2インスタンスの作成が始まります。(約2分ほど待てば下記のようにインスタンスの状態が「running」に切り替わると思います。)

スクリーンショット_2019-12-22_11_48_13.png

お疲れ様でした!
ここまででVPCの構築と、EC2インスタンスの起動まで終わりました!

あとは、EC2インスタンス上でWebアプリケーションを動かすだけです。もうちょっとなので一緒に頑張りましょう💪

3. Webアプリをデプロイしよう!

さぁ、あとは自作したWebアプリケーションをEC2上で動かすだけですね!

Webアプリのデプロイは下記のような手順で行なっていきます。

  1. EC2インスタンスにssh接続する
  2. GitコマンドとDocker・Docker-composeコマンドが使用できるようにパッケージをインストール
  3. GitHubからプロジェクトをクローンしてくる
  4. アプリケーションを立ち上げる

それでは、さっそく始めましょう〜!

EC2インスタンスにSSH接続しよう!

まずは、作成したEC2インスタンスにSSHで接続しましょう!

自分のEC2インスタンスのIPアドレスを知っておく必要があるので、下記の画像を参考にして、IPアドレスをコピーしておきます。

スクリーンショット_2019-12-22_11_48_13.png

それが完了したら、ターミナルを起動して下記のようなコマンドを打ちます。

# ダウンロードしたaws-tutorial.pemがあるディレクトリへ移動
$ cd ~/Downloads

# pemファイルを~/.sshへ移動
$ mv aws-tutorial.pem ~/.ssh

# pemファイルにアクセス権限を付与しておく
$ chmod 400 ~/.ssh/aws-tutorial.pem

# ssh接続
$ ssh -i "~/.ssh/aws-tutorial.pem" ec2-user@[自分のIPアドレス(ペースト)]
Are you sure you want to continue connecting (yes/no)? yes # ←初回起動時には`yes`と入力

ssh接続が完了すると、下記のようなコマンドプロンプトに切り替わります。


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

https://aws.amazon.com/amazon-linux-2/
8 package(s) needed for security, out of 17 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-0-10-151 ~]$

これでSSH接続は完了です!
ちなみに、SSH接続を切断する場合は、下記のコマンドを打ちます。

$ exit

GitとDockerを動かせるようにしよう!

SSH接続が完了したら、GitとDockerを使えるようにセットアップしていきましょう!

# yumをアップデート
$ sudo yum update -y

# Gitのインストール
$ sudo yum install git -y

# Dockerのインストール
$ sudo yum install -y docker

# Dockerの起動
$ sudo service docker start
$ sudo systemctl enable docker.service
$ sudo service docker status

# 下記のような出力結果が得られればOK
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 日 2019-12-22 03:26:02 UTC; 10s ago
     Docs: https://docs.docker.com
 Main PID: 12952 (dockerd)
   CGroup: /system.slice/docker.service
           └─12952 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd....

# dockerコマンドを使用可能にする
$ sudo usermod -a -G docker ec2-user

# 一度exit
$ exit

ここまででDockerとGitが動くようになりました。
SSHで再接続して、Docker-composeも入れていきましょう!

# スーパーユーザに切り替える
$ sudo -i

# 必要なファイルをダウンロード
curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 権限を与える
chmod +x /usr/local/bin/docker-compose

# 通常ユーザに戻る
exit

# 確認
$ docker-compose --version

GitHubからプロジェクトをクローンしてこよう!

DockerとGitが使えるようになったので、GitHubからアプリケーションをダウンロードしてきましょう!

https://github.com/[あなたのGitHubID]/AWS_tutorial へ遷移しましょう。

「Clone with HTTPS」モードでクローンURLをコピーします。

スクリーンショット_2019-12-22_12_37_15.png

コピーしたクローンURLを使ってEC2上にクローンしてきましょう!

$ git clone [ペースト]

# AWS_tutorialが存在するか確認
$ ls
AWS_tutorial

アプリケーションを立ち上げよう!

ここまでこれば準備万端!あとは立ち上げるだけですね😽

プロジェクトフォルダに移動して、アプリケーションを立ち上げましょう!

# プロジェクトフォルダへ移動
$ cd AWS_tutorial

# アプリケーションを立ち上げる
$ make start

...

Creating aws_tutorial_api_server_1 ... done
Creating aws_tutorial_client_1     ... done

立ち上がりました!
Webブラウザからアクセスをして動作チェックをしてみましょう!

http://EC2インスタンスのIPアドレス:3000/
スクリーンショット 2019-12-22 12.56.23.png

動いているみたいですね!
バックエンドとの連携もできているでしょうか?

http://EC2インスタンスのIPアドレス:3000/hello
スクリーンショット 2019-12-22 12.56.31.png

できているみたいですね!!

バックエンドAPIに対してブラウザからはアクセスできないことも確認しておきましょう。

http://EC2インスタンスのIPアドレス:8080/ping
スクリーンショット 2019-12-22 12.59.46.png

成功です!!お疲れ様でした:tada:
ハンズオンはここまでとなります。

【発展】
バックエンド側(:8080)にアクセスできない理由は分かりますか?
余裕のある方は、発展としてなぜアクセスできないのか考えてみてください!(ヒントは、セキュリティグループです!)


いかがだったでしょうか?
かなり長いハンズオンになってしまいましたが、ここまで読んでいただきましてありがとうございました!

今回はVPCとEC2を使って簡単なWebアプリケーションをデプロイしました。

次はRDSというサービスを使ってDB機能を持たせたり、Code Buildというサービスを使って自動デプロイを実現できるようなハンズオンを作りたいと思います!

明日のCA Tech Dojo/Challenge/JOB Advent Calendar 2019@hmarfさんが担当です!引き続きお楽しみください!!

▼こちらも要チェック!!

TakumaKurosawa
CA21卒サーバサイドエンジニア / 世界で1番シュークリームが好き / 好きな技術:Golang, Typescript, Nuxt.js, AWS, Docker, Kubernetes /
https://twitter.com/TakumaKurosawa
techtrain
プロのエンジニアを目指すU30(30歳以下)の方に現役エンジニアにメンタリングもらえるコミュニティです。
https://techbowl.co.jp/techtrain/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした