okochangの馬鹿でありがとう

ふらふら適当に世間を生きる日々でございます

CodePipeline、Jenkins、Elastic Beanstalkの連携を試してみた(失敗からの大成功!)

こんにちは、前回のエントリーでJenkinsにCodePipelineのプラグインをインストールしました。 今回はCodePipelineと連携するJenkinsプロジェクトを作成し、Management ConsoleでPipelineを作成してみたいと思います。

最終的な構成イメージ

最終的な構成図は以下のようになります。Jenkinsと連携させ、この記事で作成したElastic Beanstalkにデプロイしたいと思います。

f:id:okochang:20150720205541p:plain

JenkinsがPipelineと連携するためのIAMユーザーを作成

最初にJenkinsがCodePipelineと連携するためのIAMユーザーを作成し、権限を割り当てます。この部分はIAMユーザーではなくIAMロールを使うという方法もあります。

IAMユーザーの作成と、認証情報の取得

IAMのコンソールホーム画面左メニューからUsers、Create New Usersをクリックします。

f:id:okochang:20150720233923p:plain

作成するIAMユーザーの名前を指定してCreateし、認証情報をメモしておきます。

f:id:okochang:20150720234033p:plain

作成したIAMユーザーにCodePipelineと連携する権限を追加

IAMコンソール画面の左メニューからUsersを選択し、先ほど作成したユーザーを選択します。

f:id:okochang:20150720234047p:plain

PermissionsのManaged PolicyからAttach Policyをクリックします。

f:id:okochang:20150720234058p:plain

リストされているポリシーからAWSCodePipelineCustomActionAccessを選択してAttach Policyをクリックします。

f:id:okochang:20150720234108p:plain

Jenkinsプロジェクトを作成

次はJenkinsプロジェクトの作成です。前回作成したJenkinsトップページにアクセスし、新規ジョブ作成をクリックします。

f:id:okochang:20150718232228p:plain

ジョブ名に任意のジョブ名(MimawarigumiProject)を入力し、フリースタイル・プロジェクトのビルドを選択してOKをクリックします。

f:id:okochang:20150718232423p:plain

ソースコードの管理でAWS CodePipelineを選択、AWS Access KeyとAWS Secret Keyにメモした認証情報を入力してProviderに任意の名前(MimawarigumiProvider)を入力します。

f:id:okochang:20150718233531p:plain

ビルド・トリガでSCMをポーリングを選択し、スケジュールに* * * * *を入力します。Jenkins側からCodeDeployにビルドするかどうかを定期的にチェックするようです。

f:id:okochang:20150718233720p:plain

ビルド環境の設定で、The Ruby versionを2.2.2にし、テスト実行に必要なスクリプトを入力します。

f:id:okochang:20150718234005p:plain

今回入力したスクリプトは以下のようなものです。

#!/bin/bash
bundle config build.nokogiri --use-system-libraries
bundle install --path vendor/bundle
bundle exec rake db:setup
bundle exec rake db:migrate RAILS_ENV=test
bundle exec rspec spec

ビルド後の処理で、AWS CodePipeline Publisherを選択し、追加します。Locationは空欄のままで構いません。最後に保存をクリックしてプロジェクトを作成します。

f:id:okochang:20150718234422p:plain

CodePipelineを作成

CodePipelineのホーム画面からGet Startedをクリックします。

f:id:okochang:20150720152708p:plain

作成するPipelineに割り当てる名前を指定してNext Stepをクリックします。

f:id:okochang:20150720152722p:plain

Source ProviderでGitHubを選択して、Connectをクリックします。

f:id:okochang:20150720152850p:plain

RepositoryとBranchにソースとしたいリポジトリ名とブランチを入力し、Next Stepをクリックします。

f:id:okochang:20150720154451p:plain

Build ProviderでAdd Jenkinsをクリックします。
Provider name、Server URL、Project nameにJenkinsの情報を入力して、Next Stepをクリックします。Provider name(MimawarigumiProvider)とProject name(MimawarigumiProject)は先ほどJenkinsのプロジェクトを作成したときと同じ名前にして下さい。

f:id:okochang:20150720154334p:plain

Deployment ProviderではAWS Elastic Beanstalkを選択します。今回は以前構築したElastic Beannstalkの環境を選択してNext Stepをクリックします。

