iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
Cloud Native

30 天學習 Pulumi:用各種程式語言控制雲端資源系列 第 29

[Day 29] AWSx (Pulumi Crosswalk for AWS) 介紹

  • 分享至 

  • xImage
  •  

AWSx (Pulumi Crosswalk for AWS)

AWSx 是 Pulumi 官方根據 AWS 最佳實務與 well-architected 所提供的套件,主要是將 AWS Provider 再包裝,提供比較高階的 Component Resource。有點像是 Terraform 的 module 或是 AWS CDK 的 L3 Constrcut 的角色。

使用 awsx.ec2.Vpc 建立 AWS 基礎建設

在之前的實戰練習中,練習自己包裝製作 Vpc Component Resource 來簡化建立 AWS Infrastructure 的流程。

其實建立 AWS Infrastructure 這功能是很常見的需求,AWS 也有最佳實務,所以在 AWSx 中也有提供建立整套 AWS Infrastructure 的 Component Resource —— awsx.ec2.Vpc

以下是使用 awsx.ec2.Vpc 的範例:

const vpc = new awsx.ec2.Vpc('vpc', {
    cidrBlock: '10.120.0.0/16',
    natGateways: {
        strategy: 'Single'
    },
    numberOfAvailabilityZones: 2,
});

短短 7 行的程式碼,就可以建立 22 個資源,包含 2 個 Public Subnet、2 個 Private Subnet,並設定對應的路由表與路由。

     Type                                          Name            Plan
     pulumi:pulumi:Stack                           day29-awsx-dev
 +   └─ awsx:ec2:Vpc                               vpc             create
 +      └─ aws:ec2:Vpc                             vpc             create
 +         ├─ aws:ec2:Subnet                       vpc-private-1   create
 +         │  └─ aws:ec2:RouteTable                vpc-private-1   create
 +         │     ├─ aws:ec2:RouteTableAssociation  vpc-private-1   create
 +         │     └─ aws:ec2:Route                  vpc-private-1   create
 +         ├─ aws:ec2:InternetGateway              vpc             create
 +         ├─ aws:ec2:Subnet                       vpc-public-1    create
 +         │  ├─ aws:ec2:Eip                       vpc-1           create
 +         │  ├─ aws:ec2:RouteTable                vpc-public-1    create
 +         │  │  ├─ aws:ec2:RouteTableAssociation  vpc-public-1    create
 +         │  │  └─ aws:ec2:Route                  vpc-public-1    create
 +         │  └─ aws:ec2:NatGateway                vpc-1           create
 +         ├─ aws:ec2:Subnet                       vpc-private-2   create
 +         │  └─ aws:ec2:RouteTable                vpc-private-2   create
 +         │     ├─ aws:ec2:RouteTableAssociation  vpc-private-2   create
 +         │     └─ aws:ec2:Route                  vpc-private-2   create
 +         └─ aws:ec2:Subnet                       vpc-public-2    create
 +            └─ aws:ec2:RouteTable                vpc-public-2    create
 +               ├─ aws:ec2:RouteTableAssociation  vpc-public-2    create
 +               └─ aws:ec2:Route                  vpc-public-2    create

除了 Vpc 以外,AWSx 還有提供很多其他的 Component Resource,可以到以下這些 package 的文件中查詢。

Lambda

今天的最後,要介紹一個 Pulumi 中滿特別的功能,可以將 Lambda 與 IaC 程式結合在一起。

如何結合呢?我們先來看一個範例:

const bucket = new aws.s3.Bucket('my-bucket');
bucket.onObjectCreated('log-object', new aws.lambda.CallbackFunction<aws.s3.BucketEvent, void>('onObjectCreated', {
    callback: async (event) => {
        console.log(event);
    }
}));

這個程式碼除了建立了 S3 Bucket 以外,還設定了 s3 notificaiton,當物件被建立時,會執行一個 Lambda。而這個 Lambda 就是直接定義在 onObjectCreated 方法中所傳入的 Lambda 資源中。
這個資源特殊的地方就在於,是將 Lambda 的程式碼寫在 Pulumi IaC 程式中。方便的地方在於不需將 Lambda 放置於其他資料夾,也不需處理打包的問題。Pulumi runtime 在執行的時候,會自動分析 callback 中所使用到的程式碼相依性,並將相關的相依性打包、提取 Callback 的內容、打包成 zip,最後建立 Lambda 資源。

