AWSでサクッとインフラ構築

[東京理科大学AdventCalendar2日目](https://qiita.com/advent-calendar/2018/tokyo_university_of_science) やります、[100010](https://github.com/100010)です

現在東京理科大学3年の理工学部機械工学科に属しております

鬼のようなレポートの時間を縫っていろんなサービスに触れて来ましたが












やっぱり一番触るのが難しくてブラックボックスなところはインフラかなとおもい、それをテーマに筆をとることにしました✒️

これまではRailsでdeployすることが多くて、それなりのユーザを捌けるようなおおきなサービスのインフラも見ることができる環境にも運良く巡り会えたこともあったので

今回はAWSの構成について書いていきたいなと思いました。

Railsアプリを想定したインフラを想定して書いていきたいと思います

# VPC とはなんぞや

公式ドキュメントを読んでみますがgoogle翻訳にかけたんじゃないかってくらい日本語なのか英語なのかよくわからない事を書いてます

```
Virtual Private Cloud (VPC) は、AWS アカウント専用の仮想ネットワークです。VPC は、AWS クラウドの他の仮想ネットワークから論理的に切り離されており、AWS のリソース (例えば Amazon EC2 インスタンス) を VPC 内に起動できます。VPC の IP アドレス範囲を指定して、サブネットを追加し、セキュリティグループを関連付けて、ルートテーブルを設定できます。

サブネットは、VPC の IP アドレスの範囲です。AWS リソースは、指定したサブネット内に起動できます。インターネットに接続する必要があるリソースにはパブリックサブネットを、インターネットに接続しないリソースにはプライベートサブネットを使用してください。パブリックサブネットとプライベートサブネットの詳細については、「VPC とサブネットの基本」を参照してください。

各サブネットでの AWS リソースの保護には、セキュリティグループ、ネットワークアクセスコントロールリスト (ACL) など、複数のセキュリティレイヤーを使用できます。詳細については、「セキュリティ」を参照してください。
```
([VPCの説明](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html)より抜粋)

当然初心者には、サブネットとかルートテーブルとか全くわかるわけありません


VPCの個人的な理解ですが、それは <b>インターネットの柵</b>だと思ってます。

この柵を作ることによって、データベースサーバなどを外界から隔絶し、より安全にインフラを作ろうという仕組みを実現できます

インフラの初見殺しなところが、VPCを構築したからといって、それが本当に外界から隔絶されているのか、逆にVPC内のサブネットの中だったら接続が本当にできるのか、よくわからないです

また、<b>インターネットゲートウェイ</b>につながないと逆に外界に接続できなかったり、本当によくわからない状態に陥ることが多いです

しかし、<b>インフラで最も大事なのは間違いなくVPCの構成</b> だと確信しています

なのでVPCを構成し、正しく接続を確認するためにも、

<h6>VPCを一回作って苦しんでみることが非常に重要だと思います</h6>


それでもこの記事内でVPCの構成をつらつらと書いても~~めんどくさいし~~しょうがないので

CloudFormationで昔作ったVPCを貼ってしまいたいと思います


```yml

AWSTemplateFormatVersion: 2010-09-09
Resources:
  VPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      Tags:
        - Key: Name
          Value: vpc-apn1
  SubnetPublic1a:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.5.0/24
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: 'true'
      Tags:
        - Key: Name
          Value: subnet-pub-apn1a
  SubnetPublic1c:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.6.0/24
      AvailabilityZone: ap-northeast-1c
      MapPublicIpOnLaunch: 'true'
      Tags:
        - Key: Name
          Value: subnet-pub-apn1c
  SubnetPrivate1a:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.7.0/24
      AvailabilityZone: ap-northeast-1a
      Tags:
        - Key: Name
          Value: subnet-prv-apn1a
  SubnetPrivate1c:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.8.0/24
      AvailabilityZone: ap-northeast-1c
      Tags:
        - Key: Name
          Value: subnet-prv-apn1c
  DbSubnetGroup:
    Type: 'AWS::RDS::DBSubnetGroup'
    Properties:
      DBSubnetGroupDescription: DB subnet group
      DBSubnetGroupName: db-subnet-group
      SubnetIds:
        - !Ref SubnetPrivate1a
        - !Ref SubnetPrivate1c
  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
        - Key: Name
          Value: igw-apn1
  GatewayToInternet:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  PublicRouteTable:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: rtb-pub-apn1
        - Key: Application
          Value: !Ref 'AWS::StackId'
        - Key: Network
          Value: Public
  PublicRoute:
    Type: 'AWS::EC2::Route'
    DependsOn: GatewayToInternet
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  PublicSubnetRouteTableAssociatio1a:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref SubnetPublic1a
  PublicSubnetRouteTableAssociatio1c:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref SubnetPublic1c
  EIPNat:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: vpc
  NatGateway1a:
    Type: 'AWS::EC2::NatGateway'
    DependsOn: EIPNat
    Properties:
      AllocationId: !GetAtt
        - EIPNat
        - AllocationId
      SubnetId: !Ref SubnetPublic1a
  PrivateRouteTable1a:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: rtb-prv-apn1
        - Key: Application
          Value: !Ref 'AWS::StackId'
  PrivateRoute1a:
    Type: 'AWS::EC2::Route'
    DependsOn:
      - NatGateway1a
      - PrivateRouteTable1a
    Properties:
      RouteTableId: !Ref PrivateRouteTable1a
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1a
  PrivateSubnetRouteTableAssociatio1a:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      RouteTableId: !Ref PrivateRouteTable1a
      SubnetId: !Ref SubnetPrivate1a
  SecurityGroupWeb:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupName: sg_web
      GroupDescription: security group for web
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIpv6: '::/0'
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '443'
          ToPort: '443'
          CidrIpv6: '::/0'
        - IpProtocol: tcp
          FromPort: '443'
          ToPort: '443'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          CidrIp: 0.0.0.0/0
      VpcId: !Ref VPC
  SecurityGroupDB:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupName: sg_db
      GroupDescription: security group for db
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '3306'
          ToPort: '3306'
          CidrIp: 0.0.0.0/0
      VpcId: !Ref VPC
  SecurityGroupStep:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      GroupName: sg_step
      GroupDescription: security group for step
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 0.0.0.0/0
      VpcId: !Ref VPC

```

AWS CloudFormation では、スタックという単位でインフラをyml/jsonベースで管理することができ
しかも、この作成したインフラを可視化することができて

![template1-designer.png](https://qiita-image-store.s3.amazonaws.com/0/105153/a233e944-623a-20a3-5840-368b972a17d1.png)


こんな感じでインフラの雰囲気や内部の構造を可視化することができます

このサブネットにEC2やRDSを紐付け、セクリティグループを正しく割り当てる(RDSなら3306のインバウンドがある、applicationサーバなら80番、443番、sshのための22番のインバウンド)ことによって、VPC内でのインフラが構築することができるようになります


privateサブネットにwebサーバは置くため、実際に動いているサーバを外界からアクセスさせるにはALBに紐づける必要があるのでまだ手順は色々ありますが、AWS/VPCによるインターネットのインフラの構築に関してはこんなところです(めちゃくちゃ省いてしまった)


中途半端な記事になってしまった感が否めないですがお次は
@saikishunsuke さん