f:id:okochang:20150720155610p:plain

次にCodePipelineが使用するIAMロールの設定をします。今回は新規作成するのでCreate roleをクリックします。

f:id:okochang:20150720161038p:plain

Role Nameが自動的に入力されますので、そのままAllowをクリックします。

f:id:okochang:20150720234741p:plain

先ほど作成したロールが選択されていることを確認してNext Stepをクリックします。

f:id:okochang:20150720161113p:plain

最後に作成した内容を確認して、Create Pipelineをクリックします。

f:id:okochang:20150720161440p:plain

そうすると、さっそくPipelineで定義されたプロセスが実行されます。

f:id:okochang:20150720210455p:plain f:id:okochang:20150720212124p:plain

CodePipelineのBuildが成功するとJenkis側でもビルドが成功しています。

f:id:okochang:20150720212224p:plain

と、ここまでは良かったのですが、最終的にElastic Beanstalkのデプロイで失敗してしまいました。

f:id:okochang:20150720212512p:plain

CodePipelineとElastic BeanstalkのEventには以下のようなエラーメッセージが出ていました。
CodePipelineに割り当てているIAMロールの権限不足かなと思って確認してみたところ必要な権限は割り当ってるようでした。
ここに関してはまだ解決できていないので引き続き調査しないと。→解決方法を追記しました!

Service:AmazonElasticLoadBalancing, Message:User: arn:aws:sts::123456789012:assumed-role/AWS-CodePipeline-Service/1437394759838 is not authorized to perform: elasticloadbalancing:RegisterInstancesWithLoadBalancer on resource: arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/awseb-e-u-AWSEBLoa-Z20VI2NDPANA

ちなみに、CodeDeployを使ったパターンでは最後までしっかりと処理されました。

f:id:okochang:20150720222454p:plain

作成後は、GitHubに新しいバージョンをPushしたり、Release changeを実行するとPipelineが再実行されます。Pipelineを削除する場合は、編集画面のDeleteから消すことが出来ます。

7月25日追記

ブログを公開していて数日後、Twitterで以下のような情報を頂きました。

ツイートに記載されているリンクのForumで同じ問題が報告されておりまして、Pipeline作成ウィザードで作ったIAMロール(AWS-CodePipeline-Service)の権限を修正することで解決出来ます。@understeerさんからも解決方法を教えて頂きました、ありがとうございます! 具体的な修正手順は以下のようになります。

  1. IAMコンソール画面の左メニューからRolesを選択し、AWS-CodePipeline-Serviceをクリックします f:id:okochang:20150725011437p:plain
  2. InlinePoliciesにあるポリシーの編集画面に移ります f:id:okochang:20150725011548p:plain
  3. elasticloadbalancing:DescribeLoadBalancersの部分をelasticloadbalancing:*に変更してApply Policyをクリックします f:id:okochang:20150725011526p:plain

最終的には以下のようなポリシーになるはずです。

{
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::codepipeline*",
                "arn:aws:s3:::elasticbeanstalk*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "codedeploy:CreateDeployment",
                "codedeploy:GetApplicationRevision",
                "codedeploy:GetDeployment",
                "codedeploy:GetDeploymentConfig",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "elasticbeanstalk:CreateApplicationVersion",
                "elasticbeanstalk:DescribeApplicationVersions",
                "elasticbeanstalk:DescribeEnvironments",
                "elasticbeanstalk:DescribeEvents",
                "elasticbeanstalk:UpdateEnvironment",
                "autoscaling:DescribeAutoScalingGroups",
                "autoscaling:DescribeLaunchConfigurations",
                "autoscaling:DescribeScalingActivities",
                "autoscaling:ResumeProcesses",
                "autoscaling:SuspendProcesses",
                "cloudformation:GetTemplate",
                "cloudformation:DescribeStackResource",
                "cloudformation:DescribeStackResources",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStacks",
                "cloudformation:UpdateStack",
                "ec2:DescribeInstances",
                "ec2:DescribeImages",
                "ec2:DescribeAddresses",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeKeyPairs",
                "elasticloadbalancing:*",
                "rds:DescribeDBInstances",
                "rds:DescribeOrderableDBInstanceOptions",
                "sns:ListSubscriptionsByTopic"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:invokefunction",
                "lambda:listfunctions"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketPolicy",
                "s3:GetObjectAcl",
                "s3:PutObjectAcl",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::elasticbeanstalk*",
            "Effect": "Allow"
        }
    ],
    "Version": "2012-10-17"
}

