aws elasticbeanstalk でデプロイをする

[AWS] [AWS Elastic Beanstalk] AWS Elastic Beanstalk のデプロイ環境と基礎知識 | UI/UX Design、フロントエンド系の技術に関する備忘録 | whiskers

上記を参考。

仕事で既に用意されたAWS Elastic Beanstalk 環境にデプロイする機会があったので環境構築と使い方についてメモしておきます。AWSやGitについては説明を省くのでこれから使い始めたい方は以下のページを参考にどうぞ。

1, AWS Elastic Beanstalk とは

AWS Elastic Beanstalk は、Java、.NET、PHP、Node.js、PythonRuby、Go および Docker を使用して開発されたウェブアプリケーションやサービスを、Apache、Nginx、Passenger、IIS など使い慣れたサーバーでデプロイおよびスケーリングするための、使いやすいサービスです。

お客様はコードをアップロードするだけで、Elastic Beanstalk が、キャパシティのプロビジョニング、ロードバランシング、Auto Scaling からアプリケーションの状態モニタリングまで、デプロイを自動的に処理します。同時に、お客様のアプリケーションが稼動している AWS リソースの完全なコントロールを維持でき、いつでも基本的なリソースにアクセスすることができます。

AWS Elastic Beanstalk

もう少し具体的に言うとgitのリポジトリAWS Elastic BeanstalkにpushしてAWS環境に自動デプロイしてくれるサービスです。デザイナーやフロントエンジニアは既に用意されたAWS Elastic Beanstalk環境にpushするだけでデプロイを行うことができます。

2, デザイナーやフロントエンジニアがAWS Elastic Beanstalkを使うには

AWS Elastic Beanstalkを使うために必要なソフトウェアは以下の通り。

2.1, IAMアカウント

Gitは既に使っている前提で、デザイナーやフロントエンジニアであればインフラエンジニアからIAMアカウントが発行されるはずです。発行されたIAMアカウントでAWSマネジメントコンソールにアクセスし、アクセスキーとシークレットキーをメモしておきます。

このアクセスキーとシークレットキーをユーザーrootの.aws/credentialsAWSへアクセスするためのプロファイル<profile-name>を定義します。<profile-name>の部分は任意の指定が可能です。

[<profile-name>]
aws_access_key_id = <AWS_ACCESS_KEY_ID>
aws_secret_access_key = <AWS_SECRET_ACCESS_KEY>

2.2, Python

詳しいインストール方法は記載しませんがHomebrewからインストール可能です。インストールが完了したらバージョンを確認しておきます。

$ brew install python
$ python -V
Python 2.7.9

2.3, Elastic Beanstalk CLI

AWS Elastic Beanstalkをコマンドラインから操作するためにElastic Beanstalk CLIをHomebrew経由でインストールします。インストールが完了したらこちらもバージョンを確認します。

$ brew install aws-elasticbeanstalk
$ eb --version
EB CLI 3.3.2 (Python 2.7.6)

これでAWS Elastic Beanstalkに必要な環境は用意できました。

3, デプロイするための準備

インフラエンジニアがすでに環境を用意している前提でデプロイするための準備を行います。AWS Elastic Beanstalkにデプロイするためにはまずgitプロジェクトを定義します。

$ mkdir <project_directory>
$ cd <project_directory>
$ git init

3.1, AWS Elastic Beanstalk

次に$ eb init --profile <profile-name>を実行し質問形式でElastic Beanstalkプロジェクトを設定していきます。<profile-name>はIAMアカウントを設定した際に.aws/credentialsに記載したプロファイルネームです。質問は以下の3つになります。

  1. リージョン(AWSのリージョン)
  2. アプリケーション(用意されているアプリケーション)
  3. 環境(テスト、本番等)

アプリケーションと環境はインフラエンジニアが用意しているはずなので、基本的に番号を入力して選択していくだけです。リージョンについてはマネジメントコンソールから確認が必要ですが、日本であればTokyoになるでしょう。コマンドが完了すると.elasticbeanstalk/config.yml.gitignoreが作られます。

.elasticbeanstalk/config.ymlにはgitのブランチmaster:に合わせて環境名environment: app-prdが指定されます。masterブランチでデプロイを実行した際、app-prdの環境にデプロイするという指定です。

branch-defaults:
  master:
    environment: app-prd
global:
  application_name: appname
  default_ec2_keyname: hoge-fuga
  default_platform: 64bit Amazon Linux 2015.03 v1.3.2 running PHP 5.6
  default_region: ap-northeast-1
  profile: <profile-name>
  sc: git

.gitignoreの中身はこのようになっています。

# Elastic Beanstalk Files
.elasticbeanstalk/*
!.elasticbeanstalk/*.cfg.yml
!.elasticbeanstalk/*.global.yml

これでデプロイの準備が完了しました。あとは$ git add ...$ git commit ...してコミットしておきます。

4, AWS Elastic Beanstalkにデプロイする

デプロイ作業は簡単、コマンド1発です。コマンドを実行するとインフラエンジニアの手を煩わせず自動でデプロイ処理が行われます。

$ eb deploy

デプロイ先を確認するのもコマンドから行えます。ブラウザが起動しデプロイ先が表示されます。

$ eb open

4.1, developブランチをテスト環境にデプロイするには

developブランチの場合はテスト環境にデプロイしたい、そんな時はdevelopブランチにcheckoutし$ eb initを行うことでブランチ設定を追加することができます。

branch-defaults:
  master:
    environment: app-prd
  develop:
    environment: app-dev
...

4.2, 環境情報を知りたい

$ eb status
Environment details for: <env-name>
  Application name: <app-name>
  Region: ap-northeast-1
  Deployed Version: fba1
  Environment ID: <id>
  Platform: 64bit Amazon Linux 2015.03 v1.3.2 running PHP 5.6
  Tier: WebServer-Standard-1.0
  CNAME: <xxxxxxx.elasticbeanstalk.com>
  Updated: 2015-05-18 11:59:23.048000+00:00
  Status: Ready
  Health: Green
Alert: An update to this CLI is available.

4.3, マネジメントコンソールを開く

$ eb console [environment_name]

4.4, アプリケーションの環境一覧を表示する

$ eb list

4.5, 環境に設定されている環境変数を表示する

$ eb printenv [environment_name]

環境変数を設定することもできます。

$ eb setenv key=[value]

4.6, デフォルトの環境を設定する

$ eb use <environment_name>

5, その他のコマンド

以下のコマンドを使う機会はそれほどないと思いますが一応紹介しておきます。

5.1, 環境を新たに作成する

$ eb create <env-name>

5.2, 実行中の環境をシャットダウンする

$ eb terminate [env-name]

5.3, アプリケーションを完全に削除する

このコマンドを実行するとアプリケーションが消えるのでかなり危険なコマンドです。

$ eb terminate --all

6, まとめ

デプロイ系のツールをはじめて使いましたが便利ですね。すべては紹介しきれていないので下記ドキュメントを改めて読むとコマンド周りを一通り覚えることができると思います。

AsyncTask 注意点

AsyncTaskを使ってUIThreadと違うThreadでsocket通信などをしたら、複数AsyncTask同時実行されない現象があった。 どうもデフォルトだとAsyncTaskが並行実行されず、順番待ちみたい。

調べたら、AsyncTaskには以下の二つの実行モードがあると分かった。

  • THREAD_POOL_EXECUTOR
    並列

  • SERIAL_EXECUTOR
    単列

Android 開発 viewをリサイズ

やり方をメモ

タイミング

Activity内なら、onWindowFocusChanged(hasFocus=true)いい。 onCreateだと、viewがまだ見えない、取得する幅が0のまま。

カスタマビューを使ってるなら、surfaceCreated(SurfaceViewの場合)でもいい。

設定の仕方

this.getLayoutParams().height = (int) height;
this.getLayoutParams().width = (int) width;

Android 開発、向きを設定

静的に指定する場合

下記のようにAndroidManifest.xmlで指定する。

  • 縦固定
AndroidManifest.xml
<activity
    android:name=".MainActivity"
    android:screenOrientation="portrait">
  • 横固定
AndroidManifest.xml
<activity
    android:name=".MainActivity"
    android:screenOrientation="landscape">
  • 自動
AndroidManifest.xml
<activity
    android:name=".MainActivity"
    android:screenOrientation="unspecified"> <!-- 未指定でもOK! というか、普通は未指定 -->

動的に指定する場合

下記のように Activity#setRequestedOrientation を呼び出す。
呼び出した結果、実際に画面の向きが変わった場合はActivityが再生成される(android:onConfigChangesでorientation等を指定していなければ)。

  • 縦固定
MainActivity.java
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  • 横固定
MainActivity.java
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
  • 自動
MainActivity.java
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);

初Android開発

環境

Android Studio

起動

なぜかデフォルトのままエミュレータが起動しない。
後程原因判明: vagrantvirtualboxを起動しているのは理由。
$vagrant haltで問題解決。

仕方なく実機で確認することに。

Activity

アプリで言うと画面のこと。iOSの場合StoryBoradで描くViewと同じ。

  • activity間遷移
Intent intent = new Intent(getApplicationContext(),JoinActivity.class);
startActivity(intent);
  • Toastの表示

引数で表示時間設定。メソッドで表示position設定

Toast ts = Toast.makeText(this, "You did not enter a nickname", Toast.LENGTH_SHORT);
ts.setGravity(Gravity.TOP, 0, 0);
ts.show();
  • タイトルバーの非表示

AppCompatActivityを普通のActivityに変える。

もしくは、動的に切り替え:
/ 非表示 /
getSupportActionBar().hide();

/ 表示 /
getSupportActionBar().show();

AngularJS サーバサイドJSONレスポンスのスタブを作成

WEBサービスを実現する場合、フロントエンドからバックエンドのAPIサーバにアクセスすることが多いと思いますが、バックエンド側がまだ開発途中であったりすると、代替としてNode.js等でスタブのアプリケーションを作ったり、または固定のJSONファイルを作ったりと、割と手間がかかってしまいます。

今回、ためしに AngularJS の ngMockE2E を利用して、擬似的なAPIサーバを構築してみたので、その方法を紹介します。

前提

  • Yeomanで構築したAngularJS開発環境が前提です。

  • 別途 ngMockライブラリをインストール場合も、Bower を使えば簡単にできます。

    • $ bower install angular-mocks

ngMockを使う準備

①index.htmlからngMockのJSファイルをロード

app/index.html
<script src="bower_components/angular-mocks/angular-mocks.js"></script>

②ルートモジュールにngMockE2Eを追加

app/scripts/app.js
'use strict';

angular.module('ngMockTestApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute',
+  'ngMockE2E'
])
  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }]);

これで準備は完了です。

疑似APIサーバの処理を書く

  • 先程と同じ app.js に、.run 以降を追記してみます。
    • 面倒なのでこうしてますが、本当はファイルを分けた方がいいです。
app/scripts/app.js
'use strict';

angular.module('ngMockTestApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute',
  'ngMockE2E'
])
  .config(['$routeProvider', function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  }])
  .run(['$httpBackend', function ($httpBackend) {

    $httpBackend.whenGET(/^views\//).passThrough();

    var sample = [
      {
        "id": "1",
        "name": "山田"
      },
      {
        "id": "2",
        "name": "鈴木"
      }
    ];

    $httpBackend.whenGET('data/sample.json?hoge=1').respond(200, sample, {});

    $httpBackend.whenGET('data/sample.json?hoge=2').respond(function(method, url, data, headers) {
            return [200, sample, {}];
    });

  }])
;

動作確認

ここは何でもいいのですが、APIを叩く処理を書きます。

まず、APIにアクセスするFactoryを作って、

app/scripts/services/data.js
'use strict';

angular.module('ngMockTestApp')
  .factory('JsonData', function ($http) {

    return {

      getSampleData: function () {

        return $http.get('data/sample.json?hoge=1')

          .success(function(data, status, headers, config) {

            return data;

          });

      }

    }

  })
;

Controllerから呼び出し、

app/scripts/controllers/main.js
'use strict';

angular.module('ngMockTestApp')
  .controller('MainCtrl', ['$scope', 'JsonData', function ($scope, JsonData) {

    JsonData.getSampleData().then(function(res){

      $scope.items = res.data;

    });

  }])
;

Viewで描写します。

app/views/main.html
<!-- 対応する Controller は app.js の $routeProvider で定義済み -->
<li ng-repeat="item in items">
  {{item.id}} - {{item.name}}
</li>

結果はこんな感じ。表示されました!

スクリーンショット 2014-05-13 15.06.07.png

疑似APIサーバの処理をみてみる

  .run(['$httpBackend', function ($httpBackend) {

    $httpBackend.whenGET(/^views\//).passThrough();

    var sample = [
      {
        "id": "1",
        "name": "山田"
      },
      {
        "id": "2",
        "name": "鈴木"
      }
    ];

    $httpBackend.whenGET('data/sample.json?hoge=1').respond(200, sample, {});

    $httpBackend.whenGET('data/sample.json?hoge=2').respond(function(method, url, data, headers) {
            return [200, sample, {}];
    });

  }])

全ての HTTPアクセスがこのロジックを経由します。
で、ここに全てのHTTPアクセスについて定義しないとエラーになるので、注意が必要です。
正規表現はつかえます。)

.passThrough()は何もしない、という意味です。テンプレートのアクセスもHTTP経由なので、「URLが views/で始まる場合は何もしない」というふうに記載しています。

whenGET でURLを定義し、対応するレスポンスを .respond に記載します。今回は2パターンを記載してみました。

上のパターンは、単純に用意されたJSONデータをレスポンンスしています。

下のパターンは、JavaScriptでいろいろ処理させてからレスポンンスさせるパターンです。
この例だと、結局JSONをレスポンスしているだけですが、判定処理とか動的なJSONファイルの生成処理がここに書けるわけです。

ほか

 

qiita.com