Skip to content

ytabira/humidifier_sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

humidifier_sample

CloudFormationテンプレートをRubyスクリプトで作成できるHumidifierというgemを使ってVPC環境を構築します。Humidifierは標準のテンプレート記法(JSON)では実装できない環境変数や設定ファイルの取り込み、条件判断、ループなどをCloudFormationテンプレートの作成時に組み込むことが出来ます。

参照元

https://github.com/localytics/humidifier

前提条件

  • OS: macOS Sierra
  • Rubyバージョン: 2.2.5

準備

AWSアカウントの設定

環境変数にAWS認証情報とCloudFormationスタックをデプロイするリージョンを設定します。

export AWS_REGION=ap-northeast-1
export AWS_ACCESS_KEY_ID=AKIA****************
export AWS_SECRET_ACCESS_KEY=******************************

Humidifierのインストール

gem "humidifier"
gem "rake"
bundle install

基本的な使い方

最初にCloudFormationスタックを作成します。

stack = Humidifier::Stack.new(name: "sample-stack", aws_template_format_version: "2010-09-09")

次に作成したスタックにリソースを追加します。この例ではAWS::EC2::VPCをスタックに追加しています。

vpc = Humidifier::EC2::VPC.new(
  cidr_block: Humidifier.ref("VpcCidr"),
  enable_dns_support: true,
  enable_dns_hostnames: true
)
stack.add('VPC', vpc)

パラメータの仕様はCloudFormationテンプレートのリファレンスのパラメータをスネークケース化したものです。 引用元: https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html

{
   "Type" : "AWS::EC2::VPC",
   "Properties" : {
      "CidrBlock" : String,
      "EnableDnsSupport" : Boolean,
      "EnableDnsHostnames" : Boolean,
      "InstanceTenancy" : String,
      "Tags" : [ Resource Tag, ... ]
   }
}

パラメータも追加できます。

stack.add_parameter("VpcCidr", type: "String", no_echo: false)

上記Humidifier::EC2::VPC.newメソッドでHumidifier.refメソッドを使用してVpcCidrの値を参照しています。

最後にパラメータを指定してデプロイを実行します。

stack.deploy_and_wait(parameters: [ { parameter_key: "VpcCidr", parameter_value: "10.0.0.0/16" } ])

チェンジセットを作成する場合は以下です。

stack.create_change_set(parameters: [ { parameter_key: "VpcCidr", parameter_value: "10.0.0.0/16" } ])

Templateファイルはto_cfメソッドで取得できます。

puts stack.to_cf

スクリプトの例

CloudFormationスタックのクラスを作成し、Rakefileから実行するスクリプトの例です。

CloudFormationスタックを構築するクラス

VPCを作成するクラスです

require "humidifier"