編集後、改めてPipelineが実行されると以下のようにバッチリデプロイまで成功します!

f:id:okochang:20150725011934p:plain

感想

とてもシンプルではありますが、CodePipelineの作成までを追ってみました。とはいえ、このようなシンプルなものだとCodePipelineの強みが出づらいなというのが正直な感想です。 CIツールという意味では、JenkinsにもGitHubと連携するためのプラグインがあり、Jenkinsプロジェクトの設定でステージング環境やプロダクション環境へのデプロイまで自動化することが出来ます。また、JenkisではなくTravis CICircleCIといったSaaSを使うという手段もあります。
以下は作成したPipelineの編集画面なのですが、赤く囲まれたところに注目して下さい。

f:id:okochang:20150720223149p:plain

例えばBuildプロセスひとつでも、いくつかのものを順番に実行したり、同時に実行するといったことが出来るようになっています。Sourceについても複数のものを指定することが出来るようになっています。大きなプロジェクトを運用していたりすると、複数リポジトリを運用しつつビルドやデプロイの順番が決まっていたりしてリリースプロセスが複雑化する場合もあると思います。そういった複雑化した環境で継続的インテグレーションをする場合にCodeDeployは力を発揮してくれそうな気がしました(今回は紹介していませんが、負荷テストなどを組み込む事も可能です)。
Travis CI、CircleCI、 OpsWorksなどもっと色々なサービスにも対応して欲しいですね。

参考

Amazon LinuxにCodePipelineのJenkinsプラグインをセットアップする

こんにちは、前回のブログでCentOS7にJenkinsとCodePipelineのプラグインをインストールしましたが、実際にテストをしてみると、エラーが発生してしまって連携が出来ませんでした。このエラーはaws-codepipeline-plugin-for-jenkinsのIssueでも報告されておりますが、Amazon Linuxを使って環境を構築してみたところ最新のJenkinsでも正しい動作をしました。aws-codepipeline-plugin-for-jenkinsの新しいバージョンがリリースされ、現在は問題なく動作するようになっています。
というわけで、今回はAmazon Linuxを使ったJenkinsの構築手順をまとめておきたいと思います。

f:id:okochang:20150714153507j:plain

使用したAMI

amzn-ami-hvm-2015.03.0.x86_64-gp2 (ami-cbf90ecb)

必要なパッケージのインストール

Raila環境の構築に必要なパッケージをインストールします。

$ sudo yum -y update
$ sudo yum -y install git emacs gcc zlib-devel libxml2-devel libxslt-devel readline-devel openssl-devel gcc-c++ $ curl-devel ruby-devel git postgresql postgresql-server postgresql-libs postgresql-contrib postgresql-devel
$ sudo yum -y install nodejs --enablerepo=epel

PostgreSQLのセットアップ

サンプルプロジェクトではPostgreSQLを使っていますので初期設定をします。

$ sudo service postgresql initdb --encoding=UTF-8 --locale=ja_JP.UTF-8
$ sudo service postgresql start
$ sudo chkconfig postgresql on
$ sudo su - postgres
$ createuser -a -d -P mimawarigumi
$ exit

Jenkinsのセットアップ

Jenkinsのインストールや自動起動の設定をします。

$ sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
$ sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
$ sudo yum install jenkins
$ sudo service jenkins start
$ sudo chkconfig jenkins on

rbenv、ruby-build、Rubyのセットアップ

サンプル用アプリのテストが出来るようにrbenv、Rubyをインストールします。 /usr/loca以下にrbenvをインストールし、jenkinsユーザーが実行出来るようにセットアップします。

$ sudo groupadd ruby
$ sudo  gpasswd -a jenkins ruby

rbenvをインストールし、rubyグループが実行可能なように権限設定をします。

$ cd /usr/local
$ sudo  git clone git://github.com/sstephenson/rbenv.git rbenv
$ sudo  chgrp -R ruby rbenv
$ sudo chmod -R g+rwxXs rbenv

