AWS Lambda로 kintone 앱의 간이 자동 백업을 만들어 보았다 그 1(폼 설계 정보와 레코드의 취득)

금과 소리 자체는 어플리케이션을 매우 간단하게 작성할 수 있습니다만, 그 백업, 되면 유료의 제품을 구입하거나 혹은 수동으로 실시한다는 것이 현재입니다.

거기서, 유상의 백업과까지는 가지 않아도, 간이적인 백업의 구조를 만들 수 없는지, 시험해 보았습니다.

목표



우선 이하의 조건을 골로 합니다.
  • 백업 대상은 "폼 디자인"과 "데이터 세트"
  • 백업은 자동으로 정기적으로 수행됩니다
  • 필요한 경우 복원 메커니즘을 만듭니다

  • 백업을 위한 메커니즘



    · 양식 설계 정보 백업
    → → 양식 설계 정보 취득
    · 데이터 세트 백업
    → → 제10회 kintone REST API를 이용한 레코드 취득

    이들을 AWS Lambda(Python 3)에서 호출할 수 있도록 구현합니다. 복원도 json 형식으로 대응할 수 있을 것 같기 때문에, 위의 페이지대로의 결과를 얻을 수 있으면 백업으로서는 문제 없을 것 같습니다.

    처리 대상



    이런 느낌의 비품 재고 관리(기성품)를 이용합니다.



    구현



    전처리



    다양한 준비가 필요하기 때문에 먼저 실시합니다.
    KINTONE_BASE_URL = os.environ['KINTONE_URL']
    KINTONE_FORM_BASE_URL = os.environ['KINTONE_FORM_BASE_URL']
    URL = KINTONE_BASE_URL.format(
        kintone_domain=os.environ['KINTONE_DOMAIN'],
        kintone_app=os.environ['KINTONE_APP']
    )
    FORM_URL = KINTONE_FORM_BASE_URL.format(
        kintone_domain=os.environ['KINTONE_DOMAIN'],
        kintone_app=os.environ['KINTONE_APP']
    )
    HEADERS_KEY = os.environ['KINTONE_HEADERS_KEY']
    API_KEY = os.environ['KINTONE_API_KEY']
    
    S3_BUCKET = os.environ['S3_BUCKET']
    S3_OBJECT_PREFIX = os.environ['S3_OBJECT_PREFIX']
    
    s3_client = boto3.client('s3')
    

    모든 레코드 얻기



    이러한 느낌으로 Query에 아무것도 지정하지 않는 전건 취득을 실시합니다.
    def get_all_records(headers):
        query = u''
    
        response_record = requests.get(URL + query , headers=headers)
        return json.loads(response_record.text)
    

    양식 설계 정보 취득



    폼은 위의 페이지를 참고로 이러한 구현이 됩니다.
    def get_form_info(headers):
    
        response_record = requests.get(FORM_URL, headers=headers)
        return json.loads(response_record.text)
    

    취득한 데이터를 S3에 백업으로 유지



    boto 라이브러리를 이용하여 tmp 폴더에 일시적으로 작성한 파일을 S3에 업로드합니다.
    def put_data_to_s3(contents):
        date = datetime.now()
        date_str = date.strftime("%Y%m%d%H%M%S")
        tmp_dir = "/tmp/"
        tmp_file = S3_OBJECT_PREFIX + "_" + date_str + ".json"
    
        with open(tmp_dir + tmp_file, 'w') as file:
            file.write(json.dumps(contents, ensure_ascii=False, indent=4, sort_keys=True, separators=(',', ': ')))
    
        s3_client.upload_file(tmp_dir + tmp_file, S3_BUCKET, tmp_file)
    
        return True
    

    위를 호출하는 메소드



    지금까지 만든 부품을 연결합니다. 각각 레코드 일람과 폼 설계 정보를 하나의 JSON 파일에 정리하도록 구현하고 있습니다.
    def run(event, context):
    
        headers = {HEADERS_KEY: API_KEY}
        record_data = get_all_records(headers)
        records = record_data['records']
    
        form_data =get_form_info(headers)
        forms = form_data['properties']
    
        result = {
            "records": records,
            "properties": forms
        }
    
        return put_data_to_s3(result)
    

    (덤) 환경 변수는 스테이지 마다 전환하도록 구현



    크라메소의 기사 을 참고로, 스테이지 마다 환경 변수를 전환할 수 있도록(듯이) 하고 있습니다.

    serverless.yml
    service: aws-kintone-backup
    
    provider:
      name: aws
      runtime: python3.6
      region: us-east-1
      stage: ${opt:stage, self:custom.defaultStage}
      environment:
        KINTONE_URL: https://{kintone_domain}/k/v1/records.json?app={kintone_app}
        KINTONE_FORM_BASE_URL: https://{kintone_domain}/k/v1/form.json?app={kintone_app}
        KINTONE_HEADERS_KEY: X-Cybozu-API-Token
    custom:
      defaultStage: dev
      otherfile:
        environment:
          dev: ${file(./conf/dev.yml)}
          prd: ${file(./conf/prd.yml)}
    
    functions:
      run:
        handler: handler.run
        environment:
          KINTONE_DOMAIN: ${self:custom.otherfile.environment.${self:provider.stage}.KINTONE_DOMAIN}
          KINTONE_API_KEY: ${self:custom.otherfile.environment.${self:provider.stage}.KINTONE_API_KEY}
          KINTONE_APP: ${self:custom.otherfile.environment.${self:provider.stage}.KINTONE_APP}
          S3_BUCKET: ${self:custom.otherfile.environment.${self:provider.stage}.S3_BUCKET}
          S3_OBJECT_PREFIX: ${self:custom.otherfile.environment.${self:provider.stage}.S3_OBJECT_PREFIX}
    

    dev.yml
    KINTONE_DOMAIN: xxxxxx.cybozu.com
    KINTONE_API_KEY: XXXXXXXXX
    KINTONE_APP: XXX
    S3_BUCKET: XXXXXX
    S3_OBJECT_PREFIX: XXXXXX
    

    sls 명령으로 업로드할 때 --stage 옵션을 지정해야 합니다. (기본값은 dev)

    실행해보기



    이제 각각 환경 변수를 지정하여 실행해 보겠습니다. 안전 S3에 파일이 출력되었습니다. 내용도 무사 출력되고 있습니다. (콘텐츠가 길기 때문에 여기에는 올리지 않지만)



    AWS Lambda로 개발하고 있으므로, 나머지는 스케줄링에서도 하면 자동 기동은 간단하네요.

    현재의 과제



    일단 가능했지만 몇 가지 이미 알고있는 과제가 있습니다.
  • 레코드의 일괄 취득은 한 번에 500건까지 밖에 할 수 없다. (kintone 사양)
  • 레코드의 일괄 등록은 한 번에 100건까지 밖에 할 수 없다. (kintone 사양)
  • S3에 업로드한 파일은 계속 남아 버린다. (수동으로 삭제하지 않으면 나중에 쓰레기가됩니다)
  • 복원 메커니즘이 없습니다

  • 이 근처를 해소하는 것 같은 구현은 또 나중에.

    아티팩트



    지금까지의 아티팩트는 다음과 같습니다.

    요약



    흔한 kintone 애플리케이션 백업의 일부를 자동화할 수 있었습니다. 그렇다고는 해도 API로서는 프로세스 관리나 어플리케이션의 일반적인 설정까지 취득하는 것이 있기 때문에, 이 근처를 담으면, 점점 풍부한 백업 처리가 될 것 같습니다. 그 주변은 또 다음에도.

    좋은 웹페이지 즐겨찾기