sttsのソースコードMemoブログ

色々やってみた結果のMemo

AWS App Runnerを試してみる

AWS App Runnerを試した時の記録です

AWS CLI2をインストール

いつのまにかAWS CLI2が出来ていました。インストールにpipを使わなくなった

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

$ aws configure

アクセスキー、シークレット、デフォルトリージョン(安そうなのでus-west-2派)、json

ECRにDockerイメージを登録

AWSコンソールからリポジトリを作成

"プッシュコマンドの表示"ボタンを押して表示されたコマンドを入力。↓のコマンドが表示された。

dockerコマンドにログイン情報を付ける

$ aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin <数字>.dkr.ecr.us-west-2.amazonaws.com

タグをつける

$ docker tag my-image-name:v3 <数字>.dkr.ecr.us-west-2.amazonaws.com/my-image-name:v3

pushする

$ docker push <数字>.dkr.ecr.us-west-2.amazonaws.com/my-image-name:v3

App Runner作成

ダイアログに従う。

  • リポジトリタイプ: コンテナレジストリ
  • プロバイダー: ECR
  • デプロイトリガー: 手動(自動にすると$1取られるので)
  • ECR アクセスロール: 適当に作成

次ページも適切に入力

  • ポートは、コンテナ上のプログラムが待ち受けているポート
  • セキュリティは、AppRunnerで実行するイメージが必要とするIAMロールを設定する

IAMロールは下記の信頼関係で事前作成した。どこかの見真似です。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "tasks.apprunner.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

App Runnerにカスタムドメインを付ける

ドメイン追加」ボタンを押しドメイン名を入力。

「関連付け指示を表示」に入力すべきCNAMEレコードが表示される。

指示に従いDNSレコードを登録。(Route53である必要はなかった)

半日ぐらい待つと検証が成功して利用できるようになった。

(半日はツライ。。。)

 

CentOS8のVNCサーバでログイン画面を表示する

GUIがインストールされていないCentOS8にインストールした時の記録です。

実施したコマンドは下記です。CentOS7の頃より簡単になっていました。

# yum group install "Server with GUI"
# yum install tigervnc-server
# systemctl enable xvnc.socket
# vi /etc/gdm/custom.conf

custom.confにDisallowTCP=falseとEnable=trueを足しました。

# GDM configuration storage

[daemon]
# Uncoment the line below to force the login screen to use Xorg
#WaylandEnable=false

[security]
DisallowTCP=false

[xdmcp]
Enable=true

[chooser]

[debug]
# Uncomment the line below to turn on debugging
#Enable=true

これで再起動するとport5900でVNCサーバが起動していました。

日本語入力の設定は下記を参考にしました。

CentOS8での日本語入力 | コリオのブログ

AWS SAMでカスタムドメイン設定をした記録

template.ymlは下記とした

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  customdomain-dynamodb-app

  Customdomain API-gateway and DynamoDB my Example

Parameters:
  DomainName:
    Type: String
    Default: api.my.example.com
  HostedZoneName:
    Type: String
    Default: my.example.com. # don't miss the  dot at the end

Globals:
  Api:
   Cors:
     AllowMethods: "'*'"
     AllowHeaders: "'*'"
     AllowOrigin: "'*'"
  Function:
    Timeout: 5
    Environment:
      Variables:
        TABLE_NAME: !Ref TodoDyanmoTable # Lambda実行時の環境変数TABLE_NAMEで参照可能になる 

