Lambdaを書くための、Dockerでテストしたり、デプロイまでをやってみった（PHP編）

## はじめに
はじめまして、香港出身のライです。
これは記念すべきのQiitaでの初投稿です。なにか参考できるや面白いだと思ってくるととても嬉しいです。

では早速、本題行きましょう。
最近の `AWS re:Invent 2018` に、Lambdaのカスタムランタイムはリリースされました。
なので、このブームを逃すわけではいけないので、自分もPHPのLambdaのカスタムランタイム環境を作ってみました。

~~PHP以外を書くつもりはなかったけど~~

## Requirement
### php-lambda-layer
https://github.com/stackery/php-lambda-layer

### aws-sam-cli
https://github.com/awslabs/aws-sam-cli

### Docker
https://www.docker.com/get-started

## lambda Layerを作る
1.  php-lambda-layer
2. Dockerを実行できる環境で `make php71.zip` を実行するだけで、  `php71.zip` を作ることができる
3. コンソールで、先作った `php71.zip` をアップし、lambdaのlayerを作る

### Extensions
下記はサポートする Extensions

```json.so
bz2.so
calendar.so
ctype.so
curl.so
dom.so
exif.so
fileinfo.so
ftp.so
gettext.so
iconv.so
json.so
phar.so
posix.so
shmop.so
simplexml.so
sockets.so
sysvmsg.so
sysvsem.so
sysvshm.so
tokenizer.so
wddx.so
xml.so
xmlreader.so
xmlwriter.so
xsl.so
zip.so
```

※ `make` をする前に、 `php.ini` に `extension=json.so` を入れる必要がある
※ 他の `extension` を入れることも可能です

## プロジェクト

```
├── Lambda_php
|     ├── template.yaml
|     ├── src
|     |    └── php
|     |       ├── index.php
|     |       └── print.php
|     └── test
|           └── php
|              └── indexTest.php
└── Dockerfile
```

適当に作った


## やってみる
### Dockerの環境を作る
layerと同じ環境の `php7.1` を入れ、 `phpunit` もインストールする

```Dockerfile
FROM lambci/lambda:build-nodejs8.10

WORKDIR /tmp
RUN yum install wget -y
RUN yum install -y php71-cli zip
RUN wget https://phar.phpunit.de/phpunit-6.5.phar
RUN chmod +x phpunit-6.5.phar
RUN mv phpunit-6.5.phar /usr/local/bin/phpunit
WORKDIR /srv
```

`docker build --tag lai:lambdatest .` でビルド

### 開発＆テスト
#### コーディング
いい感じに〜

```index.php
<?php
require dirname(__FILE__) . '/print.php';

$print = new PrintInfo();
echo $print->printNum();
```

```print.php
<?php
class PrintInfo {
    function printNum() {
        return 1;
    }
}
```

#### テストコード
こちらもいい感じに〜

```indexTest.php
<?php
require dirname(__FILE__) . '/../../src/php/print.php';

use PHPUnit\Framework\TestCase;

class IndexTest extends TestCase
{
    public function testFunction()
    {
        $print = new PrintInfo();
        $this->assertEquals(1, $print->printNum());
    }
}
```

#### テスト実行
`docker run --rm --volume ${PWD}/lambda_php:/srv lai:lambdatest /bin/bash -c "phpunit --verbose /srv/test/php/indexTest”`

```
PHPUnit 6.5.13 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.1.7

.                                                                   1 / 1 (100%)

Time: 118 ms, Memory: 8.00MB

OK (1 test, 1 assertion)
```

やった！

### デプロイ

```template.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: My PHP Application
Transform: AWS::Serverless-2016-10-31
Resources:
  phpserver:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub ${AWS::StackName}-phpserver
      Description: PHP Webserver
      CodeUri: src/php
      Runtime: provided
      Handler: index.php
      MemorySize: 3008
      Timeout: 30
      Tracing: Active
      Layers:
        - <先作ったlambda layerのARN>
      Events:
        api:
          Type: Api
          Properties:
            Path: /{proxy+}
            Method: ANY
```

`sam package --output-template-file serverless-output.yaml --s3-bucket <S3バケット名>`

`sam deploy --template-file serverless-output.yaml --stack-name <スタック名>  --capabilities CAPABILITY_IAM`

## アクセスしてみる
![スクリーンショット 2018-12-05 14.39.56.png](https://qiita-image-store.s3.amazonaws.com/0/309401/da7239d8-a8ca-2e94-3b60-ad55956fe721.png)


やった！

## 結論
lambdaはこれから、いろんな言語で書くことができる。
これは結構嬉しいアップデートですね。

次のプロジェクトはこれでいきたいですね（笑）。

というコピペ多い記事でした。

**もうコピペしない！**