ビルドAWSラムダのようなエクスプレスのようなアプリ
43990 ワード
ラムハープワールド例のような簡単な簡単な表現⚡ ☁️
私は最近、バックエンドの残りのアプリを構築し、いくつかの簡単なルートを経由してExpress 私のニーズを満たすために.Expressは、JavaScript/ノードの一般的に使用されるバックエンドです.js私は、AWSでこれを走らせたかったですLambda Serverlessなアーキテクチャを持つすべての利点のために.この記事は私が学んだことの結果です.あなたはこの例に従うことができなければならなくてAWS free tier .
私には2つの目標がありました. インフラストラクチャを作成し、管理したい. 私は、バックエンドのような単純な急行を使いたいです.
このHello Worldの例のJavaScript部分は、AWSサービスを作成して配線するためのTorraformであるコードのより多くで単純です.両方について以下に概説する.私も、この例のためにコードのすべてを持ちますmy GitHub .
あなたが必要Node.js インストールとAWS account .
lambda-api 提供するシンプルで軽量なソリューションは、誰もが時間を費やしているおなじみに見えるExpress . ソリューションを構築する
新しいノードプロジェクトを起動するnpm init .
インデックス.js
AWSラムダでこの仕事をするためには、APIゲートウェイを通してラムダを公開する必要があります.私はインフラストラクチャの構築、配備、削除を行うために、terraformを使いたかったです.これは、コード(IAC)としてインフラストラクチャとして知られています.テラフォームを使用すると、いくつかの利点があります. 構成だけでなく、オーケストレーション 不変のインフラストラクチャ 宣言的な手続きコードではない 作成、再作成、変更、またはインフラストラクチャの削除速度. このHello Worldの例を簡単にするために、私はローカルマシンを使用してterraform状態を保存しますがTerraform Cloud 実際のアプリケーションのインフラストラクチャ状態のストレージ.GitHubまたはリポジトリの選択にあなたの状態をアップロードしないでください.
クリエイトア
クリエイトア
プロバイダ.TF
クリエイトア
変数.TF
IAACを組織するためにモジュールを使用するつもりです.インサイド
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
フォルダ/モジュール/アーカイブフォルダで
メイン.TF
私たちはAWS IAM AWSサービスとリソースへのアクセスを安全に管理する.IAMを使用すると、AWSのユーザーとグループを作成し、管理でき、AWSリソースへのアクセスを許可し、拒否するアクセス許可を使用できます.
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
フォルダ/モジュール/iamフォルダで
メイン.TF
私たちはAWS Lambda プロビジョニングやサーバの管理なしにコードを実行するには.あなたが消費する計算時間だけを支払う.
ラムダを使用すると、ほぼすべての種類のアプリケーションまたはバックエンドサービスのコードを実行できます.ラムダは、高可用性でコードを実行し、スケールするために必要なすべての面倒を見ます.
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
モジュール/ラムダを作成する
変数.TF
フォルダ/モジュール/ラムダフォルダで
メイン.TF
ホームストレッチ、そこにハングアップ.
私たちはAWS API Gateway RESTful APIを作成するにはAPIゲートウェイは、トラフィック管理、CORSサポート、認証およびアクセス制御、throttling、監視、およびAPIバージョン管理を含む同時のAPI呼び出しの何十万もの受け入れと処理を行うすべてのタスクを処理します.APIゲートウェイには、最低料金または起動コストがありません.あなたが受け取るAPIコールと転送されたデータの量を支払う.
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
ゲートウェイ/モジュール/APIゲートウェイで
変数.TF
フォルダ/モジュール/iamゲートウェイフォルダを作成する
メイン.TF
我々は、我々が一緒に作った地形の全てを結ぶ必要があります.フォルダフォームで
🎉 あなたは、これまでそれを作りました!あなたが作ったコードで遊びましょう!🎉
インフラストラクチャを展開するためにいくつかの地形コマンドを実行するつもりです.
あなたがこのterraform計画を適用することの上に動くことができるように、それは問題なしで働かなければなりません.
これをAで確認する必要があります
例えば、
開ける
今、我々はAPIを打つことができます🎉
私は楽しみました.私は少しの地形とRADノードについて学びました.JSパッケージlambda-api . 私が間違いを犯したならば、私はコメントのそれらを学ぶことが幸せであるということから学ぶことができます.あなたが質問をするならば、自由に尋ねてください.
何
私は最近、バックエンドの残りのアプリを構築し、いくつかの簡単なルートを経由してExpress 私のニーズを満たすために.Expressは、JavaScript/ノードの一般的に使用されるバックエンドです.js私は、AWSでこれを走らせたかったですLambda Serverlessなアーキテクチャを持つすべての利点のために.この記事は私が学んだことの結果です.あなたはこの例に従うことができなければならなくてAWS free tier .
私には2つの目標がありました.
仕事はいくらですか。
このHello Worldの例のJavaScript部分は、AWSサービスを作成して配線するためのTorraformであるコードのより多くで単純です.両方について以下に概説する.私も、この例のためにコードのすべてを持ちますmy GitHub .
必要条件
あなたが必要Node.js インストールとAWS account .
ラムダAPI
lambda-api 提供するシンプルで軽量なソリューションは、誰もが時間を費やしているおなじみに見えるExpress . ソリューションを構築する
lambda-api
28 KBで小さい単一の依存性解決を提供します.新しいノードプロジェクトを起動するnpm init .
npm init
インストールlambda-api
npm install lambda-api
インデックスを作成します.このコンテンツをプロジェクトにJSファイル.インデックス.js
// Require the framework and instantiate it
const api = require("lambda-api")()
// Define a route
api.get("/", async (req, res) => {
console.log("hello world")
return "hello world"
})
api.get("/foo", async (req, res) => {
console.log("/foo hit")
return "/foo hit"
})
api.get("/bar", async (req, res) => {
console.log("/bar hit")
return "/bar hit"
})
// Declare your Lambda handler
exports.handler = async (event, context) => {
return await api.run(event, context)
}
lambda-api
ルート経由で簡単になりますget()
, post()
, put()
いくつかのオプションを指定します.地形
AWSラムダでこの仕事をするためには、APIゲートウェイを通してラムダを公開する必要があります.私はインフラストラクチャの構築、配備、削除を行うために、terraformを使いたかったです.これは、コード(IAC)としてインフラストラクチャとして知られています.テラフォームを使用すると、いくつかの利点があります.
クリエイトア
terraform
プロジェクトのフォルダ.そのフォルダでterraform init
Torraform設定ファイルを含む作業ディレクトリを初期化する.これは、新しい地形の構成を書いた後、またはバージョン管理から既存のものをクローニングした後に実行されるべき最初のコマンドです.このコマンドを複数回実行することは安全です.プロバイダ。TF
クリエイトア
provider.tf
この内容のファイル.プロバイダ.TF
provider "aws" {
version = "~> 3.0"
region = var.aws-region
}
変数。TF
クリエイトア
variables.tf
この内容のファイル.変数.TF
variable "aws-region" {
description = "AWS region for the infrastructure"
type = string
default = "us-east-1"
}
モジュール
IAACを組織するためにモジュールを使用するつもりです.インサイド
terraform
フォルダを作成modules
フォルダ.その中にモジュールをたくさん作成します.アーカイブファイル
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
archive
.フォルダ/モジュール/アーカイブフォルダで
main.tf
この内容のファイル.メイン.TF
data "archive_file" "placeholder" {
type = "zip"
output_path = "${path.module}/lambda-function-payload.zip"
source {
content = "placeholder"
filename = "placeholder.txt"
}
}
output "data-archive-file-placeholder-output-path" {
value = data.archive_file.placeholder.output_path
}
使用するarchive_file
ファイルの内容、ファイル、ディレクトリからアーカイブを生成します.以下のラムダを作成する際に使用するプレースホルダテキストファイルを保持します.これは、CI/CDパイプラインの展開段階でコードの展開からインフラストラクチャの作成、更新、および削除を分離するために行われます.ああ、きれいなseperation🎉!IAM
私たちはAWS IAM AWSサービスとリソースへのアクセスを安全に管理する.IAMを使用すると、AWSのユーザーとグループを作成し、管理でき、AWSリソースへのアクセスを許可し、拒否するアクセス許可を使用できます.
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
iam
.フォルダ/モジュール/iamフォルダで
main.tf
この内容のファイル.メイン.TF
resource "aws_iam_role" "express-like-lambda-example" {
name = "express-like-lambda-example"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": {
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow"
}
}
POLICY
}
resource "aws_iam_policy" "express-like-lambda-example-logs" {
name = "express-like-lambda-example-logs"
description = "Adds logging access"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "attach-logs" {
role = aws_iam_role.express-like-lambda-example.name
policy_arn = aws_iam_policy.express-like-lambda-example-logs.arn
}
output "aws-iam-role-express-like-lambda-example-arn" {
value = aws_iam_role.express-like-lambda-example.arn
}
The aws_iam_role
express-like-lambda-example
使用するラムダの役割を設定します.その後、我々はaws_iam_policy
express-like-lambda-example-logs
これはラムダへのアクセスをログに追加します.私たちはaws_iam_role_policy_attachment
呼ばれるattach-logs
ポリシーをロールにアタッチします.最後に、出力するarn 他のモジュールで使用する役割の少し後に.ラメラ
私たちはAWS Lambda プロビジョニングやサーバの管理なしにコードを実行するには.あなたが消費する計算時間だけを支払う.
ラムダを使用すると、ほぼすべての種類のアプリケーションまたはバックエンドサービスのコードを実行できます.ラムダは、高可用性でコードを実行し、スケールするために必要なすべての面倒を見ます.
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
lambda
.モジュール/ラムダを作成する
variables.tf
この内容のファイル.変数.TF
variable "aws-iam-role-express-like-lambda-example-arn" {
description = "IAM role ARN"
type = string
}
variable "data-archive-file-placeholder-output-path" {
description = "Placeholder content for Lambda"
type = string
}
最初の変数はarn
のiam
role
上から.番目の変数はarchive
上記からのファイル.この例ではラムダを作成する必要があります.フォルダ/モジュール/ラムダフォルダで
main.tf
この内容のファイル.メイン.TF
resource "aws_lambda_function" "express-like-lambda-example" {
filename = var.data-archive-file-placeholder-output-path
function_name = "express-like-lambda-example"
handler = "index.handler"
role = var.aws-iam-role-express-like-lambda-example-arn
runtime = "nodejs12.x"
memory_size = 128
timeout = 1
}
resource "aws_lambda_function_event_invoke_config" "express-like-lambda-example-event-invoke-config" {
function_name = aws_lambda_function.express-like-lambda-example.arn
maximum_event_age_in_seconds = 60
maximum_retry_attempts = 0
}
resource "aws_lambda_permission" "express-like-lambda-example" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.express-like-lambda-example.arn
principal = "apigateway.amazonaws.com"
}
output "aws-lambda-function-express-like-lambda-example-arn" {
value = aws_lambda_function.express-like-lambda-example.arn
}
output "aws-lambda-function-express-like-lambda-example-invoke-arn" {
value = aws_lambda_function.express-like-lambda-example.invoke_arn
}
The aws_lambda_function
express-like-lambda-example
ラムダ関数を作成します.The filename
使用するのはarchive
terraform/modules/lambda/変数で定義されている変数を使うことで.tf.The aws_lambda_function_event_invoke_config
express-like-lambda-example-event-invoke-config
関数を実行できるようにするために秒単位で最大値を定義することができます.The aws_lambda_permission
express-like-lambda-example
ラムダをAPIゲートウェイ経由で実行することができます.最後に、出力ラムダarn
and invoke_arn
APIゲートウェイを設定するときに使用します.ゲートウェイ
ホームストレッチ、そこにハングアップ.
私たちはAWS API Gateway RESTful APIを作成するにはAPIゲートウェイは、トラフィック管理、CORSサポート、認証およびアクセス制御、throttling、監視、およびAPIバージョン管理を含む同時のAPI呼び出しの何十万もの受け入れと処理を行うすべてのタスクを処理します.APIゲートウェイには、最低料金または起動コストがありません.あなたが受け取るAPIコールと転送されたデータの量を支払う.
terraform/modulesフォルダの内部にあるフォルダを作成しましょう
api-gateway
.ゲートウェイ/モジュール/APIゲートウェイで
variables.tf
この内容のファイル.変数.TF
variable "aws-lambda-function-express-like-lambda-example-arn" {
description = "express-like-lambda-example Lambda ARN"
type = string
}
variable "aws-lambda-function-express-like-lambda-example-invoke-arn" {
description = "express-like-lambda-example Lambda invoke ARN"
type = string
}
最初の変数はarn
そして、2番目はラムダを指定するinvoke_arn
.フォルダ/モジュール/iamゲートウェイフォルダを作成する
main.tf
この内容のファイル.メイン.TF
resource "aws_api_gateway_rest_api" "express-like-lambda-example" {
name = "express-like-lambda-example"
}
resource "aws_api_gateway_method" "proxy-root" {
rest_api_id = aws_api_gateway_rest_api.express-like-lambda-example.id
resource_id = aws_api_gateway_rest_api.express-like-lambda-example.root_resource_id
http_method = "ANY"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "express-like-lambda-example" {
rest_api_id = aws_api_gateway_rest_api.express-like-lambda-example.id
resource_id = aws_api_gateway_method.proxy-root.resource_id
http_method = aws_api_gateway_method.proxy-root.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = var.aws-lambda-function-express-like-lambda-example-invoke-arn
}
resource "aws_api_gateway_resource" "proxy" {
rest_api_id = aws_api_gateway_rest_api.express-like-lambda-example.id
parent_id = aws_api_gateway_rest_api.express-like-lambda-example.root_resource_id
path_part = "{proxy+}"
}
resource "aws_api_gateway_method" "proxy" {
rest_api_id = aws_api_gateway_rest_api.express-like-lambda-example.id
resource_id = aws_api_gateway_resource.proxy.id
http_method = "ANY"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "lambda" {
rest_api_id = aws_api_gateway_rest_api.express-like-lambda-example.id
resource_id = aws_api_gateway_method.proxy.resource_id
http_method = aws_api_gateway_method.proxy.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = var.aws-lambda-function-express-like-lambda-example-invoke-arn
}
resource "aws_api_gateway_deployment" "express-like-lambda-example_v1" {
depends_on = [
aws_api_gateway_integration.express-like-lambda-example
]
rest_api_id = aws_api_gateway_rest_api.express-like-lambda-example.id
stage_name = "v1"
}
output "endpoint" {
value = aws_api_gateway_deployment.express-like-lambda-example_v1.invoke_url
}
ここでは、APIリクエストの詳細をラムダ関数のイベントパラメータとして渡すことができるAPIゲートウェイのラムダプロキシ統合オプションを設定します.lambda-api
自動的にこの情報を解析し、正規化されたリクエストオブジェクトを作成します.リクエストはlambda-api
'sメソッド.aws_api_gateway_rest_api
APIゲートウェイREST APIを提供します.aws_api_gateway_method
APIゲートウェイリソースのHTTPメソッドを提供します.aws_api_gateway_integration
APIゲートウェイ統合のためのHTTPメソッド統合を提供します.aws_api_gateway_resource
APIゲートウェイリソースを提供します.aws_api_gateway_deployment
APIゲートウェイレスト展開を提供します.最後に、APIを呼び出すためにURLを出力します.メイン.TF
我々は、我々が一緒に作った地形の全てを結ぶ必要があります.フォルダフォームで
main.tf
この内容のファイル.module "archive" {
source = "./modules/archive"
}
module "iam" {
source = "./modules/iam"
}
module "lambda" {
source = "./modules/lambda"
data-archive-file-placeholder-output-path = module.archive.data-archive-file-placeholder-output-path
aws-iam-role-express-like-lambda-example-arn = module.iam.aws-iam-role-express-like-lambda-example-arn
}
module "api-gateway" {
source = "./modules/api-gateway"
aws-lambda-function-express-like-lambda-example-arn = module.lambda.aws-lambda-function-express-like-lambda-example-arn
aws-lambda-function-express-like-lambda-example-invoke-arn = module.lambda.aws-lambda-function-express-like-lambda-example-invoke-arn
}
# Set the generated URL as an output. Run `terraform output url` to get this.
output "endpoint" {
value = module.api-gateway.endpoint
}
これは、私たちが書いたモジュールの全てをまとめており、terraformで宣言的なインフラストラクチャを完成させます.コードの実行
インフラストラクチャの配備
🎉 あなたは、これまでそれを作りました!あなたが作ったコードで遊びましょう!🎉
インフラストラクチャを展開するためにいくつかの地形コマンドを実行するつもりです.
terraform plan
terraform planコマンドは実行計画を作成するために使用されます.このコマンドは、変更のセットの実行計画が実際のリソースや状態に変更を加えることなく、期待に一致するかどうかをチェックする便利な方法です.あなたがこのterraform計画を適用することの上に動くことができるように、それは問題なしで働かなければなりません.
terraform apply
The terraform apply
コマンドは、構成の望ましい状態に到達するために必要な変更を適用するために使用されるか、またはterraform plan
施工計画.これをAで確認する必要があります
yes
を返します.あなたが入力する前に何を作成するかを読む時間をくださいyes
. それは何が作成されることを示します.例えば、
terraform apply
...
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
module.iam.aws_iam_policy.express-like-lambda-example-logs: Creating...
module.iam.aws_iam_role.express-like-lambda-example: Creating...
module.api-gateway.aws_api_gateway_rest_api.express-like-lambda-example: Creating...
module.iam.aws_iam_role.express-like-lambda-example: Creation complete after 0s [id=express-like-lambda-example]
module.lambda.aws_lambda_function.express-like-lambda-example: Creating...
module.iam.aws_iam_policy.express-like-lambda-example-logs: Creation complete after 1s [id=arn:aws:iam::REDACTED:policy/express-like-lambda-example-logs]
module.api-gateway.aws_api_gateway_rest_api.express-like-lambda-example: Creation complete after 1s [id=REDACTED]
module.iam.aws_iam_role_policy_attachment.attach-logs: Creating...
module.api-gateway.aws_api_gateway_resource.proxy: Creating...
module.api-gateway.aws_api_gateway_method.proxy-root: Creating...
module.api-gateway.aws_api_gateway_method.proxy-root: Creation complete after 0s [id=REDACTED-ANY]
module.iam.aws_iam_role_policy_attachment.attach-logs: Creation complete after 0s [id=express-like-lambda-example-REDACTED]
module.api-gateway.aws_api_gateway_resource.proxy: Creation complete after 1s [id=REDACTED]
module.api-gateway.aws_api_gateway_method.proxy: Creating...
module.api-gateway.aws_api_gateway_method.proxy: Creation complete after 0s [id=REDACTED-ANY]
module.lambda.aws_lambda_function.express-like-lambda-example: Still creating... [10s elapsed]
module.lambda.aws_lambda_function.express-like-lambda-example: Creation complete after 16s [id=express-like-lambda-example]
module.lambda.aws_lambda_permission.express-like-lambda-example: Creating...
module.lambda.aws_lambda_function_event_invoke_config.express-like-lambda-example-event-invoke-config: Creating...
module.api-gateway.aws_api_gateway_integration.lambda: Creating...
module.api-gateway.aws_api_gateway_integration.express-like-lambda-example: Creating...
module.lambda.aws_lambda_permission.express-like-lambda-example: Creation complete after 0s [id=AllowAPIGatewayInvoke]
module.api-gateway.aws_api_gateway_integration.express-like-lambda-example: Creation complete after 0s [id=REDACTED-ANY]
module.api-gateway.aws_api_gateway_deployment.express-like-lambda-example_v1: Creating...
module.api-gateway.aws_api_gateway_integration.lambda: Creation complete after 0s [id=REDACTED-ANY]
module.lambda.aws_lambda_function_event_invoke_config.express-like-lambda-example-event-invoke-config: Creation complete after 0s [id=arn:aws:lambda:us-east-1:REDACTED:function:express-like-lambda-example]
module.api-gateway.aws_api_gateway_deployment.express-like-lambda-example_v1: Creation complete after 1s [id=REDACTED]
Apply complete! Resources: 13 added, 0 changed, 0 destroyed.
Outputs:
endpoint = https://REDACTED.execute-api.us-east-1.amazonaws.com/v1
ビットの使用のために出力から終点をコピーするか、覚えてください.アプリの配備
開ける
package.json
これを作成npm script ."scripts": {
"build": "npm install --production && rm -rf build && mkdir build && zip -r -q -x='*terraform*' -x='*.md' -x='LICENSE' -x='*build*' -x='*.DS_Store*' -x='*.git*' build/express-like-lambda-example.zip . && du -sh build"
},
プロジェクトのルートで、ビルドコマンドを実行して、作成したラムダに展開する準備ができました.npm run build
例えば、npm run build
> [email protected] build /Users/REDACTED/Development/express-like-lambda-example
> npm install --production && rm -rf build && mkdir build && zip -r -q -x='*media*' -x='*terraform*' -x=*coverage* -x='*.md' -x='LICENSE' -x='*build*' -x='*.DS_Store*' -x='*.git*' build/express-like-lambda-example.zip . && du -sh build
audited 1 package in 0.916s
found 0 vulnerabilities
28K build
今、我々はラムダに私たちのzipアプリを展開することができます.そのためにこのコマンドを使います.aws lambda update-function-code --function-name=express-like-lambda-example --zip-file=fileb://build/express-like-lambda-example.zip --region=us-east-1 1> /dev/null
APIの呼び出し
今、我々はAPIを打つことができます🎉
curl https://REDACTED.execute-api.us-east-1.amazonaws.com/v1
hello world
使用例curl https://REDACTED.execute-api.us-east-1.amazonaws.com/v1/foo
/foo hit
curl https://REDACTED.execute-api.us-east-1.amazonaws.com/v1/bar
/bar hit
curl https://REDACTED.execute-api.us-east-1.amazonaws.com/v1/baz
{"error":"Route not found"}
注意してください、あなたのURLは上記のものと異なります.それぞれの展開はユニークです.あなたのURLの出力から来るterraform apply
.結論
私は楽しみました.私は少しの地形とRADノードについて学びました.JSパッケージlambda-api . 私が間違いを犯したならば、私はコメントのそれらを学ぶことが幸せであるということから学ぶことができます.あなたが質問をするならば、自由に尋ねてください.
Reference
この問題について(ビルドAWSラムダのようなエクスプレスのようなアプリ), 我々は、より多くの情報をここで見つけました https://dev.to/cujarrett/build-an-express-like-app-on-aws-lambda-12g6テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol