single command deployのための gradle-aws-plugin講座

64
Single Command Deployのための gradle-aws-plugin講座 ~自動ビルド厨はここまで大きくなりました~ 2015-09-26 クラスメソッド株式会社 都元ダイスケ #seasarcon

Upload: -

Post on 14-Apr-2017

4.029 views

Category:

Technology


9 download

TRANSCRIPT

Single Command Deployのためのgradle-aws-plugin講座

~自動ビルド厨はここまで大きくなりました~

2015-09-26 クラスメソッド株式会社

都元ダイスケ

#seasarcon

自己紹介✦ よく訓練されたアップル信者、都元です。 ✦ Java屋出身のAWS屋 ✦ Java歴約10年?(since 2006) ✦ AWS歴約4年(since 2011夏) ✦ SSHしたら負けだと思っている。 ✦ Twitter @daisuke_m ✦ Seasar2からSpringへ

2009-03-14 Seasar Conference 2009 White

2008-09-06 Seasar Conference 2008 Autumn

2009-06-13 Seasar Conference 2009 Spring

Do you know?

✦ DBの進化的設計を実現する開発プロセス ✦ 要するにRailsのmigrationのような ✦ 現在のJavaでいうFlywayのような ✦ EclipseプラグインによるER図エディタ

2006-20Jiemam

Jiemamy

✦ DBの進化的設計 by Martin Fowler

✦ アプリケーションのビルドに伴って ✦ アプリケーションが依存するDBの構築を自動化 ✦ DBスキーマに対して変更管理を適用

スマートビルド / デプロイ

–Miyamoto, Daisuke (2006)

“リポジトリからコードをチェックアウトし、 必要に応じて環境固有の設定をした後、

コマンド1つで起動・デプロイができるべき”

2006年にここまで言ってたかどうか忘れましたが、 Seasar Conference 2008では確実に言ってた。

この考えは現在も変わっていません。

ってなことを訴え始めた2006年

✦ あの頃の俺は青かった。

✦ 自動化と管理の対象はDBじゃない。

✦DBを含む、インフラ全部だ。

時は流れ、現在…

✦ 世はまさに大クラウド時代! ✦ Infrastructure as Code! ✦ プログラムから、アプリケーションのビルド・インフラの構築・デプロイまでが実現できる世界

Single Command DeployThoughtWorks, Inc. Technology Radar March 2012

ここまでイントロ

本日のアジェンダ✦ AWSというインフラ環境をざっとご紹介 ✦ 実演 Single Command Deploy

✦ Spring(!?)Bootアプリケーションを ✦ Dockerを使ってコンテナ化して ✦ Gradleによるタスクで ✦ AWS Elastic Beanstalk環境にデプロイ

いきなり実演(裏で✦ 前提条件(下記を満たしていれば、みんな出来るはず)

✦ Mac OS(Winでも動くかも…。未確認) w/ git ✦ インターネット接続回線があって ✦ AWSアカウントを持っていて ✦ EC2キーペアの発行・登録が終わっていて ✦ S3のバケットが1つ作ってあって ✦ アクセスキーを↓規定の場所に記述してある~/.aws/credentials

✦ http://dev.classmethod.jp/cloud/aws/exclusive-aws-credentials-location/

$ ### チェックアウト###

$ git clone [email protected]:classmethod-aws/berserker.git ~/tmp/sis-demo

$ cd ~/tmp/sis-demo

$ git checkout refs/tags/sis-demo

$ #### ここは各環境で異なるところ ###

$ cp env/_sample.gradle env/personal.gradle

$ sed -i '' -e 's/templateBucket:.*$/templateBucket: "cf-templates-1r72h3gknbax2-ap-northeast-1",/' env/personal.gradle

$ sed -i '' -e 's/KeyName:.*$/KeyName: "miyamoto-kp1",/' env/personal.gradle

$ diff env/_sample.gradle env/personal.gradle

$ ### デプロイ・HTTPアクセス・撤収 ###

$ ./gradlew -is awsFullDeploy

$ curl -s ...

$ ./gradlew -is awsFullUndeploy

システムインフラネットワークとサーバと、諸々。

旧来の最小構成インフラ‣ サーバーマシン1台

‣ Apache

‣ Tomcat

‣ MySQL

‣ ルーターとインターネット接続(IPアドレス等)

オンプレ中規模インフラ‣ DNSサーバー / ルーター / ロードバランサー

‣ APサーバー

‣ DBサーバー

‣ メールサーバー

‣ その他

Amazon Web Services

AWSインフラ

✦ ネットワーク:Amazon VPC ✦ データベース・サーバ:Amazon RDS ✦ アプリケーション・サーバ:Amazon EC2

Amazon VPC✦ VPC = 1つのプライベートネットワーク

✦ インターネット接続は任意 ✦ Availability Zone (AZ)

✦ 物理的に離れているけど高速な専用線で結ばれたDC

✦ VPC × AZ → Subnet

基本的な構成 (1) Single-AZ構成

✦ 可用性が足りない ✦ サービスを止めずにメンテナンスできない

✦ スケーラビリティが足りない ✦ 付加が増えても垂直にしかスケールできない

サーバは落ちるものだし、水平スケール出来るのが望ましい 可用性が欲しい・スケーラビリティが欲しい

Amazon EC2

✦ 結構気軽に「メンテだから再起動してね」って言われる。

✦ Multi-AZ による冗長化構成が前提。 ✦ メンテナンスだけでなく、障害にも対応。 ✦ Design for failure

基本的な構成 (2) Multi-AZ構成

✦ AZ(≒AWSのデータセンター)が1つ丸ごとぶっ飛んでも、サービスが継続できる

✦ 負荷が増えたら水平にスケールできる ✦ ただし、アプリケーション・サーバをステートレスに保たなければならない ✦ データをファイルシステムに書かない ✦ RDBやS3に書き出す

Spring Boot

最近のJavaフレームワーク✦ Play Framework ✦ Dropwizard ✦ Ninja framework ✦ Spring Boot

✦ アプリケーションサーバ(コンテナ)準備不要の、スタンドアローンアプリ。

✦ Javaプロセスを1つ立ち上げればHTTPサーバが動く。

Spring Bootの主な特徴✦ 簡単起動

✦ $ java -jar your-app.jar ✦ クラスパス設定やコンテナ準備不要。

✦ 設定の自動化 ✦ classpath内のクラスの有無によって自動設定 ✦ 設定のカスタマイズはアノテーションで

✦ Spring Bootを使ってみよう ✦ http://dev.classmethod.jp/server-side/spring-boot/

Flyway ~ DBの進化的設計✦ Jiemamy is dead

✦ スキーマにバージョンを付与 ✦ 前バージョンからの差分SQLを自作する ✦ どこまで適用したかは、実際のDB上に管理テーブルを作って記録 ✦ 未適用の差分SQLを順次適用することによるマイグレーション ✦ ただし、自動化されたロールバックは不可能 ✦ Flyway with Spring Boot でDBマイグレーションを自動化する

✦ http://dev.classmethod.jp/server-side/flyway-with-spring-boot/

Docker

1プロセスのための環境✦ 一般的にサーバ上では様々なプロセスが起動 ✦ Applicationの実行には直接関係無いものも多数 ✦ Applicationプロセスとしてはザックリと、これだけあれば充分じゃない? ✦ プロセスが稼働する基盤(OSとメモリ空間?) ✦ プロセスが読み書きする状態(ファイルシステム)

✦ 他のプロセスは見えなくて良い。 ✦ 他のプロセス用のファイルも見えなくていい。

Docker for Spring Boot✦ 最小限のファイルシステムにJavaをインストールし、your-app.jar を取り込んだDockerイメージを作成

✦ イメージからDockerコンテナ(プロセス環境)を作成し、その中で java プロセスを起動

✦ Docker と Spring Boot は相性が良い。

Dockerfileの例FROM java:openjdk-8-jdkEXPOSE 8080WORKDIR /opt/berserker/ADD logback.xml /opt/berserker/logback.xmlADD berserker-x.xx.jar /opt/berserker/CMD /usr/bin/java \ -DJDBC_CONNECTION_STRING=$JDBC_CONNECTION_STRING \ ... -Dspring.profiles.active=$SPRING_PROFILES_ACTIVE \ -Dlogging.config=/opt/berserker/logback.xml \ -Dserver.port=8080 \ -jar berserker-x.xx.jar

OpenJDK 8 インストール済みの ファイルシステムイメージ

アプリケーション本体jarの組み込み

起動コマンド

AWSElastic Beanstalk

ホントは今は オレンジ色

Elastic Beanstalk

✦ AWS上のWebシステムの基本構成を自動構築 ✦ 開発者はApplication Bundle(後述)を作成し、AWSに食わせる

✦ これだけで、アプリの動作環境が構築完了する

Application Bundle

✦ Beanstalkの作法に従ったApp一式を含むZIPファイル ✦ Spring Bootアプリケーション(jar) ✦ logback.xml(ログ設定) ✦ Dockerfile(前述)

✦ これをZIPで固めてAmazon S3にアップロード

CloudFormation✦ Beanstalkの守備範囲

✦ アプリケーションサーバシステム ✦ ELB, EC2 (AutoScaling) ...

✦ CloudFormationの守備範囲 ✦ システム全体を構成する周辺AWSリソース

✦ Beanstalk, VPC, S3, RDS ...

アプリケーションのデプロイと システムのデプロイ

–Miyamoto, Daisuke

“リポジトリからコードをチェックアウトし、 必要に応じて環境固有の設定をした後、

コマンド1つでシステムの起動・デプロイができるべき”

CloudFormation

Template

+Parameter

Parameter

Stack

Bucket withObjects

DynamoDB Table

ELB

Instances Auto Scaling Amazon CloudFront

基本的システム構成S3, DynamoDB, EC2,

IAM, AutoScaling, SecurityGroup,ELB, CloudFront

Instance Type, クラスタの台数,

SSH接続元IP, キー名, ...等

Template

JSON、ということはインフラを バージョン管理できる\(^o^)/

インフラの進化的設計

• インフラの構成をTemplateとしてバージョン管理する

• TemplateからStackを作る(構築)

• インフラ構成を追加・編集(そしてバージョン管理)

• 既存Stackを新しいテンプレートで更新する(成長)

Gradle

Gradle

✦ ビルド等を中心としたジョブ実行基盤 ✦ Javaの依存ライブラリ管理~    ビルド、パッケージング

✦ Spring Bootアプリケーションの起動 ✦ プラグイン:spring-boot-gradle-plugin

ではこれを…

✦ App Bundleの作成に使えないだろうか? ✦ App BundleのS3 uploadに使えないだろうか? ✦ Beanstalkの環境起動に使えないだろうか?

✦ 全部Yes!!

App Bundle作成task createBundle(type: Zip, dependsOn: bootRepackage) { archiveName = ... // zipファイル名 from "src/main/bundle" // Dockerfile等 from jar.archivePath // jar}

gradle-aws-plugin

✦ GradleからAWSリソースを操作したい ✦ 参考: https://github.com/classmethod-aws/gradle-aws-plugin

導入buildscript { repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "jp.classmethod.aws:gradle-aws-plugin:0.21" } } apply plugin: "jp.classmethod.aws.s3" apply plugin: "jp.classmethod.aws.cloudformation"apply plugin: "jp.classmethod.aws.beanstalk"

CloudFormation操作cloudFormation { stackName = 'berserker' conventionMapping.stackParams = { // (snip) return stackParams } capabilityIam true templateFile = file('berserker.template') templateBucket = ... templateKeyPrefix = ... } awsCfnMigrateStack.mustRunAfter uploadBundleawsCfnMigrateStack.dependsOn awsCfnUploadTemplate

S3へのリソースアップロード

task createBundle(type: Zip, dependsOn: ...) { // (snip) }

task uploadBundle(dependsOn: createBundle, type: AmazonElasticBeanstalkUploadBundleTask) { file project.createBundle.archivePath overwrite project.version.endsWith('-SNAPSHOT')}

Gradle Task Graph

一発タスクtask awsFullDeploy(dependsOn: [ uploadBundle, awsCfnUploadTemplate, awsCfnMigrateStackAndWaitComplete ]) task awsFullUndeploy(dependsOn: [ awsCfnDeleteStackAndWaitCompleted ])

Gradle Task

✦ ./gradlew bootRun

✦ ./gradlew awsFullDeploy

✦ ./gradlew awsFullUndeploy

システム ポータビリティ

Full Described System✦ システム構築及び運用のコード化・自動化―― Automated

✦ 自動化しない・できない部分はポエムを書く―― Documented

✦ システムの構成全てが「記述」されている。

✦ 1つのAWSアカウント内に複数の環境を構築できる。 ✦ 例えば本番環境と開発環境等。 ✦ 社内で共通のAWSアカウントに展開する。

✦ あらゆるAWSアカウントに環境を構築できる。 ✦ 例えば個人検証環境。サンドボックス。 ✦ 開発者毎の個人検証用AWSアカウントに展開する。

✦ あらゆるリージョンに環境を構築できる。 ✦ と、いいかもね。DRの視点で。

環境依存設定✦ プロジェクト直下のenvディレクトリに設定ファイルを置き、それを動的に読み込む

-Penv=prd

✦env/ ✦ .gititnore ✦ _sample.gradle ✦prd.gradle ✦dev.gradle ✦personal.gradle

✦profile名(AWSのキー) ✦リージョン名 ✦EC2キーファイルのパス ✦各種CFnパラメータ ✦ローカルDB名、user、pass ✦ログ設定ファイルのパス

portability✦ ./gradlew awsFullDeploy -Penv=prd

✦ ./gradlew awsFullDeploy -Penv=dev

✦ ./gradlew awsFullDeploy -Penv=personal

✦ 詳しくは Developers.IO「プロジェクトに対する環境固有設定の導入」http://bit.ly/gradle-env-dep-config を参照。

まとめ

ホントは今は オレンジ色