LoginSignup
11
11

More than 5 years have passed since last update.

CloudFormationをCircleCIでCIする

Last updated at Posted at 2016-07-19

cloudpack大阪の佐々木です。

またもCircleCIです。
今度はCloudFormationをテストをCircleCIでやってみます。
テストはawspecを使います。

awspec

設定

ソースコードはこちらに。
https://github.com/taishin/cfn-ci

CloudFormation

template.cform
VPC上にEC2を1台たてているだけです。
CloudFormationで作成されたリソース(セキュリティグループ等)は、名前にランダムな文字列が付与されていたり、テストコードに代入しにくいので、Tagで名前を設定しています。

awspecテストコード

  • EC2

EC2はImageID、InstanceType、パブリックIPアドレスをもっていること、
適用されているセキュリティグループ、VPC等の確認をしています。
####で囲まれている部分はCircleCIの変数になるので、circle.ymlで書き換えるようにしています。(後述)

ec2_spec.rb-template
require 'spec_helper'
describe ec2('####INSTANCEID####') do
  it { should exist }
  it { should be_running }
  its(:image_id) { should eq '####IMAGEID####' }
  its(:instance_type) { should eq '####INSTANCETYPE####' }
  its(:public_ip_address) { should match "^\\d{1,3}\.\\d{1,3}\.\\d{1,3}\.\\d{1,3}$" }
  its(:key_name) { should eq '####KEYNAME####' }
  it { should have_security_group('CFn-CI-SG-HTTP') }
  it { should have_security_group('CFn-CI-SG-Base') }
  it { should belong_to_vpc('CFn-CI-VPC') }
  it { should belong_to_subnet('CFn-CI-Subnet1A') }
end
  • VPC

VPCはCIDRのIPアドレス、ルーティングテーブルの確認をしています。

vpc_spec.rb
require 'spec_helper'

describe vpc('CFn-CI-VPC') do
  it { should exist }
  it { should be_available }
  its(:cidr_block) { should eq '10.0.0.0/16' }
  it { should have_route_table('CFn-CI-PubRT') }
end

describe subnet('CFn-CI-Subnet1A') do
  it { should exist }
  it { should be_available }
  it { should belong_to_vpc('CFn-CI-VPC') }
  its(:cidr_block) { should eq '10.0.1.0/24' }
end

describe subnet('CFn-CI-Subnet1C') do
  it { should exist }
  it { should be_available }
  it { should belong_to_vpc('CFn-CI-VPC') }
  its(:cidr_block) { should eq '10.0.2.0/24' }
end

describe route_table('CFn-CI-PubRT') do
  it { should exist }
  it { should belong_to_vpc('CFn-CI-VPC') }
  it { should have_route('10.0.0.0/16').target(gateway: 'local') }
  it { should have_route('0.0.0.0/0').target(gateway: 'CFn-CI-IGW') }
  it { should have_subnet('CFn-CI-Subnet1C') }
  it { should have_subnet('CFn-CI-Subnet1A') }
end
  • SecurityGroup

セキュリティグループはルールの確認です。

sg_spec.rb
require 'spec_helper'

describe security_group('CFn-CI-SG-Base') do
  it { should exist }
  its(:inbound) { should be_opened(22).protocol('tcp').for('0.0.0.0/0') }
  its(:outbound) { should be_opened }
  its(:inbound_rule_count) { should eq 1 }
  its(:outbound_rule_count) { should eq 1 }
  its(:inbound_permissions_count) { should eq 1 }
  its(:outbound_permissions_count) { should eq 1 }
  it { should belong_to_vpc('CFn-CI-VPC') }
end

describe security_group('CFn-CI-SG-HTTP') do
  it { should exist }
  its(:inbound) { should be_opened(80).protocol('tcp').for('0.0.0.0/0') }
  its(:outbound) { should be_opened }
  its(:inbound_rule_count) { should eq 1 }
  its(:outbound_rule_count) { should eq 1 }
  its(:inbound_permissions_count) { should eq 1 }
  its(:outbound_permissions_count) { should eq 1 }
  it { should belong_to_vpc('CFn-CI-VPC') }
end

circle.yml

circle.ymlではCloudFormationを実行し、EC2のInstanceIDを取得します。
SSH Key、インスタンスタイプ、AMI IDは変数で変更できるようにしているので、CloudFormation起動後、ec2_spec.rb-templateをsedで変更し、ec2_spec.rbを生成しています。

circle.yml
machine:
  timezone: Asia/Tokyo
  ruby:
    version:
      2.1.2
  environment:
    AWS_AMI_ID: ami-6154bb00
    AWS_INSTANCE_TYPE: t2.micro
    AWS_CF_STACK_NAME: cfn-ci

dependencies:
  pre:

test:
  pre:
    - aws cloudformation create-stack --stack-name ${AWS_CF_STACK_NAME} --template-body file://template.cform --parameters ParameterKey=KeyName,ParameterValue=$AWS_KEY_NAME ParameterKey=ImageId,ParameterValue=$AWS_AMI_ID ParameterKey=InstanceType,ParameterValue=$AWS_INSTANCE_TYPE
    - aws cloudformation wait stack-create-complete --stack-name ${AWS_CF_STACK_NAME}
    - aws cloudformation describe-stacks --stack-name ${AWS_CF_STACK_NAME} | jq -r '.Stacks[].Outputs[] | select(.OutputKey == "InstanceId") | .OutputValue' > /tmp/instanceid.txt
    - sed -e "s/####INSTANCEID####/`cat /tmp/instanceid.txt`/g" -e "s/####KEYNAME####/$AWS_KEY_NAME/g" -e "s/####IMAGEID####/$AWS_AMI_ID/g" -e "s/####INSTANCETYPE####/$AWS_INSTANCE_TYPE/g" spec/ec2_spec.rb-template > spec/ec2_spec.rb

  override:
    - bundle exec rake spec
  post:
    - aws cloudformation delete-stack --stack-name ${AWS_CF_STACK_NAME}

CircleCI

CircleCIの画面上の設定は、
http://qiita.com/taishin/items/89b42106582a2aa5495b
と同じく、

  • AWS Permissions
    • AccessKey
    • SecrectAccesskey
  • Environment Variables
    • AWS_DEFAULT_REGION
    • AWS_KEY_NAME

を設定します。

実行

Buildさせるとこんな感じでテストして、終わればCloudFormationを削除してくれます。

Kobito.WEGY7o.png

11
11
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
11
11