■
CloudFormationを使ってみる
概要
インフラ構築の自動化の方法を覚えたかったためCloudFormationを使ってみました。
Application Load Balancer を使ってみる : プライベートなAPIをパスでアクセス制限したい - tkaaad97’s diary
前にアプリケーションロードバランサーの実験で試した構成で試しました。
ただEC2を立てるところはちょっと複雑そうで実際CloudFormationでやるか微妙な気がしたので前と同様に手動で作りました。
CloudFormationテンプレート
下のテンプレートで構築できました。スペル間違いなどで何回かstack作り直しました。 スペル間違いとか作る前に検出して欲しいところですが実際作ってみないとエラーにならないようでちょっと不便だなと思いました。
AWSTemplateFormatVersion: "2010-09-09" Description: application load balancer experiment Parameters: EnvName: Type: String Description: Environmanet Name VpcIpBlock: Type: String Description: VPC CIDR Block AllowedPattern: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2} Subnet1IpBlock: Type: String Description: VPC CIDR Block AllowedPattern: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2} Subnet2IpBlock: Type: String Description: VPC CIDR Block AllowedPattern: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2} Resources: Vpc: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcIpBlock EnableDnsSupport: True EnableDnsHostnames: True Subnet1: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !Ref Subnet1IpBlock VpcId: !Ref Vpc Subnet2: Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !Ref Subnet2IpBlock VpcId: !Ref Vpc Igw: Type: AWS::EC2::InternetGateway VpcIgwAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref Igw VpcId: !Ref Vpc RouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref Vpc Route: Type: AWS::EC2::Route Properties: RouteTableId: !Ref RouteTable DestinationCidrBlock: "0.0.0.0/0" GatewayId: !Ref Igw RouteTableAssoc1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTable SubnetId: !Ref Subnet1 RouteTableAssoc2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTable SubnetId: !Ref Subnet2 PublicLb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: !Join ["", [!Ref EnvName, PublicLb]] Scheme: internet-facing SecurityGroups: [!Ref PublicLbSecurityGroup] Subnets: [!Ref Subnet1, !Ref Subnet2] Type: application PublicLbListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref PublicLbErrorTargetGroup Type: forward LoadBalancerArn: !Ref PublicLb Port: 80 Protocol: HTTP PublicLbListenerRule: Type: AWS::ElasticLoadBalancingV2::ListenerRule Properties: Actions: - Type: forward TargetGroupArn: !Ref PublicLbTargetGroup Conditions: - Field: path-pattern Values: - "/public*" ListenerArn: !Ref PublicLbListener Priority: 1 PublicLbTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckPath: /public HealthCheckPort: 80 Name: !Join ["", [!Ref EnvName, PublicLbTG]] Port: 80 Protocol: HTTP VpcId: !Ref Vpc PublicLbErrorTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckPath: / HealthCheckPort: 80 Name: !Join ["", [!Ref EnvName, PublicLbErrorTG]] Port: 80 Protocol: HTTP VpcId: !Ref Vpc PrivateLb: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: !Join ["", [!Ref EnvName, PrivateLb]] Scheme: internal SecurityGroups: [!Ref PrivateLbSecurityGroup] Subnets: [!Ref Subnet1, !Ref Subnet2] Type: application PrivateLbListener: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: !Ref PrivateLbErrorTargetGroup Type: forward LoadBalancerArn: !Ref PrivateLb Port: 80 Protocol: HTTP PrivateLbListenerRule: Type: AWS::ElasticLoadBalancingV2::ListenerRule Properties: Actions: - Type: forward TargetGroupArn: !Ref PrivateLbTargetGroup Conditions: - Field: path-pattern Values: - "/private*" ListenerArn: !Ref PrivateLbListener Priority: 1 PrivateLbTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckPath: /private HealthCheckPort: 80 Name: !Join ["", [!Ref EnvName, PrivateLbTG]] Port: 80 Protocol: HTTP VpcId: !Ref Vpc PrivateLbErrorTargetGroup: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckPath: / HealthCheckPort: 80 Name: !Join ["", [!Ref EnvName, PrivateLbErrorTG]] Port: 80 Protocol: HTTP VpcId: !Ref Vpc PublicLbSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Join ["", [!Ref EnvName, PublicLbSG]] GroupDescription: Security Group For Public Load Balancer SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - IpProtocol: "-1" CidrIp: 0.0.0.0/0 VpcId: !Ref Vpc PrivateLbSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Join ["", [!Ref EnvName, PrivateLbSG]] GroupDescription: Security Group For Private Load Balancer SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: !Ref VpcIpBlock SecurityGroupEgress: - IpProtocol: "-1" CidrIp: 0.0.0.0/0 VpcId: !Ref Vpc AppServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Join ["", [!Ref EnvName, AppServerSG]] GroupDescription: Security Group For Application Server SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !GetAtt [PublicLbSecurityGroup, GroupId] - IpProtocol: tcp FromPort: 80 ToPort: 80 SourceSecurityGroupId: !GetAtt [PrivateLbSecurityGroup, GroupId] SecurityGroupEgress: - IpProtocol: "-1" CidrIp: 0.0.0.0/0 VpcId: !Ref Vpc
参考
テンプレートフォーマット
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-formats.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-anatomy.html
パラメーター
VPC
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
インターネットゲートウェイ
VPCゲートウェイアタッチメント
サブネット
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html
ルートテーブル
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html
ロードバランサー
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-loadbalancer.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-targetgroup.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-listener.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-listenerrule.html
セキュリティグループ
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-security-group-egress.html
感想
CloudFormationでVPC、サブネット、ロードバランサー、セキュリティグループなどの構築ができました。 テンプレートを書いてみると思ったよりも長くなって、手動でも同じ内容でポチポチ設定していたはずなので自動化できると効率的だと思います。 ただテンプレートを書くのはもう少し便利なツールなどができるといいなという気がしました。 個人的にはGUIで組み立てるよりはIDEで補完して作成したり、バリデーションしたりができるといい気がしました。 EC2まわりのアプリデプロイと関連したあたりを今後調べてみたいです。