page_adsence

2020年6月26日金曜日

AWS CDK と AWS SAM CLI を利用してローカル実行しようとしたらハマった件 Part2

前回、AWS CDK と AWS SAM CLI を使ってローカル開発環境を作っていたのですが、時間を置いて別の環境を作ろうと思ったら別のエラーでハマったのでメモしておきます。

前提

MacOSX         10.14.6(Mojave)
AWS CLI        2.0.19
AWS SAM CLI    0.52.0
AWS CDK        1.44.0 -> (1.47.0 に上げた)

この記事のゴール

下記のエラーを回避し、ローカル環境で Lambda が実行できていること。

発生したエラー

$ yarn run build
yarn run v1.22.0
warning package.json: No license field
warning ../package.json: No license field
$ tsc
bin/cdk-test.ts:4:10 - error TS2305: Module '"/path/to/dir/cdk-test/lib/cdk-test-stack"' has no exported member 'CdkTestStack'.

4 import { CdkTestStack } from '../lib/cdk-test-stack';
           ~~~~~~~~~~~~

lib/cdk-test-stack.ts:9:45 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'Construct'.
  Type 'CdkSampleStack' is not assignable to type 'Construct'.
    Property 'onValidate' is protected but type 'Construct' is not a class derived from 'Construct'.

