25
22

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 5 years have passed since last update.

CFn → Ansible → ServerspecをCircleCIでCIする

Last updated at Posted at 2016-05-19

概要

CircleCIを使ってインフラのCIをやってみました。
Docker使う例が多いですが、ここはCloudformationでEC2を起動させます。
やることは下記です。

  1. CloudformationでEC2インスタンスを起動する
  2. Ausibleでデプロイ
  3. Serverspecでテスト

コード

Githubにアップしたコードは、ここにあります。
https://github.com/taishin/ec2-ci

主なものを説明します。

cloudformation.json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Parameters" : {
    "AmiId" : {
      "Description" : "AMI ID",
      "Type" : "String"
    },
    "InstanceType" : {
      "Description" : "Instance Type",
      "Type" : "String"
    },
    "KeyName" : {
      "Description" : "Amazon EC2 Key Pair",
      "Type" : "AWS::EC2::KeyPair::KeyName"
    }
  },  
  "Resources": {
    "SSHGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable SSH access via port 22",
        "SecurityGroupIngress": [{
          "IpProtocol" : "tcp",
          "CidrIp" : "0.0.0.0/0",
          "FromPort" : "22", "ToPort" : "22"
        }]
      }
    },
    "TestServer" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "ImageId" : { "Ref" : "AmiId" },
        "InstanceType" : { "Ref" : "InstanceType" },
        "KeyName": { "Ref": "KeyName" },
        "SecurityGroupIds" : [
          { "Ref" : "SSHGroup" }
        ]
      }
    },
    "TestServerEip": {
      "Type": "AWS::EC2::EIP",
      "Properties": {
        "InstanceId": { "Ref": "TestServer" }
      }
    }
  },
  "Outputs" : {
    "PublicIP" : {
      "Description" : "Public IP Address",
      "Value" : { "Ref" : "TestServerEip" }
    }
  }
}

まず、Cloudformationですが、SecurityGroupを作って、EC2を起動させています。
CircleCIからSSHでアクセスするために、EIPをOutputに出力し、参照できるようにしています。
AMIとInstanceType、SSHキーは変更可能なように、パラメーターで定義しています。

circle.yml
machine:
  timezone: Asia/Tokyo
  ruby:
    version:
      2.1.2
  environment:
    AWS_AMI_ID: ami-29160d47
    AWS_INSTANCE_TYPE: t2.micro
    AWS_CF_STACK_NAME: ci-test
    SSH_USER: ec2-user

dependencies:
  pre:
    - sudo pip install ansible

test:
  pre:
    - aws cloudformation create-stack --stack-name $AWS_CF_STACK_NAME --template-body file://cloudformation.json --parameters ParameterKey=KeyName,ParameterValue=$AWS_KEY_NAME ParameterKey=AmiId,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[].OutputValue' > /tmp/publicip.txt
    - echo "`cat /tmp/publicip.txt` testserver" >> /tmp/hosts.txt
    - cp /etc/hosts .
    - sudo bash -c "cat hosts /tmp/hosts.txt | tee /etc/hosts"
    - echo "Host testserver" >> ~/.ssh/config
    - echo "User $SSH_USER" >> ~/.ssh/config
    - ssh -t $SSH_USER@testserver sudo yum update -y
    - ssh -t $SSH_USER@testserver sudo yum install epel-release -y
  override:
    - ansible-playbook -i ansible/hosts ansible/nginx.yml
    - bundle exec rake spec:testserver
  post:
    - aws cloudformation delete-stack --stack-name $AWS_CF_STACK_NAME

CircleCIの設定ファイルですが、environmentでAMIとInstanceTypeを指定しています。
別のAMI、InstanceTypeを使用する場合はここを編集します。
SSHログインするユーザー名も外出しにしているので、OSによって変更します。
preのところでは、testserverという名前でアクセスできるようにhostsやsshconfigを編集しています。

ansible、serverspecの内容は、nginxをインストールして、テストしているだけなので、省略します。

CircleCI

Add ProjectsからGithubのリポジトリを選択し、Build Projectを押します。

スクリーンショット 2016-05-19 22.16.51.png

一旦、上部のcancel buildを押して、Buildを中止し、Project Settingsを押します。

スクリーンショット 2016-05-19 22.19.25.png

AWS Permissionsを押し、AccessKey、SecrectAccesskeyを入力します。

スクリーンショット 2016-05-19 22.34.20.png

Environment Variablesをクリックし、
AWS_DEFAULT_REGION(リージョン名)、AWS_KEY_NAME(SSHキーの名前)を追加します。

スクリーンショット 2016-05-19 22.36.06.png

Buildの画面に戻り、Rebuildをクリックすると、Buildが始まります。

スクリーンショット 2016-05-19 22.39.15.png

成功するとSuccessの画面になります。

スクリーンショット 2016-05-19 22.41.12.png

コードを修正し、GithubにPushすると、自動的にBuildが始まります。

まとめ

CircleCIを使うことで、CloudFormationによるAWS環境、Ansibleによるデプロイ、Serverspecによるテストまで、自動的に行う環境ができました。
ただ、Cloudformationは完了まで結構時間がかかります。(circle.ymlにsleep 120を入れいています。)
CFnの完了まで待ってくれる、aws cloudformation waitというコマンドを教えてもらいましたので、変更しました。
今回はEC2の起動だけですが、内容にもってはもっと時間を長くする必要があると思います。

25
22
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
25
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?