class VPC

  ##
  #=== コンストラクタ
  def initialize(stack_name)
    @stack_name = stack_name
    stack.add_parameter("VpcCidr", type: "String", no_echo: false)
    stack.add("VPC", vpc)
    stack.add("Subnet1", subnet1)
    stack.add("Subnet2", subnet2)
    stack.add("InternetGateway", internet_gateway)
    stack.add("VPCGatewayAttachment", vpc_gateway_attachment)
    stack.add("PublicRouteTable", public_route_table)
    stack.add("PublicRoute", public_route)
    stack.add("Subnet1RouteTableAssociation", subnet1_route_table_association)
    stack.add("Subnet2RouteTableAssociation", subnet2_route_table_association)
    stack.add("PublicNetworkAcl", public_network_acl)
    stack.add("InboundHTTPPublicNetworkAclEntry", inbound_http_public_network_acl_entry)
    stack.add("InboundSSHPublicNetworkAclEntry", inbound_ssh_public_network_acl_entry)
    stack.add("InboundEphemeralPublicNetworkAclEntry", inbound_ephemeral_public_network_acl_entry)
    stack.add("OutboundPublicNetworkAclEntry", outbound_public_network_acl_entry)
    stack.add("Subnet1NetworkAclAssociation", subnet1_network_acl_association)
    stack.add("Subnet2NetworkAclAssociation", subnet2_network_acl_association)
    stack.add("DHCPOptions", dhcp_options)
    stack.add_output("VpcId", value: Humidifier.ref("VPC"))
    stack.add_output("Subnet1Id", value: Humidifier.ref("Subnet1"))
    stack.add_output("Subnet2Id", value: Humidifier.ref("Subnet2"))
  end

  ##
  #=== CloudFormationスタック
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html AWS::CloudFormation::Stack
  def stack
    @stack ||= Humidifier::Stack.new(
      name: @stack_name,
      aws_template_format_version: "2010-09-09",
      description: "Sample CloudFormation Stack"
    )
  end

  private

  ##
  #=== VPC
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
  def vpc
    Humidifier::EC2::VPC.new(
      cidr_block: Humidifier.ref("VpcCidr"),
      enable_dns_support: true,
      enable_dns_hostnames: true
    )
  end

  ##
  #=== サブネット1
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html
  def subnet1
    Humidifier::EC2::Subnet.new(
      vpc_id: Humidifier.ref("VPC"),
      availability_zone: "ap-northeast-1b",
      cidr_block: "10.0.0.0/24"
    )
  end

  ##
  #=== サブネット2
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html
  def subnet2
    Humidifier::EC2::Subnet.new(
      vpc_id: Humidifier.ref("VPC"),
      availability_zone: "ap-northeast-1c",
      cidr_block: "10.0.1.0/24"
    )
  end

  ##
  #=== インターネットゲートウェイ
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internet-gateway.html
  def internet_gateway
    Humidifier::EC2::InternetGateway.new
  end

  ##
  #=== VPCゲートウェイアタッチメント
  def vpc_gateway_attachment
    Humidifier::EC2::VPCGatewayAttachment.new(
      vpc_id: Humidifier.ref("VPC"),
      internet_gateway_id: Humidifier.ref("InternetGateway")
    )
  end

  ##
  #=== パブリックルートテーブル
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html
  def public_route_table
    Humidifier::EC2::RouteTable.new(
      vpc_id: Humidifier.ref("VPC")
    )
  end

  ##
  #=== パブリックルート
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html
  def public_route
    Humidifier::EC2::Route.new(
      route_table_id: Humidifier.ref("PublicRouteTable"),
      destination_cidr_block: "0.0.0.0/0",
      gateway_id: Humidifier.ref("InternetGateway")
    )
  end

  ##
  #=== サブネット1をルートテーブルに関連付け
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html
  def subnet1_route_table_association
    Humidifier::EC2::SubnetRouteTableAssociation.new(
      subnet_id: Humidifier.ref("Subnet1"),
      route_table_id: Humidifier.ref("PublicRouteTable")
    )
  end

  ##
  #=== サブネット2をルートテーブルに関連付け
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html
  def subnet2_route_table_association
    Humidifier::EC2::SubnetRouteTableAssociation.new(
      subnet_id: Humidifier.ref("Subnet2"),
      route_table_id: Humidifier.ref("PublicRouteTable")
    )
  end

  ##
  #=== サブネット2をルートテーブルに関連付け
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-route-table-assoc.html
  def public_network_acl
    Humidifier::EC2::NetworkAcl.new(
      vpc_id: Humidifier.ref("VPC")
    )
  end

  ##
  #=== ネットワークACLにエントリ(http)を作成します
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
  def inbound_http_public_network_acl_entry
    Humidifier::EC2::NetworkAclEntry.new(
      network_acl_id: Humidifier.ref("PublicNetworkAcl"),
      rule_number: 100,
      protocol: 6,
      rule_action: "allow",
      egress: false,
      cidr_block: "0.0.0.0/0",
      port_range: { From: 80, To: 80 }
    )
  end

  ##
  #=== ネットワークACLにエントリ(ssh)を作成します
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
  def inbound_ssh_public_network_acl_entry
    Humidifier::EC2::NetworkAclEntry.new(
      network_acl_id: Humidifier.ref("PublicNetworkAcl"),
      rule_number: 102,
      protocol: 6,
      rule_action: "allow",
      egress: false,
      cidr_block: "0.0.0.0/0",
      port_range: { From: 22, To: 22 },
    )
  end

  ##
  #=== ネットワークACLにエントリ(エフェメラルポート)を作成します
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
  def inbound_ephemeral_public_network_acl_entry
    Humidifier::EC2::NetworkAclEntry.new(
      network_acl_id: Humidifier.ref("PublicNetworkAcl"),
      rule_number: 103,
      protocol: 6,
      rule_action: "allow",
      egress: false,
      cidr_block: "0.0.0.0/0",
      port_range: { From: 1024, To: 65535 },
    )
  end

  ##
  #=== ネットワークACLにエントリ(アウトバウンド)を作成します
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html
  def outbound_public_network_acl_entry
    Humidifier::EC2::NetworkAclEntry.new(
      network_acl_id: Humidifier.ref("PublicNetworkAcl"),
      rule_number: 100,
      protocol: 6,
      rule_action: "allow",
      egress: true,
      cidr_block: "0.0.0.0/0",
      port_range: { From: 0, To: 65535 },
    )
  end

  ##
  #=== サブネット1をネットワーク ACL に関連付けます
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html
  def subnet1_network_acl_association
    Humidifier::EC2::SubnetNetworkAclAssociation.new(
      subnet_id: Humidifier.ref("Subnet1"),
      network_acl_id: Humidifier.ref("PublicNetworkAcl")
    )
  end

  ##
  #=== サブネット2をネットワーク ACL に関連付けます
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet-network-acl-assoc.html
  def subnet2_network_acl_association
    Humidifier::EC2::SubnetNetworkAclAssociation.new(
      subnet_id: Humidifier.ref("Subnet2"),
      network_acl_id: Humidifier.ref("PublicNetworkAcl")
    )
  end

  ##
  #=== VPC 用の DHCP オプションセット
  # @see https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-dhcp-options.html
  def dhcp_options
    Humidifier::EC2::DHCPOptions.new(
      domain_name: "ap-northeast-1.compute.internal",
      domain_name_servers: [ "AmazonProvidedDNS" ]
    )
  end
end

Rakefileの作成

作成したVPCクラスを実行するRakefileを作成します。ここでスタック名やパラメータを指定しています。ENVなどで環境変数からも値を取得できます。

require "rake"

stack_name = "sample-stack"
parameters = [
  { parameter_key: "VpcCidr", parameter_value: "10.0.0.0/16" }
]

namespace "VPC" do
  desc "VPCのデプロイ"
  task :deploy do
    require "./vpc"
    vpc = VPC.new(stack_name)
    vpc.stack.deploy_and_wait(parameters: parameters)
  end

  desc "VPCのチェンジセットの作成"
  task :create_change_set do
    require "./vpc"
    vpc = VPC.new(stack_name)
    vpc.stack.create_change_set(parameters: parameters)
  end

  desc "CloudFormationテンプレートの作成"
  task :template do
    require "./vpc"
    vpc = VPC.new(stack_name)
    puts vpc.stack.to_cf
  end
end

スクリプトの実行

VPCをデプロイする場合

rake VPC:deploy

スタックが作成されました CloudFormation_Management_Console.png

パラメータも指定されています CloudFormation_Management_Console.png

出力結果 CloudFormation_Management_Console.png

テンプレートの出力

rake VPC:template

チェンジセットの作成

rake VPC:create_change_set

チェンジセットが作成される CloudFormation_Management_Console.png

変更される内容を確認して実行 Change_Set_Detail.png

About

Humidifier Sample Script

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages