2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CloudFormationでVPCNetworkを作る

Last updated at Posted at 2020-03-04

この記事

以前、VPC作ってEC2にひとまずWebサーバ用意するまで、という記事を書きましたが
https://qiita.com/shinon_uk/items/04e86115c7dd96018ec1

こういった基本的なVPC+PublicSubnet+Routetable...のセットをCFnで作るものを
ずっと記事連携させたかったので書きます。

対象は、いつもマネジメントコンソールで個別に構築してるけど
AWSのDevOpsとかインフラ自動化とか、手を伸ばしてみようかなーという方になると思います。
コードを短くしたいので、EC2+SecuriyGroupは別回にして、構築作業はGUIから行います。

#やること

今回は「あとはEC2を立てるだけ」の状態にしたいので
以下最低限のリソースをCloudFormationで作成します。

・VPC
・Subnet(Public + Private)
・RouteTable(Route含む)
・InternetGateway

#知る

###CloudFormationとは
どんなAWSサービスでも、大体Blackbeltを見れば用途は理解できます。
※下記資料:Published on Nov 28, 2018
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-aws-cloudformation?ref=https://aws.amazon.com/jp/blogs/news/webinar-bb-cfn-update-2018/

・JSON/YAMLのテキストファイルで、あらゆるリージョンのAWSリソースをプロビジョニングできる
対応リソース:https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

・プロビジョニングしたAWSリソースの変更/削除が可能で、ソフトウェアに対して行うのと同じように、AWSインフラを管理できる

・CloudFormation自体の料金は発生しない、作成したリソース分のみ

###CloudFormationのセクション

抜粋して記載します。

  • AWSTemplateFormatVersion
    フォーマットのバージョンを指定する。2020/02現時点では、 たった一つのバージョン2010-09-09が最新である。

  • Description
    作成するテンプレートの説明を記載する。

  • Parameters
    カスタマイズが必要なパラメータを、CFn流すときに渡すためのもの。例えば、作成する環境名、ドメイン名など。

  • Resources
    必須である、リソース記載部分。テンプレートで説明できる最も小さなブロックである。

  • Outputs
    テンプレートを作成した際に値を返す物を定義する。

尚、テンプレートはJSON、YAMLで定義できる。YAMLが使用可能ということは、例えばIAM RoleをYAMLで定義することも可能というメリットもある。
以降、YAMLで記載

#作る

###ドキュメント
AWSが公開しているブループリントを見てもいいんですが、
ドキュメントを参照して行きます。
例えば、VPCリソース
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
各プロパティの必須項目が

必須: はい

となっている場合は、記載が必要です。
あとは例を見て作成。

1 Resources:
2   VPC:
3     Type: AWS::EC2::VPC
4     Properties:
5       CidrBlock: !Ref VpcCidr
6       InstanceTenancy: default
7       EnableDnsSupport: true
8       EnableDnsHostnames: true
9       Tags:
10        - Key: Name
11          Value: !Sub '${AppName}-${Environment}-vpc'

2行目、リソースIDは一意であれば自由に決められます。
3行目、Typeでリソースを実際に指定しています。
あとは該当するリソース(Type)のドキュメントを見ながら作成するイメージですね。(先述)

また、11行目のValueに !Sub がありますが、組込関数で同一コード内のIDを参照しています。
!Sub, !Ref は参照によく使う組み込み関数です。

他にも組み込み関数はたくさんありますが、必要になったら使う、などでいいと思います。
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html

####何はともかくやってみる

###テンプレート

作成したテンプレートは下記です。
適宜日本語コメントも入れています。

AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC Template'

#このセクションはCFn流す際に与えるパラメータの定義
Parameters:

#サービス名など
  AppName:
    Description:  Please specify the application name.
    Type:         String
    Default:      "example"

#環境名
  Environment:
    Description:    Please specify the target environment.
    Type:           String
    Default:        "dev"
    AllowedValues:
      - prod
      - stg
      - dev

#VPCのIP指定
  VpcCidr:
    Description: Please specify the VPC IP
    Type: String
    Default: '10.0.0.0/16'
    AllowedPattern: '((\d{1,3})\.){3}\d{1,3}/\d{1,2}'

#各SubnetのIP指定
  Public1SubnetCidr: 
    Description: Please specify the Subnet IP for Public1
    Type: String
    Default: '10.0.0.0/20'

  Private1SubnetCidr: 
    Description: Please specify the Subnet IP for Public1
    Type: String
    Default: '10.0.64.0/20'

リソース定義

Resources:

  #VPCを定義
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      #Parameters参照
      CidrBlock: !Ref VpcCidr 
      InstanceTenancy: default
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          #複数のParameters参照して繋げて作成
          #defaultの値で指定だと example-dev-vpc というValueになる
          Value: !Sub '${AppName}-${Environment}-vpc'

  #IGWを定義
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub '${AppName}-${Environment}-igw'

#IGWをVPCにアタッチ
#マネジメントコンソールでやっている作業を定義しているだけ
  VPCInternetGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      #アタッチしたいVPCを参照
      VpcId: !Ref 'VPC'
      InternetGatewayId: !Ref 'InternetGateway'


#Subnetを定義する

  #Public Subnetを定義
  SubnetPublic1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref Public1SubnetCidr
      AvailabilityZone: !Select [ 0, !GetAZs ]
      MapPublicIpOnLaunch: true
      VpcId: !Ref 'VPC'
      Tags:
        - Key: Name
          Value: !Sub '${AppName}-${Environment}-Public1'

  #Private Subnetを定義
  SubnetPrivate1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref Private1SubnetCidr
      AvailabilityZone: !Select [ 0, !GetAZs ]
      VpcId: !Ref 'VPC'
      Tags:
        - Key: Name
          Value: !Sub '${AppName}-${Environment}-Private1'


#RouteTableを定義

  #Route Table for Publicを定義
  RouteTablePublic:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref 'VPC'
      Tags:
        - Key: Name
          Value: !Sub '${AppName}-${Environment}-rt-public'

  #Route Table for Privateを定義
  RouteTablePrivate:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref 'VPC'
      Tags:
        - Key: Name
          Value: !Sub '${AppName}-${Environment}-rt-private'


#RouteTableにRouteを定義する

  #Route Table for PublicにRouteを1つ定義
  RoutePublic:
    Type: AWS::EC2::Route
    DependsOn: VPCInternetGatewayAttachment
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      RouteTableId: !Ref 'RouteTablePublic'
      GatewayId: !Ref 'InternetGateway'


#各Subnetを、各RouteTableに関連づける

  #Route Table for PublicにPublic Subnetを関連づける
  SubnetRouteTableAssociationPublic1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref 'RouteTablePublic'
      SubnetId: !Ref 'SubnetPublic1'

  #Route Table for PrivateにPrivate Subnetを関連づける
  SubnetRouteTableAssociationPrivate1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref 'RouteTablePrivate'
      SubnetId: !Ref 'SubnetPrivate1'

最後に、Outputセクションで値を出力しておきます。
今回は使わないんですが、例えば他のテンプレートに値を渡したい時に使用したりします。
その話はスタック構成含めて別記事で出します。

Outputs:

  VpcId:
    Description: VPC ID
    Value: !Ref 'VPC'
    Export:
      Name: !Sub '${AWS::StackName}-VpcId'

  SubnetPublic1:
    Description: Public subnet 1
    Value: !Ref 'SubnetPublic1'
    Export:
      Name: !Sub '${AWS::StackName}-PublicSubnet1'

  SubnetPrivate1:
    Description: Private subnet 1
    Value: !Ref 'SubnetPrivate1'
    Export:
      Name: !Sub '${AWS::StackName}-PrivateSubnet1'

###実際に流す作業

テンプレート(コード)はローカルに保存してもS3でも、ひとまずは大丈夫です。
以下はアップロードするパターン。

①みんな大好きマネジメントコンソールで、CloudFormationを開く。

0304q1.png

②スタックの作成へ

0304q2.png0304q3.png


直接アップロードなのでこっち(S3にファイルは保存されます。)
0304q4.png

ファイルを指定して次に進みます。
この時点で文法エラーなどあれば、画面上にエラー出力してくれます。修正。
(大文字小文字とか自分あるある)

③パラメータ指定

始めはdefaultで指定した値が入っています。
テンプレート内で扱う名前がある場合は、アプリ名やサービス名などをここで指定します。

0304q5.png


次へを押していく。

0304q6.png


最後にパラメータで指定した値を確認

0304q7.png


スタックの作成を押して、流します。

0304q8.png

CREATE IN PROGRESSになれば作成が始まっています。
仮に問題があって一つでも作成ができなかった場合は、デフォルトでロールバックされます。
※設定は作成時に設定変更可能

0304q9.png


右上のボタンを押して更新できます。
最終的に、左のスタック画面で以下のように表示されれば完成です。

0304q10.png

リソースタブからもみることができますが、作成したリソースを確認してください。

各リソースの変更は、各サービスの変更画面から可能ですが、
テンプレートを修正して更新する事もできます。

削除する際は、スタックの削除を押せば、テンプレートのリソースが一括で削除されるのでとても便利です。

Github
https://github.com/shinon-uk/CloudFormation/tree/master/vpc-sample

#最後に

久しぶりの記事になりました。

まだまだCloudFormationでやれることはあるので、

後日またスタック構成にしたCLIベース構築の話を記載する予定です。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?