Resources:
  TodoApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: v1
      Auth:         # Lambdaオーソライザーを使う
        # 参考DefaultAuthorizerは使えない: https://nibral.hateblo.jp/entry/2019/04/24/103036
        #DefaultAuthorizer: MyLambdaTokenAuthorizer
        Authorizers:
          MyLambdaTokenAuthorizer:
            FunctionPayloadType: REQUEST
            FunctionArn: !GetAtt MyAuthFunction.Arn
            Identity:
              Headers:
                - Authorization
              ReauthorizeEvery: 1 # 認証結果を1秒間だけ結果をキャッシュする模様


  APIDomainName:
    Type: AWS::ApiGateway::DomainName
    Properties:
      CertificateArn: arn:aws:acm:us-east-1:XXXX:certificate/XXXXXXXXX # 証明書のarn バージニア北部で作る
      DomainName: !Ref DomainName
  APIBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref APIDomainName
      RestApiId: !Ref TodoApiGateway
      Stage: v1

  HelloTodoFunction: # GET用
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_todo/
      Handler: app.get_lambda_handler
      Runtime: python3.7
      Policies:
       - DynamoDBCrudPolicy:
           TableName: !Ref TodoDyanmoTable
      Events:
        HelloTodo:
          Type: Api
          Properties:
            Path: /todo
            Method: get
            Auth:
              Authorizers: MyLambdaTokenAuthorizer
            RestApiId:
              Ref: TodoApiGateway
  POSTTodoFunction: # POST用
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_todo/
      Handler: app.post_lambda_handler
      Runtime: python3.7
      Policies:
       - DynamoDBCrudPolicy:
           TableName: !Ref TodoDyanmoTable
      Events:
        HelloTodo:
          Type: Api
          Properties:
            Path: /todo
            Method: post
            Auth:
              Authorizers: MyLambdaTokenAuthorizer
            RestApiId:
              Ref: TodoApiGateway
  TodoDyanmoTable:
    Type: AWS::DynamoDB::Table
    Properties:
      BillingMode: PROVISIONED # 無料枠はこっち
      AttributeDefinitions:
        - AttributeName: "user" # 属性定義
          AttributeType: "S"    # 文字列
        - AttributeName: "id"
          AttributeType: "N"    # 数値
      KeySchema:
        - AttributeName: "user"
          KeyType: "HASH" # ハッシュキー
        - AttributeName: "id"
          KeyType: "RANGE" # レンジキー
      ProvisionedThroughput:
        ReadCapacityUnits: 2
        WriteCapacityUnits: 2
  MyAuthFunction: # Token認証用lambda
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_todo/
      Handler: app.auth_request_lambda_handler
      Runtime: python3.7

Outputs:
  HelloTodoFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloTodoFunction.Arn

参考にしたサイト↓ではroute53の設定も入っていたが上手く動作しなかったため手動route53をで設定した。

https://github.com/awslabs/serverless-application-model/issues/40

route53の設定は下記を参照(route53にはAレコードでエリアス、cloudfront.netで終わるものを設定する)

https://www.beex-inc.com/blog/apigateway-using-custom-domain/

 

app.pyは下記とした。

import os
import boto3
from boto3.dynamodb.conditions import Key, Attr
import json
import decimal
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# import requests

def auth_request_lambda_handler(event, context):
    # 参考: https://dev.classmethod.jp/server-side/serverless/lambda-authorizer/
    logger.info('## ENVIRONMENT VARIABLES')
    logger.info(os.environ)
    logger.info('## EVENT')
    logger.info(event) 
    token = event["headers"]["Authorization"]
    logger.info('## token='+str(token) )
    if token == "1":
        logger.info('## sucess' )
        myaddisonalinfo = {
          "id": 1,
          "hoge": "foo"
        }
        tmp_str = json.dumps(myaddisonalinfo)
        base64_context = base64.b64encode(tmp_str.encode('utf8'))
        return {
            "principalId" : token,
            "policyDocument" : {
                "Version" : "2012-10-17",
                "Statement" : [
                    {
                        "Action": "*",
                        "Effect": "Allow",
                        "Resource": "arn:aws:execute-api:*:*:*/*"  
                    }
                ]
            },
            'context': {
                'additional_info': base64_context.decode('utf-8')
            }
        }
    # 1以外の時はNG
    return {
        "principalId" : 2,
        "policyDocument" : {
            "Version" : "2012-10-17",
            "Statement" : [
                {
                    "Action": "*",
                    "Effect": "Deny",
                    "Resource": "arn:aws:execute-api:*:*:*/*"  
                }
            ]
        }
    }

def decimal_default_int(obj):
    """
    json.dumps用
    https://qiita.com/ekzemplaro/items/5fa8900212252ab554a3
    https://forums.aws.amazon.com/message.jspa?messageID=689708
    """
    if isinstance(obj, decimal.Decimal):
        return int(obj)
    raise TypeError

def getTodos(user:str, dynamo):
    """
    指定されたユーザのTodosを取得
    """
    tmp_q = dynamo.query( KeyConditionExpression = Key('user').eq(user) )
    # queryした結果のItemsに本当の結果が入っている
    res = tmp_q["Items"]

    return res

def putTodos(body_dict):
    dynamo = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
    item = {
        "user": body_dict["user"],
        "id": body_dict["id"],
        "todo": body_dict["todo"]
    }
    dynamo.put_item(Item = item)

def post_lambda_handler(event, context):
    """
    curl -X POST -H 'Content-Type:application/json' -d '{ "user": "foo", "id": 2, "todo": "aaabbb" }' "https://api.my.example.com/todo" -H 'Authorization:1'
    """
    logger.info('## ENVIRONMENT VARIABLES')
    logger.info(os.environ)
    logger.info('## EVENT')
    logger.info(event)

    # eventのbodyがPOSTしたパラメータ
    body = event['body']
    logger.info('## BODY')
    logger.info(body)
    logger.info('## json.loads')
    body_dict = json.loads(body)

    logger.info('## putTodos()')
    putTodos(body_dict)
    ret_dict = {
        "statusCode": 200,
        "body": '{ "result": "ok" }',
        "headers": {
             "Access-Control-Allow-Origin": "*"
          }
    }
    return ret_dict

def get_lambda_handler(event, context):
    logger.info('## ENVIRONMENT VARIABLES')
    logger.info(os.environ)
    logger.info('## EVENT')
    logger.info(event)
    #logger.info('## CONTEXT')
    #logger.info(context)
    
    # eventのqueryStringParametersがGETしたパラメータ
    q_string_p = event["queryStringParameters"]
    # 想定文字列
    # curl "https://api.my.example.com/todo?user=foo" -H 'Authorization:1'

    taget_user = q_string_p["user"]

    dynamo = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
    res = getTodos(taget_user, dynamo)

    ret_dict = {
        "statusCode": 200,
        "body": json.dumps({"todos": res}, default=decimal_default_int),
"headers": { "Access-Control-Allow-Origin": "*" } } return ret_dict if __name__ == '__main__': print("-- sart --") dynamo = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME']) res = getTodos("foo", dynamo) print(res) print("---") ret_dict = { "statusCode": 200, "body": json.dumps({"todos": res}, default=decimal_default_int) } print(ret_dict)

aws-sam-cliを使う

久しぶりにaws-sam-cliを使うとdeploy方法が変わっていた。

$ pip3 install --user aws-sam-cli

$ pip3 install awscli --user

$ aws configure

アクセスキー、シークレット、デフォルトリージョン(安そうなのでus-west-2派)を入力、jsonを選択

$ sam init --runtime python3.7

$ sam deploy --guided

スタック名を入力、リージョンを入力、あと適当にYしてしまった。

カラフルに進行状況が表示された。

CloudFormaitonを見ると"aws-sam-cli-managed-default"というスタックと指定したスタックが出来ていた

$ aws cloudformation delete-stack --stack-name mystack01

RaspberryPi Busterでnode.jsとVue.js

nodesorceからパッケージをインストールするよう設定

参考: https://github.com/nodesource/distributions/blob/master/README.md#debinstall

# curl -sL https://deb.nodesource.com/setup_12.x | bash -
# apt-get install -y nodejs

/etc/apt/sources.list.d/nodesource.listにファイルができる模様。

Vue cliのインストール

vue-cliは古い。@vue/cliをインストールする。

$ npm install @vue/cli

$ npm install @vue/cli-init

 

 Vue.jsのプロジェクトの初期化

$ ./node_modules/.bin/vue init webpack my-app
$ cd my-app

$ npm install vue-router
$ npm run dev

 表示されたURLにブラウザからアクセスする。

リモートから接続する場合、https://qiita.com/pentamania/items/c172ef5c9fe780a81e36を参照("config/index.js"のhost:行をnpm run devするサーバのIPへ書き換える)

もしElement-UIを使う場合my-appディレクトリから下記を実行する

$  ../node_modules/.bin/vue add element

ビルドする

$ npm run build

 

aws-sam-localのメモ

aws-sam-localのメモ

依存パッケージのインストール(CentOS7の場合)

# yum install python36-pip

# yum install python36-devel

aws-sam-cliのインストール

$ pip3.6 install --user aws-sam-cli

awscliのインストール

$ pip3.6 install awscli --user

awscliの設定

$ aws configure

アクセスキー、シークレット、デフォルトリージョン(安そうなのでus-west-2派)、jsonフォーマットを入力

初期ファイルの作成

$ sam init --runtime python3.6

(以降は、sam initが生成するREADME.mdファイルに説明が書かれている)

↓のコマンドでDockerが必要とメッセージが出たのでdockerグループに一般ユーザを入れた

$ sam local start-api

動かしている間に別ウインドウから 「$ curl -X POST -d "hoge=foo&aaa=bbb" http://127.0.0.1:3000/hoge」等を実行し確認

Ctrl+C

s3バケット作成

$ aws s3 mb s3://for-my-sam

SAMパッケージ作成、アップロード

$ sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket for-my-sam

デプロイ

$ aws cloudformation deploy --template-file packaged.yaml --capabilities CAPABILITY_IAM --stack-name mystack001

 

参考

https://qiita.com/hayao_k/items/841026f9675d163b58d5

raspberry pi raspbianのwifiの設定

/etc/wpa_supplicant/wpa_supplicant.confファイルに以下だけで繋がった

 country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="接続するときに選ぶID"
    psk="パスワード"
}