翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
このチュートリアルでは、Elastic Beanstalk コマンドラインインターフェイス (EB CLI) を使用してサンプルアプリケーションを Elastic Beanstalk にデプロイした後、Express
注記
この例では、課金対象となる可能性のある AWS リソースを作成します。AWS 料金の詳細については、「https://aws.amazon.com/pricing/
前提条件
このチュートリアルでは、次の前提条件が必要です。
-
Node.js ランタイム
-
デフォルトの Node.js パッケージマネージャーソフトウェア、npm
-
Express コマンドラインジェネレーター
-
Elastic Beanstalk コマンドラインインターフェイス(EB CLI)
最初の 3 つのリストされたコンポーネントのインストールとローカル開発環境の設定の詳細については、「Elastic Beanstalk 用の Node.js 開発環境の設定」を参照してください。このチュートリアルでは、AWS SDK for Node.js をインストールする必要はありません。これは、参照トピックでも言及されています。
EB CLI をインストールおよび設定する手順の詳細については、「Elastic Beanstalk コマンドラインインターフェイスをインストールする」および「EB CLI の設定」を参照してください。
Elastic Beanstalk 環境の作成
アプリケーションディレクトリ
このチュートリアルでは、アプリケーションソースバンドル用に nodejs-example-express-elasticache
と呼ばれるディレクトリを使用します。このチュートリアル用の nodejs-example-express-elasticache
ディレクトリを作成します。
~$ mkdir nodejs-example-express-elasticache
注記
この章の各チュートリアルでは、アプリケーションソースバンドル用に独自のディレクトリを使用します。ディレクトリ名は、チュートリアルで使用されるサンプルアプリケーションの名前と一致します。
現在の作業ディレクトリを nodejs-example-express-elasticache
に変更します。
~$ cd nodejs-example-express-elasticache
次に、Node.js プラットフォームとサンプルアプリケーションを実行する Elastic Beanstalk 環境を設定しましょう。Elastic Beanstalk コマンドラインインターフェイス (EB CLI) を使用します。
アプリケーションの EB CLI リポジトリを設定し、Node.js プラットフォームを実行する Elastic Beanstalk 環境を作成するには
-
eb init コマンドを使用してリポジトリを作成します。
~/nodejs-example-express-elasticache$
eb init --platform
node.js
--region<region>
このコマンドは、
.elasticbeanstalk
という名前のフォルダに、アプリケーションの環境作成用の設定ファイルを作成し、現在のフォルダに基づいた名前で Elastic Beanstalk アプリケーションを作成します。 -
eb create コマンドを使用して、サンプルアプリケーションを実行する環境を作成します。
~/nodejs-example-express-elasticache$
eb create --sample
nodejs-example-express-elasticache
このコマンドは、Node.js プラットフォームと以下のリソース用にデフォルト設定でロードバランスされた環境を作成します。
-
EC2 インスタンス – 選択したプラットフォームでウェブ・アプリケーションを実行するよう設定された Amazon Elastic Compute Cloud (Amazon EC2) 仮想マシン。
各プラットフォームは、それぞれ特定の言語バージョン、フレームワーク、ウェブコンテナ、またはそれらの組み合わせをサポートするための、特定のソフトウェア、設定ファイル、スクリプトを実行します。ほとんどのプラットフォームでは、Apache または NGINX のいずれかをウェブアプリケーションの前にリバースプロキシとして配置します。そのプロキシがリクエストをアプリケーションに転送し、静的アセットを提供し、アクセスログとエラーログを生成します。
-
インスタンスセキュリティグループ – ポート 80 上のインバウンドトラフィックを許可するよう設定された Amazon EC2 セキュリティグループ。このリソースでは、ロードバランサーからの HTTP トラフィックが、ウェブ・アプリケーションを実行している EC2 インスタンスに達することができます。デフォルトでは、トラフィックは他のポート上で許可されません。
-
ロードバランサー – アプリケーションを実行するインスタンスにリクエストを分散するよう設定された Elastic Load Balancing ロードバランサー。ロードバランサーにより、インスタンスを直接インターネットに公開する必要もなくなります。
-
ロードバランサーセキュリティグループ – ポート 80 上のインバウンドトラフィックを許可するよう設定された Amazon EC2 セキュリティグループ。このリソースでは、インターネットからの HTTP トラフィックが、ロードバランサーに達することができます。デフォルトでは、トラフィックは他のポート上で許可されません。
-
Auto Scaling グループ – インスタンスが終了されたか利用不可になった場合にそのインスタンスを置き換えるよう設定された Auto Scaling グループ。
-
Amazon S3 バケット – Elastic Beanstalk の使用時に作成されるソースコード、ログ、その他のアーティファクトの保存場所。
-
Amazon CloudWatch アラーム – 環境内のインスタンスの負荷をモニタリングする 2 つの CloudWatch アラーム。負荷が高すぎる、または低すぎる場合にトリガーされます。アラームがトリガーされると、Auto Scaling グループはレスポンスとしてスケールアップまたはダウンを行います。
-
AWS CloudFormation スタック – 環境内でリソースを起動して、設定の変更を伝達するために、Elastic Beanstalk は AWS CloudFormation を使用します。リソースは、AWS CloudFormation コンソール
に表示できるテンプレートで定義されます。 -
ドメイン名 – ウェブ・アプリケーションまでのルートとなるドメイン名であり、
subdomain
.region
.elasticbeanstalk.com の形式です。ドメインセキュリティ
Elastic Beanstalk アプリケーションのセキュリティを強化するため、elasticbeanstalk.com ドメインはパブリックサフィックスリスト (PSL)
に登録されています。 Elastic Beanstalk アプリケーションのデフォルトドメイン名に機密性のある Cookie を設定する必要がある場合は、セキュリティ強化のため
__Host-
プレフィックスの付いた Cookie の使用をお勧めします。このプラクティスは、クロスサイトリクエストフォージェリ (CSRF) 攻撃からドメインを防御します。詳細については、Mozilla 開発者ネットワークの「Set-Cookie」ページを参照してください。
-
-
環境の作成が完了したら、eb open コマンドを使用して、デフォルトのブラウザでその環境の URL を開きます。
~/nodejs-example-express-elasticache$
eb open
これで、サンプルアプリケーションを使用して Node.js Elastic Beanstalk 環境が作成されました。独自のアプリケーションで更新できます。次に、Express フレームワークを使用するようサンプルアプリケーションを更新します。
Express を使用するようアプリケーションを更新する
Elastic Beanstalk 環境にサンプルアプリケーションを更新して、Express フレームワークを使用するようにします。
最終的な出典コードは、nodejs-example-express-elasticache.zip からダウンロードすることができます。
Express を使用するようアプリケーションを更新するには
サンプルアプリケーションの環境を作成したら、その環境を使用するようにアプリケーションを更新できます。この手順では、まず express と npm install コマンドを実行して、アプリケーションディレクトリで Express フレームワークを設定します。
-
express
コマンドを実行します。これによって、package.json
とapp.js
、およびいくつかのディレクトリが生成されます。~/nodejs-example-express-elasticache$
express
プロンプトが表示されたら、続行するには
y
と入力します。注記
express コマンドが機能しない場合は、前述の「前提条件」セクションで説明したように Express コマンドラインジェネレーターがインストールされていない可能性があります。または、express コマンドを実行するために、ローカルマシンのディレクトリパス設定を行う必要がある場合があります。開発環境の設定に関する詳細なステップについては、「前提条件」セクションを参照して、このチュートリアルを続行してください。
-
ローカルの依存関係を設定します。
~/nodejs-example-express-elasticache$
npm install
-
(オプション) ウェブアプリサーバーが起動することを確認します。
~/nodejs-example-express-elasticache$
npm start
次のような出力が表示されます:
> nodejs@0.0.0 start /home/local/user/node-express > node ./bin/www
サーバーは、デフォルトでポート 3000 で実行されます。テストするには、別のターミナルで
curl http://localhost:3000
を実行するか、ローカルコンピュータでブラウザを開いて URL アドレスhttp://localhost:3000
を入力します。サーバーを停止するには、[Ctrl+C] を押します。
-
nodejs-example-express-elasticache/app.js
をnodejs-example-express-elasticache/express-app.js
に名前変更します。~/nodejs-example-express-elasticache$
mv
app.js express-app.js
-
nodejs-example-express-elasticache/express-app.js
のvar app = express();
行を次に更新します。var app = module.exports = express();
-
ローカルコンピュータで、以下のコードを含む
nodejs-example-express-elasticache/app.js
という名前のファイルを作成します。/** * Module dependencies. */ const express = require('express'), session = require('express-session'), bodyParser = require('body-parser'), methodOverride = require('method-override'), cookieParser = require('cookie-parser'), fs = require('fs'), filename = '/var/nodelist', app = express(); let MemcachedStore = require('connect-memcached')(session); function setup(cacheNodes) { app.use(bodyParser.raw()); app.use(methodOverride()); if (cacheNodes.length > 0) { app.use(cookieParser()); console.log('Using memcached store nodes:'); console.log(cacheNodes); app.use(session({ secret: 'your secret here', resave: false, saveUninitialized: false, store: new MemcachedStore({ 'hosts': cacheNodes }) })); } else { console.log('Not using memcached store.'); app.use(session({ resave: false, saveUninitialized: false, secret: 'your secret here' })); } app.get('/', function (req, resp) { if (req.session.views) { req.session.views++ resp.setHeader('Content-Type', 'text/html') resp.send(`You are session: ${req.session.id}. Views: ${req.session.views}`) } else { req.session.views = 1 resp.send(`You are session: ${req.session.id}. No views yet, refresh the page!`) } }); if (!module.parent) { console.log('Running express without cluster. Listening on port %d', process.env.PORT || 5000) app.listen(process.env.PORT || 5000) } } console.log("Reading elastic cache configuration") // Load elasticache configuration. fs.readFile(filename, 'UTF8', function (err, data) { if (err) throw err; let cacheNodes = [] if (data) { let lines = data.split('\n'); for (let i = 0; i < lines.length; i++) { if (lines[i].length > 0) { cacheNodes.push(lines[i]) } } } setup(cacheNodes) }); module.exports = app;
-
nodejs-example-express-elasticache/bin/www
ファイルの内容を次に置き換えます。#!/usr/bin/env node /** * Module dependencies. */ const app = require('../app'); const cluster = require('cluster'); const debug = require('debug')('nodejs-example-express-elasticache:server'); const http = require('http'); const workers = {}, count = require('os').cpus().length; function spawn() { const worker = cluster.fork(); workers[worker.pid] = worker; return worker; } /** * Get port from environment and store in Express. */ const port = normalizePort(process.env.PORT || '3000'); app.set('port', port); if (cluster.isMaster) { for (let i = 0; i < count; i++) { spawn(); } // If a worker dies, log it to the console and start another worker. cluster.on('exit', function (worker, code, signal) { console.log('Worker ' + worker.process.pid + ' died.'); cluster.fork(); }); // Log when a worker starts listening cluster.on('listening', function (worker, address) { console.log('Worker started with PID ' + worker.process.pid + '.'); }); } else { /** * Create HTTP server. */ let server = http.createServer(app); /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { const addr = server.address(); const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); } /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { const port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; }
-
eb deploy コマンドを使用して変更を Elastic Beanstalk 環境にデプロイします。
~/nodejs-example-express-elasticache$
eb deploy
-
数分後、環境が更新されます。環境が緑色で示されていて準備完了したら、URL を再表示して正しく動作することを確認します。ウェブページに "Welcome to Express" が表示されます。
アプリケーションを実行している EC2 インスタンスのログにアクセスできます。ログのアクセス手順については、「Elastic Beanstalk 環境の Amazon EC2インスタンスからのログの表示」を参照してください。
次に、Amazon ElastiCache を使用するよう Express アプリケーションを更新します。
Amazon ElastiCache を使用するよう Express アプリケーションを更新するには
-
ローカルコンピュータで、出典バンドルの最上位ディレクトリに
.ebextensions
ディレクトリを作成します。この例では、nodejs-example-express-elasticache/.ebextensions
を使用します。 -
次のスニペットを使用して、設定ファイル
nodejs-example-express-elasticache/.ebextensions/elasticache-iam-with-script.config
を作成します。設定ファイルの詳細については、「Node.js 設定の名前空間」を参照してください。elasticache ノードの検出に必要な許可を持つ IAM ユーザーが作成され、キャッシュが変更されると常にファイルに書き込みされます。nodejs-example-express-elasticache.zip からファイルをコピーすることもできます。ElastiCache プロパティの詳細については、「例: ElastiCache」を参照してください。注記
YAML は、一貫したインデントに依存します。設定ファイルの例でコンテンツを置き換える際はインデントレベルを一致させ、テキストエディタがインデントにタブ文字ではなくスペースを使用していることを確認します。
Resources: MyCacheSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: "Lock cache down to webserver access only" SecurityGroupIngress: - IpProtocol: tcp FromPort: Fn::GetOptionSetting: OptionName: CachePort DefaultValue: 11211 ToPort: Fn::GetOptionSetting: OptionName: CachePort DefaultValue: 11211 SourceSecurityGroupName: Ref: AWSEBSecurityGroup MyElastiCache: Type: 'AWS::ElastiCache::CacheCluster' Properties: CacheNodeType: Fn::GetOptionSetting: OptionName: CacheNodeType DefaultValue: cache.t2.micro NumCacheNodes: Fn::GetOptionSetting: OptionName: NumCacheNodes DefaultValue: 1 Engine: Fn::GetOptionSetting: OptionName: Engine DefaultValue: redis VpcSecurityGroupIds: - Fn::GetAtt: - MyCacheSecurityGroup - GroupId AWSEBAutoScalingGroup : Metadata : ElastiCacheConfig : CacheName : Ref : MyElastiCache CacheSize : Fn::GetOptionSetting: OptionName : NumCacheNodes DefaultValue: 1 WebServerUser : Type : AWS::IAM::User Properties : Path : "/" Policies: - PolicyName: root PolicyDocument : Statement : - Effect : Allow Action : - cloudformation:DescribeStackResource - cloudformation:ListStackResources - elasticache:DescribeCacheClusters Resource : "*" WebServerKeys : Type : AWS::IAM::AccessKey Properties : UserName : Ref: WebServerUser Outputs: WebsiteURL: Description: sample output only here to show inline string function parsing Value: | http://`{ "Fn::GetAtt" : [ "AWSEBLoadBalancer", "DNSName" ] }` MyElastiCacheName: Description: Name of the elasticache Value: Ref : MyElastiCache NumCacheNodes: Description: Number of cache nodes in MyElastiCache Value: Fn::GetOptionSetting: OptionName : NumCacheNodes DefaultValue: 1 files: "/etc/cfn/cfn-credentials" : content : | AWSAccessKeyId=`{ "Ref" : "WebServerKeys" }` AWSSecretKey=`{ "Fn::GetAtt" : ["WebServerKeys", "SecretAccessKey"] }` mode : "000400" owner : root group : root "/etc/cfn/get-cache-nodes" : content : | # Define environment variables for command line tools export AWS_ELASTICACHE_HOME="/home/ec2-user/elasticache/$(ls /home/ec2-user/elasticache/)" export AWS_CLOUDFORMATION_HOME=/opt/aws/apitools/cfn export PATH=$AWS_CLOUDFORMATION_HOME/bin:$AWS_ELASTICACHE_HOME/bin:$PATH export AWS_CREDENTIAL_FILE=/etc/cfn/cfn-credentials export JAVA_HOME=/usr/lib/jvm/jre # Grab the Cache node names and configure the PHP page aws cloudformation list-stack-resources --stack `{ "Ref" : "AWS::StackName" }` --region `{ "Ref" : "AWS::Region" }` --output text | grep MyElastiCache | awk '{print $4}' | xargs -I {} aws elasticache describe-cache-clusters --cache-cluster-id {} --region `{ "Ref" : "AWS::Region" }` --show-cache-node-info --output text | grep '^ENDPOINT' | awk '{print $2 ":" $3}' > `{ "Fn::GetOptionSetting" : { "OptionName" : "NodeListPath", "DefaultValue" : "/var/www/html/nodelist" } }` mode : "000500" owner : root group : root "/etc/cfn/hooks.d/cfn-cache-change.conf" : "content": | [cfn-cache-size-change] triggers=post.update path=Resources.AWSEBAutoScalingGroup.Metadata.ElastiCacheConfig action=/etc/cfn/get-cache-nodes runas=root sources : "/home/ec2-user/elasticache" : "https://elasticache-downloads.s3.amazonaws.com/AmazonElastiCacheCli-latest.zip" commands: make-elasticache-executable: command: chmod -R ugo+x /home/ec2-user/elasticache/*/bin/* packages : "yum" : "aws-apitools-cfn" : [] container_commands: initial_cache_nodes: command: /etc/cfn/get-cache-nodes
-
ローカルコンピュータに次のスニペットを使用して設定ファイル
nodejs-example-express-elasticache/.ebextensions/elasticache_settings.config
を作成し、ElastiCache を設定します。option_settings: "aws:elasticbeanstalk:customoption": CacheNodeType: cache.t2.micro NumCacheNodes: 1 Engine: memcached NodeListPath: /var/nodelist
-
ローカルコンピュータで、
nodejs-example-express-elasticache/express-app.js
を次のスニペットに置き換えます。このファイルでは、ディスクからノードリストを読み取り(/var/nodelist
)、ノードが存在する場合はmemcached
をセッションを保存するとして使用するよう Express を設定します。ファイルは次のようになります。/** * Module dependencies. */ var express = require('express'), session = require('express-session'), bodyParser = require('body-parser'), methodOverride = require('method-override'), cookieParser = require('cookie-parser'), fs = require('fs'), filename = '/var/nodelist', app = module.exports = express(); var MemcachedStore = require('connect-memcached')(session); function setup(cacheNodes) { app.use(bodyParser.raw()); app.use(methodOverride()); if (cacheNodes) { app.use(cookieParser()); console.log('Using memcached store nodes:'); console.log(cacheNodes); app.use(session({ secret: 'your secret here', resave: false, saveUninitialized: false, store: new MemcachedStore({'hosts': cacheNodes}) })); } else { console.log('Not using memcached store.'); app.use(cookieParser('your secret here')); app.use(session()); } app.get('/', function(req, resp){ if (req.session.views) { req.session.views++ resp.setHeader('Content-Type', 'text/html') resp.write('Views: ' + req.session.views) resp.end() } else { req.session.views = 1 resp.end('Refresh the page!') } }); if (!module.parent) { console.log('Running express without cluster.'); app.listen(process.env.PORT || 5000); } } // Load elasticache configuration. fs.readFile(filename, 'UTF8', function(err, data) { if (err) throw err; var cacheNodes = []; if (data) { var lines = data.split('\n'); for (var i = 0 ; i < lines.length ; i++) { if (lines[i].length > 0) { cacheNodes.push(lines[i]); } } } setup(cacheNodes); });
-
ローカルコンピュータで、
package.json
を次の内容で更新します。"dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", "express": "~4.16.1", "http-errors": "~1.6.3", "jade": "~1.11.0", "morgan": "~1.9.1", "connect-memcached": "*", "express-session": "*", "body-parser": "*", "method-override": "*" }
-
npm install を実行します。
~/nodejs-example-express-elasticache$
npm install
-
更新したアプリケーションをデプロイします。
~/nodejs-example-express-elasticache$
eb deploy
-
数分後、環境が更新されます。環境が緑色で示され準備が完了したら、コードが機能することを確認します。
-
Amazon CloudWatch コンソール
をチェックして、 ElastiCache メトリクスを表示します。ElastiCache メトリクスを表示するには、左ペインで [Metrics (メトリクス)] を選択し、[CurrItems] を検索します。[ElastiCache> Cache Node Metrics] を選択したら、キャッシュノードを選択してキャッシュ内の項目数を表示します。 注記
アプリケーションのデプロイ先と同じリージョンを調べていることを確認してください。
アプリケーション URL をコピーして別のウェブ・ブラウザに貼り付け、ページを更新した場合、5 分後に CurrItem カウントが上がります。
-
ログのスナップショットを取得します。ログの取得の詳細については、「Elastic Beanstalk 環境の Amazon EC2インスタンスからのログの表示」を参照してください。
-
ログバンドルの
/var/log/nodejs/nodejs.log
ファイルをチェックします。次のような結果が表示されます。Using memcached store nodes: [ 'aws-my-1oys9co8zt1uo.1iwtrn.0001.use1.cache.amazonaws.com:11211' ]
-
クリーンアップ
アプリケーションを実行したくない場合は、環境を終了し、アプリケーションを削除してクリーンアップできます。
環境を終了するには eb terminate
コマンドを、アプリケーションを削除するには eb delete
コマンドを使用します。
環境を終了するには
ローカルリポジトリを作成したディレクトリから、eb terminate
を実行します。
$ eb terminate
このプロセスには数分かかることがあります。環境が正常に終了すると、Elastic Beanstalk にメッセージが表示されます。