はじめに
CloudFormationがよくわからんという人
この記事は下記記事の続きの記事です。
「CloudFormationの基本的な文法を知りたい」「CloudFormationの使い方がわからん」といった場合は、↑の記事を読むことをおすすめする。
EC2とかVPCとかサブネットがよくわからんという人
こんな場合はこっちの記事を読むと良い。
- EC2やVPCやサブネットがよくわからない
- EC2はわかるけどなんでVPCやサブネットが必要なのかわからない
この記事の対象者
CloudFormationの基本的な文法や、やEC2, VPC, サブネットについては理解しているが、EC2インスタンスを立てるのにどうやって書いていったらいいのかわからーんという人。
CloudFormationでEC2サーバー2台の構成を建てる
AWSで何かサービスを建てる時、最も簡単なのは「EC2インスタンスを1台建てて、そこでアプリケーションを動かす」構成だ。これをCloudFormationで構成しようと思う。*1
CloudFormationとは?(わかっていれば読まなくて良い)
AWSのサーバー構成を記述すると、その通りにサーバーを建ててくれるというものだ。例えば「Webサーバーが1台でポート80を開ける。CPUのスペックはこんなもん。DBサーバーが1台あってWebサーバーからのMySQL接続だけを許可」といったことが記述できる。
CloudFormationを利用しなくても、WebのUIでボタンを押していけばサーバーを建てること自体は可能だ。しかし、「もう一回同じ構成を作ってくれ」と言われた場合に *2、は大変だ。しかしCloidFormationならAnsibleの用に設定ファイルを流し込むだけて全く同じ構成のものが作れる。これがCloudFormationを利用するメリットである。
構築してみる
今回は development.yml
として、Dev環境を構築するというシナリオで行う。
VPCを作成する
VPCを作るだけならすごく簡単なので、まずはVPCを構築してみる。 [AWSをはじめてみる2 - CloudFormationでのプロビジョニング・構成管理 - 猫でもわかるWebプログラミング の方も、VPCの作成を題材にしているので参考にしてもらいたい。
AWSTemplateFormatVersion: '2010-09-09' Description: "Create dvelopment environment" Resources: DevelopmentVPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 Tags: - Key: Name Value: Development-VPC
今後は、Resources 以下のみ書いていくので注意してもらいたい。
DevelopmentVPC:
と書き始める。ここの名前は何でもいいが、他と被らない名前にする必要があるので、今回はDevelopmentVPC
としたProperties
以下の VPC の設定を書いていく
CidrBlock
CIDRというのは x.x.x.x/16
のような書き方のこと。このVPCで利用するIPの範囲を指定する。10.0.0.0/16
は 10.0.0.0
〜 10.0.255.255
の範囲を利用することを示す。*3 ふつうはVPCを /16
にしてサブネットを /24
とかにするので、それに習って今回は /16
とした。((サーバーの台数によってはIPが足りなくなったりするので適宜いい感じに設定してあげてください。わからなければ思考停止で /16
でいいと思います。))
Tags
Tags: - Key: Name Value: Development-VPC
高こう定するとここのNameのところに Development-VPC と表示される。付けなくても良いのだが、Webのコンソールから見た時かなり見づらいので、設定したほうが良い。完全にWebの見た目だけのための設定なので好きに設定して良い。この設定に限らない話だが、日本語を使うとAWSのWeb上で文字化けするので英語を推奨する。
ここまででVPCの作成は終わりなので、一度CloudFormationを流してみて正しくVPCができていることを確認するとよい。次回以降は「スタックの更新」を行えば差分だけが適用されるし、「スタックの削除」を行えば今回作ったVPC, EC2などはすべて削除できるので、切りの良いところまでできたら流してみて文法ミスがないかなどをチェックしてほしい。*4
インターネットゲートウェイの設置
VPCを作成したらインターネットゲートウェイを設置してやる必要がある。VPC内に設置されたEC2インスタンスはインターネットゲートウェイを経由しなければインターネットにアクセスできない。逆に外からVPC内にアクセスする場合もインターネットゲートウェイを通る。インターネットゲートウェイの主な役割はVPC内外でのアドレス変換である。 *5
このインターネットゲートウェイは結構複雑だ。長いので適宜コメントで補足しているので見てほしい。以下の設定が書かれている。
- Gatewayを作成
- GatewayをVPCに配置
- ルートテーブルを作成。ルートテーブルとは「VPCの中から外に出る場合はGatewayを通ってアドレス変換してね」というのを記述するものである。
- ルートテーブルの内容を設定
# VPC内とインターネットをつなぐGatewayを作成 DevelopmentInternatGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: Development-VPC-Gateway # GatewayをVPCに配置する # Gateway作成とは別に配置の設定が必要となる AttachDevelopmentGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: # VpcIdで指定されたVPCに、InternetGatewayIdで指定されたGatewayを配置する VpcId: !Ref DevelopmentVPC InternetGatewayId: !Ref DevelopmentInternatGateway # ルートテーブルを作成 DevelopmentRouteTable: Type: AWS::EC2::RouteTable # このようにDependsOnを書くと、AttachGatewayが完了してから # ルートテーブルが作成される。 # Proertiesの中でDevelopmentVPCを参照しているので、 # DevelopmentVPCが作られたあとに実行されることは保証されているが、 # AttachされているかどうかはわからないのでDependsOnで明記する必要がある DependsOn: AttachDevelopmentGateway Properties: VpcId: !Ref DevelopmentVPC Tags: - Key: Name Value: Development-RouteTable # ルートテーブルの設定 DevelopmentGatewayRoute: Type: AWS::EC2::Route DependsOn: AttachGateway Properties: # VPC内から外へのすべての通信はInternetGatewayを通るようにする設定を # DevelopmentRouteTable に入れる。 RouteTableId: !Ref DevelopmentRouteTable # 0.0.0.0/0 はすべてのIPを表す(VPC内のアドレスは除く) DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref AsadaigakuDevInternetGateway
ちょっと複雑だったがこれでVPCの中とインターネットが接続できるようになった。これを行わないと、VPC内のサーバーはインターネットにアクセスできないし、*6 外から中にhttpでアクセスしたりSSHしたりすることもできない。
サブネットの作成
サブネットの作成はVPCと同じでシンプルだ。
# ユーザー(開発者)がインターネット経由でアクセスできるサブネット DevelopmentPublicSubnet: Type: AWS::EC2::Subnet DependsOn: AttachGateway Properties: CidrBlock: 10.0.1.0/24 MapPublicIpOnLaunch: true VpcId: !Ref DevelopmentVPC Tags: - Key: Name Value: Development-Public-VPC
ここまで読めたならもうこれは読めるだろう。IPアドレス帯としては 10.0.1.0
〜 10.0.1.255
をこのサブネット用のものとして定義する。((これも先程のVPCと同様、特にこだわりがなければ /24
で良いだろう))
DevelopmentPublicSubnet
という名前をつけているが、これはインターネットからポート80または443でアクセスできるという意味で付けていますので、 DevelopmentWebServerSubnet
でもなんでも、なんかいい感じの名前を付けてください。
EC2インスタンスしか作らない場合、サブネットの意義はあまり感じられませんが、EC2インスタンスを作成する際にサブネットは必要になるので、作る必要があります。
セキュリティグループの作成
セキュリティグループはEC2インスタンスに設定するセキュリティの設定です。「ここからここへはポート22のアクセスを許可」などの情報を書きます。
SSH用セキュリティグループの作成
まずは「SSH可能とするEC2インスタンスに設定するためのセキュリティグループ」を作成します。
# 開発環境EC2インスタンスにSSHするためのセキュリティグループ DevelopmentSSHSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref DevelopmentVPC GroupDescription: Enable SSH SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0
これももう読んでもらえればだいたい分かるかと思いますが、ポート22に来たtpcのアクセスを、アクセスもとがどこかにかかわらず常に許可する設定です。 VpcId
が設定されていますが、これは別にPC内部のすべてのインスタンスのポート22への接続を許可する わけではありません 。このセキュリティグループをEC2インスタンスに付与すると、そのインスタンスへのSSH接続が可能になります。
GroupDescription
は必須要素なので注意してください。
HTTP/HTTPS用セキュリティグループの作成
上記とほぼ同様です
# Webアプリケーションにアクセスできるようにするセキュリティグループ # VPNからのアクセスのみ許可する DevelopmentWebSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Enable web traffic to Instance VpcId: !Ref DevelopmentVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 - IpProtocol: tcp FromPort: 443 ToPort: 443
EC2インスタンスを立てる
ようやくEC2インスタンスを建てられます。
DevelopmentWeb: Type : AWS::EC2::Instance Properties: # Amazon Linux 2 ImageId: ami-0f9ae750e8274075b InstanceType: t2.micro SubnetId: !Ref DevelopmentPublicSubnet SecurityGroupIds: - !Ref DevelopmentSshSecurityGroup - !Ref DevelopmentWebSecurityGroup KeyName: sakamoto Tags: - Key: Name Value:Development-Web
これももう見たらわかるかと思います。EC2について全然わからん!って人は下記の記事を見ながら一度EC2インスタンスを立ててみるといいと思います。
ImageIdはAMIってやつです。OSみたいなものです。KeyNameは初期設定されるSSH用のキーの名前です。AMIやキー、インスタンスタイプについては↑のブログを呼んでみるといいです。
他は見ての通り、先ほど作成したサブネットやセキュリティグループを設定します。CloudFormationでスタックを作成してみたら、EC2のコンソールからIPを調べてSSH接続してみましょう。Keyが正しく設定されていれば
ssh ec2-user@<IP Address>
で接続できるかと思います。
ポート80も空いていますが、まだWebアプリケーションが動いていないので、接続しようとしてもなにも応答はありません。
さいごに
RDSだったり、Elastic IPだったりDNSだったりプロビジョニングだったり、まだいろいろやるべきことはありますのですが、長くなったので次回以降にします。
*1:EC2を利用する際にセットでRDSを使うことが多いが、RDSは結構複雑なので、次回以降で扱う
*2:例えばOSのバージョンを上げたいのでインスタンスを作り直したい、サーバー台数を増やしたいのでもう一台同じ設定で建てたい、といった状況が考えられる
*3:CIDRの読み方については簡単なのでググって調べてほしい
*4:yamlにミスがある場合はCloudFormationが流れる前にエラーが表示される。yamlにミスは無いが設定内容にミスがあったりする場合は、更新中にエラーがでてロールバックされたり、更新されたものの思い通りに設定できていなかったりするので注意してみてほしい。
*5:詳しくはNATでググってほしい。長くなるので細かくは説明しない
*6:インターネットにアクセスできないと、yumのようなコマンドは動かない