9     const helloLambda = new lambda.Function(this, "helloLambda", {
                                              ~~~~

lib/cdk-test-stack.ts:16:45 - error TS2345: Argument of type 'this' is not assignable to parameter of type 'Construct'.

16     const helloApi = new apigateway.RestApi(this, "helloApi", {
                                               ~~~~

test/cdk-test.test.ts:8:31 - error TS2339: Property 'CdkTestStack' does not exist on type 'typeof import("/path/to/dir/cdk-test/lib/cdk-test-stack")'.

8     const stack = new CdkTest.CdkTestStack(app, 'MyTestStack');
                                ~~~~~~~~~~~~


Found 4 errors.

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

やったこと

$ cdk init --language typescript
$ yarn add @aws-cdk/aws-lambda @aws-cdk/aws-apigateway aws-lambda
$ yarn add -D @types/node @types/aws-lambda
$ vi lib/cdk-test-stack.ts

Stack の定義は下記のようにした。

import  *  as  lambda  from  '@aws-cdk/aws-lambda'
import  *  as  apigateway  from  '@aws-cdk/aws-apigateway'
import  *  as  cdk  from  '@aws-cdk/core';

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

    // Lambda
    const  helloLambda = new  lambda.Function(this, "helloLambda", {
      runtime:  lambda.Runtime.NODEJS_12_X,
      handler:  "index.handler",
      code:  lambda.Code.asset("src")
    });

    // API Gateway
    const  helloApi = new  apigateway.RestApi(this, "helloApi", {
      restApiName:  "helloApi"
    });

    const  samplesResource = helloApi.root.addResource("ping");
    const  getSamplesIntegration = new  apigateway.LambdaIntegration(helloLambda);
    samplesResource.addMethod("GET", getSamplesIntegration);
  }
}

直すためにやったこと

package.json 内の aws-cdk 関連のバージョンをあわせるように修正しました。

修正前

"devDependencies": {
  "@aws-cdk/assert": "1.44.0", <= ここのバージョンが古かった
  "@types/jest": "^25.2.1",
  "@types/node": "10.17.5",
  "aws-cdk": "1.44.0", <= ここのバージョンが古かった
  "jest": "^25.5.0",
  "ts-jest": "^25.3.1",
  "ts-node": "^8.1.0",
  "typescript": "~3.7.2"
},
"dependencies": {
  "@aws-cdk/aws-apigateway": "^1.47.0",
  "@aws-cdk/aws-lambda": "^1.47.0",
  "@aws-cdk/core": "1.44.0", <= ここのバージョンが古かった
  "aws-lambda": "^1.0.6",
  "source-map-support": "^0.5.16"
}

修正後

"devDependencies": {
  "@aws-cdk/assert": "^1.47.0",
  "@types/jest": "^25.2.1",
  "@types/node": "10.17.5",
  "aws-cdk": "^1.47.0",
  "jest": "^25.5.0",
  "ts-jest": "^25.3.1",
  "ts-node": "^8.1.0",
  "typescript": "~3.7.2"
},
"dependencies": {
  "@aws-cdk/aws-apigateway": "^1.47.0",
  "@aws-cdk/aws-lambda": "^1.47.0",
  "@aws-cdk/core": "^1.47.0",
  "aws-lambda": "^1.0.6",
  "source-map-support": "^0.5.16"
}

原因

正直最初は原因が全くわからず・・・。
ググってもピンポイントな記事は見つからず・・・。

とはいえ、少し前は問題なく動かすこと出来ていたので、一旦動いていた時のバージョンを下げてみたところ、ちゃんとビルドできるようになりました。

とりあえず動いたので、これで終わりにしようかと思っていたのですが、package.json の中身を見てみると、yarn add で追加した @aws-cdk/aws-apigateway@aws-cdk/aws-lambda のパッケージのバージョン(1.47.0)と、@aws-cdk/core のバージョン(1.44.0)があっていないことに気づきました。
もしかしてと思って、諸々のバージョンをあわせるような形で修正をしたら、きちんと最新のバージョンで動くようになりました。

私の環境では、cdk はグローバルにインストールしているのですが、ここのバージョンが古かったせいで、cdk init した際に生成される package.json のファイルのバージョンが古く、後から yarn add で追加したパッケージのバージョンは最新が追加され、バージョンの乖離が発生してしまっていたという状態でした。

今回の反省点

前回同様、インストールしたことに満足せず、きちんとバージョン確認します・・・。
反省点活かせてない。
仕事で使っているわけではないので、ついバージョンアップは怠けがち。

2020年6月7日日曜日

AWS CDK と AWS SAM CLI を利用して、API Gateway + Lambda をローカル実行しようとしたらハマった件

AWS CDK が使えるのかどうか試してみようと思ってハマった内容をメモとして残しておきます。

前提

MacOSX         10.14.6(Mojave)
AWS CLI        1.16.155
AWS SAM CLI    0.15.0 -> 0.52.0(バグの回避のためにバージョン上げた時のバージョン)
AWS CDK        1.44.0
Docker for Mac 2.3.0.3

この記事のゴール

下記のエラーを回避し、ローカル環境で Lambda が実行できていること。

発生したエラー

$ sam local start-api -t template.yaml --docker-network bridge
2020-06-07 10:52:59 Found credentials in shared credentials file: ~/.aws/credentials
Error: Template does not have any APIs connected to Lambda functions

やったこと

brew 経由で AWS SAM CLI をインストール

brew install aws-sam-cli

AWS CDK をインストール(AWSの公式を参考に)

npm install -g aws-cdk

クラメソさんの記事を参考に、API Gateway + Lambda をローカルで動かす準備をした。

直すためにやったこと

// pip 経由でインストールした aws-sam-cli を削除
$ pip uninstall aws-sam-cli

// シェル再起動
$ exec $SHELL -l

// sam コマンドがあるか確認。brew でインストールしたものが残っていそうなことは確認できた
$ which sam
/usr/local/bin/sam

// sam cli のバージョン確認
$ sam --version
SAM CLI, version 0.52.0

// 一応 brew 側のバージョンも確認
$ brew info aws-sam-cli
aws/tap/aws-sam-cli: stable 0.52.0 (bottled), HEAD
AWS SAM CLI 🐿 is a tool for local development and testing of Serverless applications

原因

AWS SAM CLI のバージョンが古かったことが原因だったっぽい。
最新のバージョンに上げたことで解消できた。

はっきりとした原因が発見できたわけではなく、いろんな記事を渡り歩いたらこの結論に至ったという形。

気づけたのは sam start-api ではなく sam local invoke を実行してみたら、nodejs12.X 系のランタイムはサポートしてないとか言われたので、aws-sam-cli のバージョン確認してみたらやたら古かった。
どうやらはるか昔に pip 経由でインストールした aws-sam-cli があり、そっちのパスが通っていたらしく、今回brew 経由でインストールした方は利用されなかった。

今回の反省点

インストールしたことに満足せず、きちんとバージョン確認します・・・。