不過可惜的是,這個功能目前只能在 TypeScript 語言中使用。且支援 aws.lambda.CallbackFunction 的事件也很有限。官方文件中有列出支援的 11 種事件。

範例:圖片上傳至 S3 自動產生縮圖

接著來做一個範例,是當有圖片上傳至 S3 時,可以自動使用 Lambda 產生縮圖。

一開始,先建立兩個 bucket,一個用來儲存原圖,一個儲存縮圖。

const bucket = new aws.s3.Bucket('image-bucket');
const processedBucket = new aws.s3.Bucket('processed-image-bucket');

接著,註冊 onObjectCreated 事件,設定要執行的 Lambda 函式。因為要在 Lambda 中讀寫 S3 Bucket 內的檔案,因此需要設定 Lambda 相關的 Policy。這邊為了方便就直接給 FullAccess,正常來說,應該要使用 IAM 資源,建立專屬的 Policy。

import {S3Client, GetObjectCommand, PutObjectCommand} from "@aws-sdk/client-s3";
import * as Jimp from 'jimp';

bucket.onObjectCreated('resize-image', new aws.lambda.CallbackFunction<aws.s3.BucketEvent, void>('onObjectCreated', {
    policies: [
        aws.iam.ManagedPolicy.AWSLambdaExecute,
        aws.iam.ManagedPolicy.AmazonS3FullAccess
    ],
    memorySize: 1024,
    timeout: 300,
    callback: async (event) => {

    }
}, {parent: bucket}));

最後在 callback 內,就是使用 aws-js SDK 內的 S3Client 下載圖片,並利用 Jimp 套件製作圖片縮圖,最後將縮圖上傳至另一個 bucket 中。

await Promise.all(event.Records.map(async (record) => {
    // S3 檔案的路徑
    const file = record.s3.object.key;
    
    // 下載圖片檔
    const s3client = new S3Client();
    const data = await s3client.send(new GetObjectCommand({
        Bucket: bucket.id.get(),
        Key: file
    }));
    const bytes = await data.Body.transformToByteArray();
    
    // 使用 Jimp 轉檔
    return Jimp.read(Buffer.from(bytes), async (err, image) => {
        if (err) {
            console.log(err);
            return;
        }

        // 產生縮圖,最大的寬高為 200
        return await image.resize(200, Jimp.AUTO)
            .getBufferAsync(Jimp.MIME_JPEG)
            .then(async (data) => {
                // 上傳至另一個 S3 Bucket
                return s3client.send(new PutObjectCommand({
                    Bucket: processedBucket.id.get(),
                    Key: file,
                    Body: data
                }));
            });
    });
}));

設定完以後,執行 pulumi up 就能看到所建立的資源列表。雖然程式中只有建立 2 個 bucket 與一個 Lambda,但其實背後會建立這麼多資源!

$ pulumi up
Previewing update (dev)

     Type                                  Name                    Plan
 +   pulumi:pulumi:Stack                   day29-awsx-dev          create
 +   ├─ aws:s3:Bucket                      processed-image-bucket  create
 +   └─ aws:s3:Bucket                      image-bucket            create
 +      ├─ aws:iam:Role                    resize-image            create
 +      ├─ aws:s3:BucketEventSubscription  resize-image            create
 +      │  └─ aws:lambda:Permission        resize-image            create
 +      ├─ aws:iam:RolePolicyAttachment    resize-image-4aaabb8e   create
 +      ├─ aws:iam:RolePolicyAttachment    resize-image-aadec3c3   create
 +      ├─ aws:lambda:Function             resize-image            create
 +      └─ aws:s3:BucketNotification       resize-image            create

小結

不知道是不是因為 Pulumi 的創始團隊有 AWS 前員工的關係,Pulumi 與 AWS 的整合做的滿深入的,今天介紹的功能 Pulumi 就沒有做在其他 Provider 中。

Reference


上一篇
[Day 28] Pulumi 的 Policy as Code
下一篇
[Day 30] 整合 SCM、CI/CD 工具
系列文
30 天學習 Pulumi:用各種程式語言控制雲端資源30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言