不知道大家還記不記得在 Day 6 - AWS CDK 部署 Lambda 與 API Gateway 服務 (上) 的時候有說過要介紹 Lambda 串接 ALB,那時候因為還沒介紹 VPC,而我們已經介紹過 VPC 了,所以今天就來介紹它吧!
這次的 Lambda 與上次的大同小異,主要在於直接印出寫 API 的資訊
大家可以直接用這個網頁做 Debug 或是開發
檔案:lambda/index.js
exports.handler = async function (event) {
console.log("request:", JSON.stringify(event, undefined, 2));
return {
statusCode: 200,
headers: { "Content-Type": "text/html" },
body:
`<meta charset="utf-8">` +
`<h1><a href="https://ithelp.ithome.com.tw/users/20117701/ironman/3734" target="_blank">用 CDK 定義 AWS 架構 AWS Lambda!</a></h1>` +
`<p><a href="https://blog.clarence.tw/" target="_blank">https://blog.clarence.tw/</a></p>` +
`<p>Method: ${event.httpMethod}</p>` +
`<p>Path: ${event.path}</p>` +
`<p>Query: ${JSON.stringify(
event.queryStringParameters,
undefined,
2
)}</p>`,
};
};
在這邊 VPC 建立方法與之前教大家 EC2 建立機器的 VPC 相同,主要不同的地方在於我們把 targets 放入 new targets.LambdaTarget(lambdaFunction)
const vpc = new ec2.Vpc(this, "VPC", {
maxAzs: 3,
natGateways: 0,
});
const lambdaFunction = new lambda.Function(this, "lambda", {
runtime: lambda.Runtime.NODEJS_10_X,
handler: "index.handler",
code: lambda.Code.fromAsset("lambda"),
});
const lb = new elbv2.ApplicationLoadBalancer(this, "ALB", {
vpc,
internetFacing: true,
});
new cdk.CfnOutput(this, "ALBDomain", {
value: lb.loadBalancerDnsName,
});
const listener = lb.addListener("Listener", { port: 80 });
listener.addTargets("LambdaTarget", {
targets: [new targets.LambdaTarget(lambdaFunction)],
healthCheck: {
enabled: true,
},
});
我們這次拿到的 ALB Domain:http://cdklb-albae-1ixf52wqbsc7b-2018343058.us-west-2.elb.amazonaws.com/
拿到的資訊如下:
使用了 Lambda 串接 ALB 大家有注意到可以玩什麼不一樣的變化嗎?
就是可以把前天教的 ALB 串接 EC2 加上 ALB 串接 Lambda 做一個組合技拉!
如此應該滿好玩的!因為大家就可以是情況幫它們拆負載或是把用 Lambda 比較好寫的服務用 Lambda 寫,想要用 EC2 組合的服務放機器,做很多種變化。
話不多說現在就教大家怎麼做吧!
準備一下目標,我們希望目標 path 是 /api*
的全部導入 Lambda 而其他都給 EC2
如此我們會有兩個 Target 並且要切 path,而在 ALB 裡面如果設定 conditions
就需要給 priority
先來介紹一下 conditions
const listener = lb.addListener("Listener", { port: 80 });
listener.addTargets("LambdaTarget", {
priority: 1,
conditions: [elbv2.ListenerCondition.pathPatterns(["/api*"])],
targets: [new targets.LambdaTarget(lambdaFunction)],
healthCheck: {
enabled: true,
},
});
listener.addTargets("EC2Target", {
healthCheck: {
enabled: true,
path: "/phpinfo.php",
},
port: 80,
targets: [new targets.InstanceTarget(ec2Instance)],
});
拆散解釋大家可能會看不懂,所以我們還是把它整個整理一下吧!
const vpc = new ec2.Vpc(this, "VPC", {
maxAzs: 3,
natGateways: 0,
});
const lambdaFunction = new lambda.Function(this, "lambda", {
runtime: lambda.Runtime.NODEJS_10_X,
handler: "index.handler",
code: lambda.Code.fromAsset("lambda"),
});
const asset = new assets.Asset(this, "Asset", {
path: path.join(__dirname, "../", "ec2-config", "configure.sh"),
});
const ec2Instance = new ec2.Instance(this, "Instance", {
vpc,
instanceType: ec2.InstanceType.of(
ec2.InstanceClass.T3,
ec2.InstanceSize.NANO
),
machineImage: ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
}),
vpcSubnets: {
subnetType: ec2.SubnetType.PUBLIC,
},
keyName: "KeyPair",
});
const localPath = ec2Instance.userData.addS3DownloadCommand({
bucket: asset.bucket,
bucketKey: asset.s3ObjectKey,
});
ec2Instance.userData.addExecuteFileCommand({
filePath: localPath,
arguments: "--verbose -y",
});
asset.grantRead(ec2Instance.role);
const lb = new elbv2.ApplicationLoadBalancer(this, "ALB", {
vpc,
internetFacing: true,
});
new cdk.CfnOutput(this, "ALBDomain", {
value: lb.loadBalancerDnsName,
});
const listener = lb.addListener("Listener", { port: 80 });
listener.addTargets("LambdaTarget", {
priority: 1,
conditions: [elbv2.ListenerCondition.pathPatterns(["/api*"])],
targets: [new targets.LambdaTarget(lambdaFunction)],
healthCheck: {
enabled: true,
},
});
listener.addTargets("EC2Target", {
healthCheck: {
enabled: true,
path: "/phpinfo.php",
},
port: 80,
targets: [new targets.InstanceTarget(ec2Instance)],
});
listener.connections.allowTo(ec2Instance, ec2.Port.tcp(80));
event.path
取得它
以上為今日的 Application Load Balancer 與 Lambda 整合介紹,希望有幫助到大家
文章內容主要是網路或是程式開發類型的文章
本文同步刊載於 Clarence 部落格:Day 16 - 要串接 API 除了 API Gateway 你還有另外的選擇 Application Load Balancer
「AWS CDK 完全學習手冊:打造雲端基礎架構程式碼 IaC」
本書改編並延伸自第 12 屆 iT 邦幫忙鐵人賽獲得 DevOps 組冠軍的《用 CDK 定義 AWS 架構》系列文章,以簡單、好讀的行文風格詳述技術細節,並提供完整的程式碼範例與說明,一步一步帶領新手從零開始踏上 AWS CDK 技術達人之路。有興趣的朋友歡迎至天瓏書局選購!