ruby-buildをインストールし、先ほどと同じくrubyグループに権限を割り当てます。

$ sudo mkdir /usr/local/rbenv/plugins
$ cd /usr/local/rbenv/plugins
$ sudo git clone git://github.com/sstephenson/ruby-build.git
$ sudo chgrp -R ruby ruby-build
$ sudo chmod -R g+rwxs ruby-build

rootユーザーの環境変数を設定し、Rubyのインストールが出来るかテストします。

$ sudo -i
# echo 'export RBENV_ROOT=/usr/local/rbenv' >> .bash_profile
# echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> .bash_profile
# echo 'eval "$(rbenv init -)"' >> .bash_profile
# exec $SHELL -l
# rbenv install 2.2.2
# rbenv rehash
# rbenv global 2.2.2
# ruby -v

Jenkinsプラグインのインストール

ここからの手順は前回の手順と同じです、そちらをご覧ください。現場からは以上です。

CentOSにJenkinsとAWS CodePipelineプラグインをセットアップする

前回までの記事でサンプル用RailsプロジェクトをElastic Beanstalkにデプロイ出来ました。
今回は、新しくCentOS7にサンプル用Railsプロジェクトのテスト環境とJenkinsをセットアップし、AWS CodePipelineと連携するために必要なJenkinsプラグインをインストールするまでまとめたいと思います。
最初のうちはサンプル用Railsプロジェクトを作った時の構築手順とほとんど同じようになります。
※その後、この環境でAWS CodePipelineと連携しても失敗してしまうことが分かりました、別記事を用意しているのでそちらの手順に沿って環境構築することをおすすめします。aws-codepipeline-plugin-for-jenkinsの新しいバージョンがリリースされ、正しく動作することを確認しました。

f:id:okochang:20150714153507j:plain

使用したAMI

CentOS 7 x86_64 (2014_09_29) EBS HVM-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-d2a117ba.2 (ami-89634988)

aws.amazon.com

基本設定

タイムゾーンなどの基本的な設定をしておきます。それぞれお好みで調整して下さい。

$ sudo timedatectl set-timezone Asia/Tokyo
$ sudo sed -i -e "s/^ - update_hostname/# - update_hostname/g" /etc/cloud/cloud.cfg
$ sudo sh -c "echo 'jenkins.okochang.com' > /etc/hostname"
$ sudo reboot

SELinuxごめんなさい

$ sudo sed -i -e "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
$ sudo reboot

必要なパッケージのインストール

Railの環境がテストするために必要なパッケージと、AWS CLIをインストールします。

$ sudo yum update -y
$ sudo yum install -y git emacs gcc make zlib-devel libxml2-devel libxslt-devel readline-devel openssl-devel gcc-c++ curl-devel ruby-devel  vim wget epel-release bzip2 bind-utils nodejs git postgresql postgresql-server postgresql-libs postgresql-contrib postgresql-devel
$ sudo reboot
$ sudo easy_install pip
$ sudo pip install awscli

PostgreSQLのセットアップ

サンプル用のRailsプロジェクトではPostgreSQLを使っていますので、初期設定をしておきます。

$ sudo su - postgres
$ initdb --encoding=UTF-8 --locale=ja_JP.UTF-8
$ exit
$ sudo systemctl start postgresql
$ sudo systemctl enable postgresql
$ sudo su - postgres
$ createuser -a -d -P mimawarigumi
$ exit

Jenkinsのセットアップ

ここは今回の手順の主役の部分です。Jenkinsをインストールし、自動起動の設定をします。

$ sudo yum install java-1.8.0-openjdk
$ sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
$ sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
$ sudo yum install jenkins
$ sudo systemctl start jenkins
$ sudo systemctl enable jenkins

rbenv、ruby-build、Rubyのセットアップ

サンプル用Railsプロジェクトのテストが出来るようにrbevnやRubyなどをインストールします。
すでにJenkinsのセットアップは終わりましたが、jenkinsユーザーはログイン出来ないようになっております。そのため、/usr/local以下にrbenvをインストールしてjenkinsユーザーが実行できるように権限設定をします。

$ sudo groupadd ruby
$ sudo  gpasswd -a jenkins ruby

rbenvをインストールし、rubyグループが実行可能なように権限設定をします。

$ cd /usr/local
$ sudo  git clone git://github.com/sstephenson/rbenv.git rbenv
$ sudo  chgrp -R ruby rbenv
$ sudo chmod -R g+rwxXs rbenv

ruby-buildをインストールし、先ほどと同じくrubyグループに権限を割り当てます。

$ sudo mkdir /usr/local/rbenv/plugins
$ cd /usr/local/rbenv/plugins
$ sudo git clone git://github.com/sstephenson/ruby-build.git
$ sudo chgrp -R ruby ruby-build
$ sudo chmod -R g+rwxs ruby-build

rootユーザーの環境変数を設定し、Rubyのインストールが出来るかテストします。

$ sudo -i
# echo 'export RBENV_ROOT=/usr/local/rbenv' >> .bash_profile
# echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> .bash_profile
# echo 'eval "$(rbenv init -)"' >> .bash_profile
# exec $SHELL -l
# rbenv install 2.2.2
# rbenv rehash
# rbenv global 2.2.2
# ruby -v

Jenkinsのプラグインのインストール

ここまでのセットアップが終わったら、http://サーバーのIPアドレス:8080/にアクセスします。
Jenkinsのダッシュボードの左メニューにある「Jenkinsの管理」から「プラグインの管理」を選択します。「利用可能」タブでテストに必要な以下のプラグインをインストールします。

f:id:okochang:20150717014010p:plain

  • Hudson Ruby Plugin

f:id:okochang:20150717014700p:plain

  • Rake plugin

f:id:okochang:20150717014202p:plain

  • rbenv plugin

f:id:okochang:20150717014221p:plain

AWS CodePipelineプラグインのインストール

いよいよCodePipelineのプラグインをインストールしていきます。
まず最初にこちらGitHubリポジトリからZIPファイルをダウンロードし、解凍します。
次に「プラグインの管理」で「高度な設定」タブを開きます。「プラグインのアップロード」から先ほど解凍したaws-codepipeline-plugin-for-jenkins/dist以下にあるhpiファイルをアップロードしてインストールして下さい。

f:id:okochang:20150717014858p:plain

これでプラグインのインストールは完了です。次回は実際にJenkinsのジョブを作って、CodePipelineと連携するところまでいきたいと思います。

RailsアプリケーションをElastic Beanstalkにデプロイする

前回の記事で簡単なRailsアプリケーションのサンプルを作成しました。
今回はこのサンプルをElastic Beanstalkにデプロイしてみたいと思います。デプロイに必要となるコマンドラインツールなど、環境構築手順は前回の記事に書いてありますので、そちらを参照して下さい。

f:id:okochang:20150714153507j:plain

EB CLIの設定

作成したプロジェクトリポジトリでeb initコマンドを実行して環境設定を行います。

$ cd ~/repos/mimawarigumi
$ eb init

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-southeast-1 : Asia Pacific (Singapore)
7) ap-southeast-2 : Asia Pacific (Sydney)
8) ap-northeast-1 : Asia Pacific (Tokyo)
9) sa-east-1 : South America (Sao Paulo)
(default is 3): 1

Enter Application Name
(default is "mimawarigumi"): 
Application mimawarigumi has been created.

It appears you are using Ruby. Is this correct?
(y/n): y

Select a platform version.
1) Ruby 2.2 (Puma)
2) Ruby 2.2 (Passenger Standalone)
3) Ruby 2.1 (Puma)
4) Ruby 2.1 (Passenger Standalone)
5) Ruby 2.0 (Puma)
6) Ruby 2.0 (Passenger Standalone)
7) Ruby 1.9.3
(default is 1): 1
Do you want to set up SSH for your instances?
(y/n): n

環境設定が完了すると、以下のように.gitignoreが更新されており、.elasticbeanstalk/configが作成されています。
変更点は忘れずにコミットしておいて下さい。

$ git diff
diff --git a/.gitignore b/.gitignore
index cd84d08..a90ebee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,8 @@
 
 # Ignore dotenv
 /.env
+
+# Elastic Beanstalk Files
+.elasticbeanstalk/*
+!.elasticbeanstalk/*.cfg.yml
+!.elasticbeanstalk/*.global.yml
$ ls .elasticbeanstalk/
config.yml
$ git add .gitignore
$ git commit -m "Elastic Beanstalkの設定ファイルを除外するようにした"

AWS Management Consoleでは、以下のようにApplicationが作成されています。

f:id:okochang:20150714215024p:plain

環境作成とアプリケーションのデプロイ

環境作成とデプロイをしていきます。eb createコマンドでタイムアウトしてしまう場合は--timeoutオプションを使ってみて下さい(タイムアウトしても環境作成とデプロイが失敗するわけではありません)。

$ eb create --database --database.engine postgres
Enter Environment Name
(default is mimawarigumi-dev): mimawarigumi-env
Enter DNS CNAME prefix
(default is mimawarigumi-env): 

Enter an RDS DB username (default is "ebroot"): mimawarigumi
Enter an RDS DB master password: 
Retype password to confirm: 
WARNING: Deploying a previously deployed commit.
Environment details for: mimawarigumi-env
  Application name: mimawarigumi
  Region: us-east-1
  Deployed Version: a265
  Environment ID: e-zhkdupp9c6
  Platform: 64bit Amazon Linux 2015.03 v1.4.3 running Ruby 2.2 (Puma)
  Tier: WebServer-Standard
  CNAME: mimawarigumi-env.elasticbeanstalk.com
  Updated: 2015-07-15 00:11:00.587000+00:00
Printing Status:
INFO: createEnvironment is starting.

(略)

---
$ eb setenv SECRET_KEY_BASE=`bundle exec rake secret`

Management Consoleでは以下のようになっています。

f:id:okochang:20150715095204p:plain

動作確認

Management Consoleに書かれているリンクにアクセスするとWebページが表示されます。

f:id:okochang:20150715095336p:plain

環境の削除

環境を削除する場合は以下のコマンドを実行します。

$ eb terminate

あとがき

前回作成したRailsアプリをElastic Beanstalkにデプロイしました。
その他の設定をしたい場合は別途ebコマンドを使ってやって下さい。これをCodePipelineとかと連携出来るのかな?

CentOS7にRailsプロジェクトを作成するまで

たまに簡単なAWSサービスの動作確認とかで、簡単なRailsアプリケーションの開発環境を作るまでの手順がブログにまとまってると(個人的に)便利だなと思うことがあるので、今回はそんな環境を構築する手順を書きます。
パッケージは執筆時点でのバージョンなので、適宜アップデートして下さい。

f:id:okochang:20150714153507j:plain

使用したAMI

CentOS 7 x86_64 (2014_09_29) EBS HVM-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-d2a117ba.2 (ami-89634988)
※起動時にIAMロールもセットしています。

aws.amazon.com

基本設定

まず最初に自分自身のユーザーを作成や時間の設定をします。EC2インスタンス起動直後に接続するユーザーはcentosです。

$ sudo -i
# useradd okochang
# passwd okochang
# visudo -f /etc/sudoers.d/okochang
# sudo cat /etc/sudoers.d/okochang
# User rules for okochang
okochang ALL=(ALL) NOPASSWD:ALL
# timedatectl set-timezone Asia/Tokyo
# sed -i -e "s/^ - update_hostname/# - update_hostname/g" /etc/cloud/cloud.cfg
# echo 'rails.okochang.com' > /etc/hostname

作成したユーザーに手元の環境から接続するためのSSH公開鍵をセットしたり、今後使うためにSSHキーペアを作成します。

$ su - okochang
$ mkdir -m 700 .ssh
$ echo 'ssh-rsa your-ssh-key-tesxt-data' .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
$ ssh-keygen -C rails.okochang.com
$ sudo reboot

SELinuxごめんなさい

$ sudo sed -i -e "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
$ sudo reboot

必要なパッケージのインストール

Railsの環境を構築するために必要なパッケージのインストールと、AWSコマンドラインツールをインストールしておきます。

$ sudo yum update -y
$ sudo yum install -y git emacs gcc make zlib-devel libxml2-devel libxslt-devel readline-devel openssl-devel gcc-c++ curl-devel ruby-devel  vim wget epel-release bzip2 bind-utils nodejs
$ sudo reboot
$ sudo easy_install pip
$ sudo pip install awscli
$ sudo pip install awsebcli

Git

ソースコードの管理にGitを使うので、このへんも設定しておきます。

$ git config --global user.email "okochang@example.com"
$ git config --global user.name "okochang"

Ruby

rbenvを使って、現時点最新の安定版であるRuby 2.2.2をインストールします。

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ cd .rbenv/plugins/ruby-build/
$ sudo ./install.sh
$ cd
$ echo 'export PATH=$HOME/.rbenv/bin:$PATH' >> .bashrc
$ echo 'eval "$(rbenv init -)"' >> .bashrc
$ exec $SHELL -l
$ rbenv install --list
$ rbenv install 2.2.2
$ rbenv global 2.2.2

gems

サンプルプロジェクトではBundlerを使ってgemパッケージを管理しますので、インストールします。

$ gem install rbenv-rehash
$ rbenv rehash
$ gem install bundler

PostgresQL

サンプルプロジェクトでデータベースは使う予定はありませんが、PostgreSQLを使えるようにしてます。プロジェクト名をmimawarigumiにする予定なので、ユーザー名に指定しています。

$ sudo yum install -y postgresql postgresql-server postgresql-libs postgresql-contrib postgresql-devel
$ sudo su - postgres
$ initdb --encoding=UTF-8 --locale=ja_JP.UTF-8
$ exit
$ sudo systemctl start postgresql
$ sudo systemctl enable postgresql
$ sudo su - postgres
$ createuser -a -d -P mimawarigumi
$ exit

サンプル用のRailsプロジェクト作成

プロジェクト用のディレクトリを作成して、railsコマンドでプロジェクトを初期化します。
初期化したら、現時点の内容をコミットします。以降の作業は適宜コミットしていくものとします。

$ mkdir -p repos/mimawarigumi
$ cd repos/mimawarigumi
$ bundle init
$ sed -i -e 's/# gem "rails"/gem "rails"/g' Gemfile
$ bundle config build.nokogiri --use-system-libraries
$ bundle install --path vendor/bundle
$ bundle exec rails new . -d postgresql --skip-test-unit
$ bundle exec rake db:migrate
cat << EOF >> .gitignore

# Ignore ruby version configuration.
/.ruby-version

# Ingonre bundled contents.
/vendor/bundle

# Ignore sass cache
.sass-cache

# Ignore dotenv
/.env
EOF
$ git add .
$ git commit -m "initial commit"

静的ページの作成

静的ページの作成をしていきます。最初にGemfileにrspecとcapybaraを追加してインストールしておきました。具体的な変更内容はこちらを見て下さい。

$ vim Gemfile
$ bundle install --path vendor/bundle
$ bundle exec rails generate controller StaticPages home --no-test-framework
$ bundle exec rails generate rspec:install
$ bundle exec rails generate integration_test static_pages
$ vim app/views/static_pages/home.html.erb 
$ vim spec/rails_helper.rb
$ vim app/views/static_pages/home.html.erb 
$ vim config/routes.rb
$ vim config/database.yml

あとがき

簡単なRailsアプリのサンプルが出来ました。
普段GitHubを使っていることもありCodeDeployとかCodePipelineとかもGitHub連携で試してみたいのです。そういう時にこういうサンプル用のアプリを持っておくと便利かなと。

AWS CodeCommitのリポジトリにSSHでアクセスする

前回のブログAWS CodeCommitを触ってみました。その時作成しGitたリポジトリへはHTTPSを使ってアクセスしましたが、今回はSSHを使ったやり方をまとめます。
ドキュメントにはリポジトリのサイズが大きい場合はHTTPSでなくSSHの使用を検討しましょうって書いてますね。

SSHキーの操作をするIAMポリシーを作成&割り当てる

AWS Management ConsoleでIAMにアクセスし、左メニューからPoliciesを選択します。

f:id:okochang:20150713093955p:plain

ポリシーテンプレートの中からIAMUserSSHKeysを選択し、Attachを選択します。

f:id:okochang:20150713012822p:plain

アタッチしたいユーザーをチェックして、Attach Policyをクリックします(IAMユーザーは事前に作成しておいて下さい)。

f:id:okochang:20150713012919p:plain

IAMユーザーにSSH公開鍵を割り当てる

IAMユーザーにSSH公開鍵を割り当てます。左メニューからUsersを選択します。

f:id:okochang:20150713094125p:plain

割り当てたいユーザーをクリックします。

f:id:okochang:20150713013045p:plain

設定画面のSSH keys for AWS CodeCommitにあるUpload SSH Keyをクリックします。

f:id:okochang:20150713013149p:plain

使いたいSSH公開鍵のテキストデータをペーストしてUpload SSH Keyをクリックします。
SSHの公開鍵と秘密鍵のペアは事前に作成しておいて下さい。

f:id:okochang:20150713013227p:plain

ローカルコンピュータのSSH設定

CodeCommitにSSHアクセスする場合の設定をします。SSH公開鍵をアップロードするとSSH Key IDが付与されます。

f:id:okochang:20150713013339p:plain

CodeCommitのホスト名、付与されたSSH Key ID、秘密鍵のパス、を以下のように設定します。

$ vim .ssh/config
Host git-codecommit.*.amazonaws.com
    User APKAI2EI6HC4N47QBQ3Q
    IdentityFile ~/.ssh/your-ssh-private-key.pem

設定ファイルの権限設定を忘れずにしておいてください。

$ chmod 600 .ssh/config

動作確認

以下のようにSSHで前回のGitリポジトリを手元にCloneできました。

$ git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/SampleRepository

必要に応じて、リモートリポジトリの設定を追加します。

$ git remote add  ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/SampleRepository

感想

普段はGitリポジトリへの接続はSSHを使っているので、個人的にはこっちのほうがしっくりきます。
OpsWorksで起動するEC2インスタンスSSH公開鍵をセットしたり出来ますが、その時の手順とはまったく別物という感じですね。

参考

docs.aws.amazon.com

AWS CodeCommitを触ってみた

久しぶりのブログとなってしまいました。
AWS Summits 2015 | New YorkAWSからいくつかの新サービスがリリースされたようです。新しいサービスはひと通り触ってみたいなと思っておりまして、まずはお手軽に始められそうなAWS CodeCommitから手を付けてみましたのでログを残しておきます。
CodeCommitは、2014年のAWS re:Inventで発表されてから何となくこんなサービスだろうとイメージはしていたものの、理解するには触ってみるのが一番です。

CodeCommitにリポジトリを作成する

AWS Management Consoleにアクセスし、CodeCommitでリポジトリを作成します。
以下のように名前などを指定するだけです。

f:id:okochang:20150712223818p:plain

f:id:okochang:20150712223832p:plain

f:id:okochang:20150712232906p:plain

AWS CLIのバージョンアップ

以下のように手元の環境のAWS CLIをバージョンアップします。特に難しくはありません。

$ sudo pip install --upgrade awscli

AWS CLIの設定

すでに設定済の方はこのステップは必要ありません。認証情報などを以下のコマンドでセットします。

$ aws configure 

gitの設定

次にgitの設定をします。
以下はaws configureコマンドで認証情報のdefaultを設定している場合の例ですが、--profileオプションを使うことも出来ます。
また、特定のディレクトリ以下のみに指定する場合は--localオプションを使用し、gitのデフォルト設定にする場合は--globalオプションを使用して下さい。

$ cd development-repo/
$ git config --local credential.helper '!aws codecommit credential-helper $@'
$ git config --local credential.UseHttpPath true

CodeCommitをGitのリポジトリとして登録する

CodeCommitのダッシュボードからリポジトリを選択します。

f:id:okochang:20150712232951p:plain

リポジトリの詳細画面からHTTPSのアクセス先をコピーしておきます。

f:id:okochang:20150713000134p:plain

以下のようにリモートリポジトリを追加してPushします。

$ git remote add codecommit https://git-codecommit.us-east-1.amazonaws.com/v1/repos/SampleRepository
$ git push codecommit master

感想

何となくGitHubみたいにIssue管理やPRの作成なんかが出来るのかなと予想していましたけど、今時点ではそういった機能はなさそうです。
単純にリモートのGitリポジトリを手軽にホストしてくれるサービスといった感じでしょうか。利用料金はそんなに高くは感じませんでしたので、個人のプライベートリポジトリとしても使えるかも。
他のサービスとの連携で力を発揮するのかなと感じました。

参考

aws.typepad.com