SORACOM APIをLambdaから呼んで、SIMの情報を取得してみた

SORACOM APIをLambdaで使って、SIMの情報を取得しました。
2021.11.15

SORACOMには、開発者向けにAPIが提供されています。 SORACOM APIの使い方を調べつつ、AWS LambdaでSORACOM APIを呼んでみました。

おすすめの方

  • SORACOM APIを使いたい方
  • SORACOM APIをLambdaで使いたい方
  • AWS SAMでLambdaを作りたい方
  • パラメータストアのSecureStringをLambdaで取得したい方

SORACOM APIを使う準備

SAMユーザを作成し、認証情報を取得する

下記を参考にして、SAMユーザを作成します。

SORACOM SAMユーザを作成する

続けて、認証情報を取得します。

APIキーとトークンを取得してメモしておく

SAMユーザにアクセス権限を付与する

下記の権限を直接付与します。本番運用するときは、ロール作成などをしたほうが良いですね。

{
  "statements": [
    {
      "api": [
        "Subscriber:getSubscriber"
      ],
      "effect": "allow"
    }
  ]
}

SORACOM SAMユーザの権限を設定する

System ManagerのパラメータストアにSORACOM SAMユーザの認証情報を格納する

認証キーID

Stringとして格納します。

aws ssm put-parameter \
    --name "/SORACOM/SAM/KeyId" \
    --type "String" \
    --value "keyId-xxx"

認証キー シークレット

SecureStringとして格納します。

aws ssm put-parameter \
    --name "/SORACOM/SAM/Secret" \
    --type "SecureString" \
    --value "secret-yyy"

Lambdaを作る

sam init

sam init \
    --runtime python3.8 \
    --name Lambda-Soracom-Api-Sample \
    --app-template hello-world \
    --package-type Zip

AWS SAMテンプレート

認証キーIDはLambdaの環境変数に設定し、認証キーシークレットはLambda内で取得します。

template.yml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Lambda-Soracom-Api-Sample

Parameters:
  SoracomKeyId:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /SORACOM/SAM/KeyId

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Timeout: 10
      Policies:
        - arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
      Environment:
        Variables:
          SORACOM_KEY_ID: !Ref SoracomKeyId
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

  HelloWorldFunctionLogGroup:
      Type: AWS::Logs::LogGroup
      Properties:
        LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}

Outputs:
  HelloWorldApi:
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"

requirements.txt

requests

Lambdaコード

処理の流れは下記です。

  1. パラメータストアから認証キー シークレットを取得する
  2. SORACOM APIのAPIキー&トークンを取得する
  3. SIM情報を取得する
お試し実装のため、下記となっています。本番運用時には適宜検討し、実装してください。

  • APIトークンの有効期限はデフォルト設定です。
  • レートリミットの考慮をしていません。

API トークンの有効期間について

制限事項と注意事項

app.py

import os
import json
import boto3
import requests
from typing import Tuple

ssm = boto3.client('ssm')

SORACOM_ENDPOINT = 'https://api.soracom.io/v1'

IMSI = '1111'

def lambda_handler(event, context):
    soracom_key_id = os.environ['SORACOM_KEY_ID']
    soracom_secret = get_soracom_secret()

    api_key, token = get_token(soracom_key_id, soracom_secret)

    sim_info = get_sim_info(api_key, token, IMSI)

    print(json.dumps(sim_info))

    return {
        'statusCode': 200,
        'body': json.dumps({
            'status': sim_info['status'],
        }),
    }

def get_soracom_secret() -> str:
    res = ssm.get_parameter(
        Name='/SORACOM/SAM/Secret',
        WithDecryption=True
    )
    return res['Parameter']['Value']


def get_token(soracom_key_id, soracom_secret) -> Tuple[str, str]:
    headers = {'Content-Type': 'application/json'}
    data = {
        'authKeyId': soracom_key_id,
        'authKey': soracom_secret,
    }
    resp = requests.post(f'{SORACOM_ENDPOINT}/auth', headers=headers, data=json.dumps(data))

    d = resp.json()

    return d['apiKey'], d['token']

def get_sim_info(api_key: str, token: str, imsi: str) -> dict:
    headers = {
        'Content-Type': 'application/json',
        'X-Soracom-API-Key': api_key,
        'X-Soracom-Token': token,
    }
    resp = requests.get(f'{SORACOM_ENDPOINT}/subscribers/{imsi}', headers=headers)

    return resp.json()

デプロイ

sam build

sam package \
    --output-template-file packaged.yaml \
    --s3-bucket cm-fujii.genki-deploy

sam deploy \
    --template-file packaged.yaml \
    --stack-name Lambda-Soracom-Api-Sample-Stack \
    --s3-bucket cm-fujii.genki-deploy \
    --capabilities CAPABILITY_NAMED_IAM \
    --no-fail-on-empty-changeset

APIエンドポイントを確認する

aws cloudformation describe-stacks \
    --stack-name Lambda-Soracom-Api-Sample-Stack \
    --query 'Stacks[].Outputs'

動作確認

API Gatewayのエンドポイントにアクセスすると、SORACOM SIMのstatusが返ってきました。バッチリですね。

$ curl https://xxx.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"status": "active"}

参考