API Gateway ＆ Lambdaを利用してServerlessにJIRAチケット作成

#はじめに
社内用問い合わせフォームを刷新するにあたり、今までGoogleフォームで行っていたものをAWSへ移管することにしました。
その作業の備忘録です。

#システム構成図
<img width="1314" alt="スクリーンショット 2019-07-12 18.26.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/32a66e88-2c3f-b7f5-6748-43a676804003.png">


#本記事のスコープ
メインは**API Gateway**・**Lambda（Python3.7）**・**JIRA API**の連携についてです。
S3には入力フォーム用のファイルを置き、API GatewayへPOSTでリクエストするだけなので今回の記事からは割愛します。
また、VPC・NATゲートウェイについても本記事では触れないので他の方の記事を参考にしてください。


#1. Lambda Functionの作成
API Gateway作成時に指定する必要があるのでまずこちらから作成します。
###1-1. ローカル環境構築
JIRAチケット作成のためにJIRAモジュールを入れる必要があります。またJIRAモジュールを入れるためにpipを使いたいのですが、Python3系にpipが無いので別途入れています。
※dockerは予めインストールお願いします

```
$ mkdir jira_function
$ cd jira_function
$ docker run --rm -it -v `pwd`:/lambda amazonlinux /bin/bash
# yum -y install vi zip gcc python3-devel zlib-devel libffi-devel
# curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
# python3 get-pip.py
# pip install jira -t /lambda
# exit
```

###1-2. jira_function.pyの作成
1-1で作成したjira_functionディレクトリ配下に作成します。

```python:jira_function.py
# -*- coding: utf-8 -*
from jira import JIRA
from jira.exceptions import JIRAError
import json
import os
import requests
 
def jira_handler(event, context):
 
    # get environment value
    jira_options = {'server': os.environ["JIRA_URL"]}
    jira_user = os.environ["JIRA_USER"]
    jira_pass = os.environ["JIRA_PASS"]
 
    # JIRA Login
    try:
        jira = JIRA(options=jira_options, basic_auth=(jira_user, jira_pass))
    except JIRAError as e:
        return { "status" : "JIRA Login Failed." }
 
    # Create New Issue
    new_issue = jira.create_issue(
        project=os.environ["JIRA_PROJECT"],
        summary=event['summary'],    # API GatewayからJIRAチケットのタイトルをもらう
        description=event['desc'],   # API GatewayからJIRAチケットの詳細文をもらう
        issuetype={'name':os.environ["JIRA_ISSUE_TYPE"]}
        )

    return { "status" : "finished" }

```
###1-3. zipの作成
```
$ cd jira_function
$ zip -r ../jira_function.zip *
```

###1-4. コンソール上で作成
サービスからAWS Lambdaを選択し、「関数の作成」をクリック
<img width="799" alt="スクリーンショット 2019-07-11 18.28.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/a86f906a-da63-652d-c4cd-78a5bc216470.png">


関数名を適宜入力し、今回はランタイムにPython3.7を指定。右下の「関数の作成」をクリック
<img width="1396" alt="スクリーンショット 2019-07-11 18.33.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/57064619-66d2-8290-c22a-cb32c0a1fa40.png">


コードエントリタイプを「.zipファイルをアップロード」を選択し、「アップロード」から1-3で作成したzipをアップロードする
<img width="1290" alt="スクリーンショット 2019-07-11 18.36.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/f60ec5a5-9ff4-d8ad-38f5-9524fb7795e8.png">

###1-5. Lambda Functionのテスト
右上の「テスト」を押すとモーダルが立ち上がる
<img width="833" alt="スクリーンショット 2019-07-11 18.44.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/d17cf30e-3408-3d3a-713a-c7f06c63a07e.png">
<img width="845" alt="スクリーンショット 2019-07-11 18.43.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/640f51f7-6cb2-1f5f-3769-433e8bdc211e.png">

イベント名は適宜付け、コードを以下に修正する

```
{
  "summary": "test summary",
  "desc": "test desc"
}
```
これで準備ができたので、再度右上の「テスト」を押す
<img width="789" alt="スクリーンショット 2019-07-11 18.48.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/9cae4b55-53de-0b99-ea5d-02a95a535a63.png">
無事チケットが作成されました。

#2. API Gatewayの作成
先程作成したLambda FunctionをコールするAPI Gatewayを作成します。
###2-1. コンソール上で作成
サービスからAPI Gatewayを選択し、「APIの作成」をクリック
<img width="561" alt="スクリーンショット 2019-07-11 18.49.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/477c8aa8-9759-02a3-a7df-785c011f6a98.png">


API名を入力して「APIの作成」をクリック
<img width="1210" alt="スクリーンショット 2019-07-11 19.03.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/010eb0cc-fb88-7ebf-172f-63db39543683.png">


「アクション」から「リソースの作成」を選択してリソース名を入力後、右下の「リソースを作成」ボタンをクリック
<img width="1071" alt="スクリーンショット 2019-07-11 19.07.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/a272992a-0ecc-1365-e8ae-c43ee40e4fde.png">


「アクション」から「メソッドの作成」を選択してドロップダウンリストから「POST」を選択後、すぐ右のチェックボタンをクリック
<img width="269" alt="スクリーンショット 2019-07-11 19.11.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/1bc18920-37dd-8c2a-da71-8fdad9b718a3.png">


1で作成したLambda Functionを指定して保存をクリック
<img width="1162" alt="スクリーンショット 2019-07-11 19.16.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/e2e01f3e-92e0-b933-75cd-8f66a388e4ca.png">


権限追加のダイアログが出るのでOKをクリック
<img width="940" alt="スクリーンショット 2019-07-12 11.06.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/c36adc33-8520-4f2b-389c-47c6463d5076.png">

###2-2. API Gatewayに渡ってきたパラメータをLambdaに渡す設定
「統合リクエスト」をクリック
<img width="1157" alt="スクリーンショット 2019-07-12 11.08.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/083727ff-56fb-5965-5872-856de84ea8c6.png">


「マッピングテンプレート」を押してContent-Typeに`application/json`を入力後チェックボタンをクリック
<img width="848" alt="スクリーンショット 2019-07-12 11.12.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/72920dd4-4f10-29ee-2758-5dbb674cfc32.png">

コードに以下を記述する
<img width="839" alt="スクリーンショット 2019-07-12 11.14.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/02459e27-d1fc-9cb8-feea-3a22ca02a031.png">

```
{
    "summary" : "$input.params('summary')",
    "desc" : "$input.params('desc')"
}
```
###2-3. API Gateway→Lambdaのテスト
前の画面に戻り「テスト」をクリック
<img width="402" alt="スクリーンショット 2019-07-12 11.17.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/a8ce64d4-4ec4-8a3e-11e6-1e94aad7ba55.png">

POSTのリクエストパラメータは「クエリ文字列」欄にGETパラメータのように記述することでリクエストできます。
なのでクエリ文字列欄に以下を入力
<img width="733" alt="スクリーンショット 2019-07-12 11.22.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/1239bc11-1b67-3b3e-0ab9-c7d2cdd4add2.png">

```
summary=test summary2&desc=test desc2
```

一番下の「テスト」をクリックすると
<img width="724" alt="スクリーンショット 2019-07-12 11.24.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314386/4bb16300-f8a7-84cb-7796-bf017b72a3b9.png">
無事チケットが作成されました。
あとは適当なフォームをHTMLで作成し、API GatewayのエンドポイントへPOSTすれば問い合わせフォームの完成ですがこの部分は最初にも述べた通り割愛します。