AWS CLI を AWS CDK で構築した Lambda上で動かす

はじめに

AWS CDK を利用して、 Lambda 上で動かすことがあったので備忘録として残しておきます。
参考記事

1. 実装

1.1. 全体像

空の aws-cli-lambda フォルダ内で cdk init app --language typescript 実行した状態のファイル構成になります。
ここに実装を追加していきます。

aws-cli-lambda
├── bin
│   └── est-aws-cli-lambda.ts
├── lambda
│   └── lambda
│       └── lambda_function.py
├── lib
│   └── test-aws-cli-lambda-stack.ts
├── test
│   └── test-aws-cli-lambda.test.ts
├── cdk.json
├── .gitignore
├── .npmignore
├── cdk.json
├── jest.config.js
├── package-lock.json
├── package.json
└── tsconfig.json

1.2. AWS CDK の Stack の実装

AWS CLI を利用するために、 aws-cdk-lib/lambda_layer_awscli を利用します。
AWSコマンドのバイナリは /opt/awscli/aws にあリます。

lib/stack.ts

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as logs from 'aws-cdk-lib/aws-logs';
import { AwsCliLayer } from 'aws-cdk-lib/lambda-layer-awscli';

export class TestAwsCliLambdaStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const syncFunction = new lambda.Function(this, "s3-bucket-sync", {
      runtime: lambda.Runtime.PYTHON_3_9,
      architecture: lambda.Architecture.ARM_64,
      handler: 'lambda_function.lambda_handler',
      code: lambda.Code.fromAsset('lambda/python-aws-cli'),
      environment: {},
      timeout: cdk.Duration.minutes(5),
      memorySize: 128,
      logRetention: logs.RetentionDays.ONE_DAY,
    });
    syncFunction.addLayers(new AwsCliLayer(this, 'awscli-layer'));

  }
}

1.3 Lambda関数の実装

subprocess を利用して、コマンドを実行します。 lambda/python-aws-cli/lambda_handler.py に以下のように記述します。

import subprocess

def run_command(cmd):
    result = subprocess.run(
        cmd.split(" "),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT
    )
    return result.stdout.decode()

def lambda_handler(event, context):
    print(run_command('/opt/awscli/aws --version'))

おわりに

Lambda に CloudWatch Events を使って定期実行を行ったりすることで、cronのように使うなど用途は様々だと思います。
ほとんど環境構築のコードを書かずに作れるので、ぜひ使ってみてください。