東京理科大学AdventCalendar2日目 やります、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の説明より抜粋)
当然初心者には、サブネットとかルートテーブルとか全くわかるわけありません
VPCの個人的な理解ですが、それは インターネットの柵だと思ってます。
この柵を作ることによって、データベースサーバなどを外界から隔絶し、より安全にインフラを作ろうという仕組みを実現できます
インフラの初見殺しなところが、VPCを構築したからといって、それが本当に外界から隔絶されているのか、逆にVPC内のサブネットの中だったら接続が本当にできるのか、よくわからないです
また、インターネットゲートウェイにつながないと逆に外界に接続できなかったり、本当によくわからない状態に陥ることが多いです
しかし、インフラで最も大事なのは間違いなくVPCの構成 だと確信しています
なのでVPCを構成し、正しく接続を確認するためにも、
VPCを一回作って苦しんでみることが非常に重要だと思います
それでもこの記事内でVPCの構成をつらつらと書いてもめんどくさいししょうがないので
CloudFormationで昔作ったVPCを貼ってしまいたいと思います
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ベースで管理することができ
しかも、この作成したインフラを可視化することができて
こんな感じでインフラの雰囲気や内部の構造を可視化することができます
このサブネットにEC2やRDSを紐付け、セクリティグループを正しく割り当てる(RDSなら3306のインバウンドがある、applicationサーバなら80番、443番、sshのための22番のインバウンド)ことによって、VPC内でのインフラが構築することができるようになります
privateサブネットにwebサーバは置くため、実際に動いているサーバを外界からアクセスさせるにはALBに紐づける必要があるのでまだ手順は色々ありますが、AWS/VPCによるインターネットのインフラの構築に関してはこんなところです(めちゃくちゃ省いてしまった)
中途半端な記事になってしまった感が否めないですがお次は
@saikishunsuke さん