Введение
В этой статье я постараюсь объяснить, как заставить работать вместе два популярных cloud сервиса на благо человечества. Несомненно, придет тот светлый день, когда Elastic Beanstalk будет идеален и эта статья не понадобится.
Функциональность которую предоставляет СloudBees которой мне не хватает в Elastic Beanstalk Free Tier
- MySQL DB
- Jenkins
- Svn, Git
- Deploy to CloudBees
Функциональность которую предоставляет Elastic Beanstalk которой мне не хватает в СloudBees
- «100%» uptime
- быстродействие
- мониторинг, event-ы и тд.
Несомненно Elastic Beanstalk более мощный и перспективный сервис, который полностью поглотит СloudBees в будущем, а пока сделаем его лучше для себя.
Шаг 1: Регистрируем Elastic Beanstalk (пропустите, если у вас уже есть)
В примере я создавал тестовое приложение на серверах US East (Virginia) что, как мне кажется, существенно повлияло на скорость соединения с базой и деплоймента приложения из Jenkins. Но вы, конечно же, можете попробовать другие регионы.
1.1 Создаем новое приложение
1.2 Получаем результат
1.3 Создаем нового пользователя для Elastic Beanstalk API
1.4 Даем пользователю permission «AWS Elastic Beanstalk Full Access»
1.5 Проверяем S3 bucket созданный для хранения WAR
1.6 Проверяем что тестовое приложение запущено
Шаг 2: Регистрируем CloudBees (пропустите, если у вас уже есть)
2.1 Создаем новую MySQL DB
Для примера была создана так же таблица testdata, с полями id, foo, bar, чтобы продемонстрировать скорость выполнения запросов.
2.2 Создаем GIT репозиторий (используется исключительно для примера, чтобы хранить исходники)
2.3 to be continued… см. шаг: 4
Шаг 3: Создаем тестовое web приложение
pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.elasticbeanstalk.sampleapp</groupId>
<artifactId>elasticbeanstalk-sampleapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>elasticbeanstalk-sampleapp</name>
<url>http://Default-Environment-whahswsu23.elasticbeanstalk.com</url>
<properties>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
<beanstalk.versionLabel>${maven.build.timestamp}</beanstalk.versionLabel>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.16</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>elasticbeanstalk-sampleapp</finalName>
<plugins>
<plugin>
<groupId>br.com.ingenieux</groupId>
<artifactId>beanstalk-maven-plugin</artifactId>
<version>0.2.6</version>
<configuration>
<applicationName>My First Elastic Beanstalk Application</applicationName>
<s3Bucket>elasticbeanstalk-us-east-1-997639223855</s3Bucket>
<s3Key>${maven.build.timestamp}-${project.build.finalName}.war</s3Key>
<environmentName>Default-Environment</environmentName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Из необычного только плагин elasticbeanstalk-sampleapp для автоматической установки приложения на Elastic Beanstalk.
applicationName — указал значение по умолчанию из пункта 1.2
s3Bucket — имя S3 bucket из пункта 1.5
s3Key — имя war файла для сохранения в S3, ${maven.build.timestamp} будет использован, как имя версии приложения.
environmentName — указал значение по умолчанию из пункта 1.2
context.xml
<Context>
<Resource name="jdbc/beanstalk"
auth="Container"
type="javax.sql.DataSource"
factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
username="beanstalk"
password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://ec2-50-19-213-178.compute-1.amazonaws.com:3306/beanstalk?autoReconnect=true&characterEncoding=utf8"
validationQuery="SELECT 1"
maxWait="1000"
removeAbandoned="true"
maxActive="30"
maxIdle="10"
removeAbandonedTimeout="60"
logAbandoned="true"/>
</Context>
Описаны параметры подключения к базе созданной в пункте 2.1
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<resource-ref>
<res-ref-name>jdbc/beanstalk</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
index.jsp
<%@ page session="false" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Custom Welcome Page</title>
</head>
<body>
<p>Your <b>custom</b> AWS Elastic Beanstalk Application is now running on your own dedicated environment in the AWS Cloud</p>
<br/><br/><b>testdata:</b><br/>
<jsp:useBean id="now1" class="java.util.Date" />
<sql:query dataSource="jdbc/beanstalk" var="rst" scope="request">
select id, foo, bar from testdata
</sql:query>
<c:forEach items="${rst.rows}" var="row">
${row.id} ${row.foo} ${row.bar}<br/>
</c:forEach>
<jsp:useBean id="now2" class="java.util.Date" />
<br/><br/>Time: ${now2.time - now1.time} ms.
</body>
</html>
И тестовая index страница, в которой выполняется простейший запрос к базе и отображается время выполнения.
Скачать проект целиком: git clone git://git.cloudbees.com/wickiup/beanstalk.git
Шаг 4: Возвращаемся к CloudBees — настраиваем Jenkins
4.1 Создаем новую задачу
4.2 Указываем из какого репозитория скачать проект (в примере GIT от CloudBees)
4.3 Добавляем Post Step для деплоя приложения на Elastic Beanstalk
aws.accessKey и aws.secretKey укажите тот, что получили при выполнении пункта 1.3
Этот шаг добавит WAR в S3 хранилище, создаст новую версию приложения, и обновит инстанс.
4.4 Собираем проект — смотрим в лог
[INFO] Target Path: s3://elasticbeanstalk-us-east-1-997639223855/20120724145549-elasticbeanstalk-sampleapp.war
[INFO] Uploading artifact file: /scratch/hudson/workspace/beanstalk/target/elasticbeanstalk-sampleapp.war
[INFO] Artifact Uploaded
[INFO] SUCCESS
[INFO] ETag: 81af708b625c34c2b5a9b1d12057f575 [class: String]
[INFO]
[INFO] --- beanstalk-maven-plugin:0.2.6:create-application-version (default-cli) @ elasticbeanstalk-sampleapp ---
[INFO] SUCCESS
[INFO] sourceBundle: {S3Bucket: elasticbeanstalk-us-east-1-997639223855, S3Key: 20120724145549-elasticbeanstalk-sampleapp.war, } [class: S3Location]
[INFO] versionLabel: 20120724145549 [class: String]
[INFO] description: elasticbeanstalk-sampleapp [class: String]
[INFO] applicationName: My First Elastic Beanstalk Application [class: String]
[INFO] dateCreated: Tue Jul 24 14:56:03 EDT 2012 [class: Date]
[INFO] dateUpdated: Tue Jul 24 14:56:03 EDT 2012 [class: Date]
[INFO]
[INFO] --- beanstalk-maven-plugin:0.2.6:update-environment (default-cli) @ elasticbeanstalk-sampleapp ---
[INFO] Calling update-environment, and using versionLabel: 20120724145549
[INFO] SUCCESS
[INFO] resources: {LoadBalancer: {LoadBalancerName: awseb-Default-Environment, Domain: awseb-Default-Environment-1219914711.us-east-1.elb.amazonaws.com, Listeners: [{Protocol: http, Port: 80, }], }, } [class: EnvironmentResourcesDescription]
[INFO] versionLabel: 20120724145549 [class: String]
[INFO] status: Updating [class: String]
[INFO] applicationName: My First Elastic Beanstalk Application [class: String]
[INFO] endpointURL: awseb-Default-Environment-1219914711.us-east-1.elb.amazonaws.com [class: String]
[INFO] health: Grey [class: String]
[INFO] dateUpdated: Tue Jul 24 14:56:03 EDT 2012 [class: Date]
[INFO] environmentId: e-4hephxdqd9 [class: String]
[INFO] solutionStackName: 32bit Amazon Linux running Tomcat 7 [class: String]
[INFO] CNAME: Default-Environment-whahswsu23.elasticbeanstalk.com [class: String]
[INFO] description: This is the default environment for the sample application. [class: String]
[INFO] dateCreated: Tue Jul 24 13:10:42 EDT 2012 [class: Date]
[INFO] environmentName: Default-Environment [class: String]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14.653s
[INFO] Finished at: Tue Jul 24 14:56:04 EDT 2012
[INFO] Final Memory: 6M/15M
[INFO] ------------------------------------------------------------------------
Finished: SUCCESS
Шаг 5: Проверим, что все получилось
5.1 Смотрим в консоль Elastic Beanstalk
Как мы видим, появилась новая версия приложения (20120724145549) которая сейчас является активной.
5.2 Смотрим в консоль S3
WAR файл (20120724145549-elasticbeanstalk-sampleapp.war) с текущей версией приложения на месте.
5.3 Проверяем WEB интерфейс
Время выполнения запроса ~2 мс, что как бы неплохо для Free Tier.
Документация
AWS Free Tier
beanstalk-maven-plugin
Автор: mais