[AWS AppSync] Schema Creation Status is FAILED with details: Internal Failure while saving the schema.
今回は CloudFormation あるあるのエラーメッセージが抽象的でエラーの特定に難航するけど、よくみたら大したこと無いシリーズです。
🔥 事象
AWS AppSync を利用していて、以下のような GraphQL をデプロイすると表題のエラーが発生してデプロイ失敗しました。
CloudFormation では表題のエラーが発生していました。
エラーメッセージと schema.graphql
を見ても何が悪いかさっぱりでした。
input UpdatePlayerInput { name: String! salary: Int! } input UpdateTeamInput { name: String player: [Player!] } type Player { name: String! salary: Int! } type Team { id: ID! name: String player: [Player!] }
💡 原因
当たり前ですが、type では type を設定し、input では input を設定する必要がありました。
今回の場合は Team
の player は Player
を設定し、UpdateTeamInput
の player は UpdatePlayerInput
を設定します。
input UpdatePlayerInput { name: String! salary: Int! } input UpdateTeamInput { name: String player: [UpdatePlayerInput!] } type Player { name: String! salary: Int! } type Team { id: ID! name: String player: [Player!] }
デプロイしたときのエラーメッセージが不親切で原因解明に時間がかかってしまいましたが、こんな当たり前のことだったんですね!
ちなみに
AWS AppSync Console 画面で graphql を入力するとリアルタイムでバリデーションしてくれるぞ!👍
NG
Expected [Player!] to be a GraphQL input type.
この気の利いたエラーメッセージを CloudFormation に出してくれませんかね…。
OK
まとめ
ということで、GraphQL の静的チェックできていれば Schema Creation Status is FAILED
は発生しない(はず)。
AWS AppSync Console 画面が便利なことがわかりましたが、いちいちコンソール開かずにチェックできるよう VS Code Extension でなんかいいのないですかね〜。
[AWS] Lambda で S3 バケットに対する権限を CDK Python で付与したい
はじめに
Lambda から S3 バケットに対して Read/Write したいけどバケットを Public にするわけにはいかない。
そんなときはバケットポリシーで特定の Lambda に対してのみ Read/Write 権限を付与しましょう。
CDK Python でやるときはこんな感じになります。
サンプル
from aws_cdk import (core, aws_s3, aws_iam, ) from aws_cdk.aws_lambda import Runtime from aws_cdk.aws_lambda_python import PythonFunction class SampleStack(core.Stack): def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # lambda lambda_ = PythonFunction( self, 'SampleLambda', runtime=Runtime.PYTHON_3_8, entry='src', index='sample.py', handler='handler') # S3 bucket_ = aws_s3.Bucket(self, 'sample-bucket-name') bucket_.add_to_resource_policy( aws_iam.PolicyStatement( effect=aws_iam.Effect.ALLOW, actions=['s3:PutObject', 's3:GetObject'], principals=[ aws_iam.ArnPrincipal( lambda_.role.role_arn ) ], resources=[ bucket_.arn_for_objects('*') ] ) )
こちらをデプロイすると S3 のバケットポリシーは以下のようになります。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": ["{Lambda Role ARN}"] }, "Action": ["s3:PutObject", "s3:GetObject"], "Resource": "{S3 Bucket ARN}/*" } ] }
これで対象の Lambda 以外からは Access Denied を返すようになりました。
サンプルでは Put と Get 両方付与していますが、S3 バケットから読み取りのみ行う Lambda であれば Action には s3:GetObject
のみ設定してください。
おわりに
ArnPrincipal を使うことで "AWS": ["{ARN}"]
の書き方ができます。
Lambda だけでなく特定ユーザーのみ操作できるようにするといった場合は IAM ユーザー ARN を設定すればよさそうです。
S3 バケット名は全世界でユニークなので公開は極力控えていきましょう。
[VirtualBox] You must specify a machine to start, using the command line.
小ネタですが、VirtualBox 壊れたのかと焦ってしまったので戒めとして残しておきます。
🔥 事象
「VirtualBox 起動しよう」
「お、この前使ったからDock にアイコンあるじゃん。」
「ポチッとな(クリック)」
↓
🤦♀️
💡 解消方法
なんと、Dock でクリックしていたのは VirtualBox ではなく、VirtualBoxVM でした!!
同じアイコンで別物なのかよ!
🙅♀️ クリックすると表題のエラーダイアログが発生します。
🙆♀️ クリックすると VirtualBox マネージャーが起動します。
VirtualBox をクリックしたら無事に VirtualBox マネージャーが起動しました。めでたしめでたし。
余談
VirtualBoxVM と間違わないように VirtualBox を Dock のスタメンに追加することにしました。
Google Search Console で「検出 - インデックス未登録」
今回はブログ運営についてです。
状況
Google Search Console にサイトマップを登録して
「これでブログのアクセス数あがりまっせ〜🙌」
ご覧のように Google 先生に全ページ 除外 されているではありませんか。
除外の内容はというと、
「検出 - インデックス未登録」とのことです。
公式見解
ページは Google により検出されましたが、まだクロールされていません。これは通常、Google が URL をクロールしようとしたものの、サイトへの過負荷が予想されたため、クロールの再スケジュールが必要となった場合です。そのため、レポート上で最終クロール日が空欄になっています。
時間が解決するといったところでしょうか。
しばらく経っても変わらない場合にサイトへの過負荷とやらについて掘り下げていきます。
ちなみに
現在のステータスは 検出 - インデックス未登録 ですが、クロール済み – インデックス未登録 となると、Google 先生から 写す価値なし の 低品質 サイトの烙印を押されたことになるようです。
頑張って書いていきますのでどうかよろしくおねがいします🙏 > Google 先生
Lambda から DynamoDB GSI でクエリすると AccessDenied になる
🔥 事象
CDK Python でデプロイした Lambda で、GSI を使った query 実行時に AccessDenied になりました。
Lambda の Policy に dynamodb:Query
足してるのになんでやねんって感じ。
💡 解消方法
grantReadData で全ての読み取り権限を Lambda に付与することで解消できました。
⌨️ サンプル
例として野球チームの選手一覧からポジションと利き手で絞り込みたい場合をあげます。
監督も「左利きの投手」で query したいことでしょう。左の先発ピッチャーは重宝されますからね。
from aws_cdk import core from aws_cdk.aws_iam import PolicyStatement from aws_cdk.aws_lambda_python import PythonFunction from aws_cdk.aws_lambda import Runtime from aws_cdk.aws_dynamodb import ( Table, Attribute, AttributeType, BillingMode, ProjectionType ) class SampleStack(core.Stack): def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) table_ = Table( self, 'BaseballTeamMembers', billing_mode=BillingMode.PAY_PER_REQUEST, partition_key=Attribute( name='id', type=AttributeType.STRING), removal_policy=core.RemovalPolicy.DESTROY, ) table_.add_global_secondary_index( index_name='PositionPitchingHandIndex', partition_key=Attribute( name='position', type=AttributeType.STRING), sort_key=Attribute( name='pitching-hand', type=AttributeType.STRING), projection_type=ProjectionType.ALL, ) lambda_ = PythonFunction( self, 'ListMembersByPositionPitching', runtime=Runtime.PYTHON_3_8, entry='lambda', index='members.py', handler='handler', environment={ 'MEMBERS_TABLE_NAME': table_.table_name }) lambda_.add_to_role_policy( PolicyStatement( resources=[table_.table_arn], actions=['dynamodb:Query'])) table_.grant_read_data(lambda_)
Spotify から Podcast を排除する
はじめに
皆さん Podcast 聴いてますか!?
2020 年 12 月に 10,000 人を対象に調査した結果によると
ポッドキャストを 1 ヶ月に 1 回以上使用するユーザーは 14.2%
とのことで、Podcast は勢いを伸ばしてきているようです。
そんな中、私は Podcast を一切利用していません。
音楽を聴くツールとして Spotify を利用していますが、Podcast が Home 画面上部に陣取り、消すこともできないし、最下部に追いやることすらできず迷惑しています。
そこで、spicetify-cli とその extension の spicetify-hide-podcasts を使って Spotify から Podcast を葬り、平穏を取り戻したいと思います。
環境
spicetify-cli インストール
Homebrew でもインストールできますが、推奨の方法でインストールします。
$ curl -fsSL https://raw.githubusercontent.com/khanhas/spicetify-cli/master/install.sh | sh
インストール後は Basic Usage に従いコマンドを実行していきます。
$ spicetify $ spicetify backup apply enable-devtool $ spicetify update
横道にそれるので紹介に留めますが、spicetify-cli では spicetify-themes を使って外観を変えたりすることもできます。
spicetify-hide-podcasts インストール
手元に hidePodcasts.js
をダウンロードしたあとに README に従いコマンドを実行していきます。
$ git clone https://github.com/theRealPadster/spicetify-hide-podcasts.git
$ cd spicetify-hide-podcasts
$ cp hidePodcasts.js ~/spicetify_data/Extensions
$ spicetify config extensions hidePodcasts.js
$ spicetify apply
🗡 Kill Podcast
- 右上のメニューアイコンを選択します。
- [Hide podcasts] を選択します。
- Home 上部に陣取っていた Podcast どもが消え去ります。🤘🤘🤘
おわりに
みなさんも spicetify-cli で豊かな Spotify ライフを。
OpenVINO を使って感情認識する 〜準備編〜
はじめに
みなさんは他人が今どういう感情か表情から読み取ることはできますか?
相手が笑顔だったり泣いていれば「嬉しい」「悲しい」くらいはわかると思います。
しかし、ポーカーフェイスの人の感情を読み取ることは難しいですよね。
そこで、OpenVINO の感情認識を利用してポーカーフェイスの人の感情を読み取ってしまいましょう。
お品書き
の 1. と 2. について本記事では記述します。 3. と 4. については Python で実装します。
環境
- MacOS Big Sur 11.4
- Docker Desktop Version 3.5.2
前提
MacOS で OpenVINO を利用するには会員登録して dmg をダウンロードする必要があります。
私みたいな会員登録したくない方のために、Ubuntu の apt で OpenVINO をインストールします。
Ubuntu 準備
Docker で Ubuntu 20.04 のイメージを用意します。
$ docker image pull ubuntu:20.04 $ docker container run -it -d --name ubuntu2004 ubuntu:20.04 $ docker container exec -it ubuntu2004 /bin/bash
OpenVINO 準備
基本的に公式サイトに従います。
後述の周辺環境インストールのために Runtime Package ではなく Developer Package をインストールします。 docs.openvinotoolkit.org
$ apt-get update $ apt-get install -y sudo $ apt-get install -y wget $ wget https://apt.repos.intel.com/openvino/2021/GPG-PUB-KEY-INTEL-OPENVINO-2021 $ apt-get install -y gnupg2 $ sudo apt-key add GPG-PUB-KEY-INTEL-OPENVINO-2021 $ echo "deb https://apt.repos.intel.com/openvino/2021 all main" | sudo tee /etc/apt/sources.list.d/intel-openvino-2021.list $ sudo apt-cache search intel-openvino-dev-ubuntu20 $ sudo apt install intel-openvino-dev-ubuntu20-2021.1.110 $ sudo apt list --installed | grep openvino
周辺環境インストール
こちらも基本的に公式サイトに従ってすすめていきます。 docs.openvinotoolkit.org
$ cd /opt/intel/openvino_2021/install_dependencies/ $ ./install_openvino_dependencies.sh $ source /opt/intel/openvino_2021/bin/setupvars.sh $ cd /opt/intel/openvino_2021/deployment_tools/model_optimizer/install_prerequisites $ ./install_prerequisites.sh $ cd /opt/intel/openvino_2021/deployment_tools/demo $ ./demo_squeezenet_download_convert_run.sh $ cd /opt/intel/openvino_2021/install_dependencies $ apt-get install lsb-release $ ./install_NEO_OCL_driver.sh
モデルダウンロード
顔認識には face-detection-adas-0001 を使用し、感情認識には emotions-recognition-retail-0003 を使用します。
model_downloader ディレクトリで python3 downloader.py --name {モデル名} --output_dir {格納先}
のコマンドを実行することでダウンロードできますので、ダウンロード先はご自身の環境に合わせて変えてください。
$ cd /opt/intel/openvino_2021/deployment_tools/tools/model_downloader # 顔認識で使用するモデル $ python3 downloader.py --name face-detection-adas-0001 --output_dir ~/models # 感情認識で使用するモデル $ python3 downloader.py --name emotions-recognition-retail-0003 --output_dir ~/models
Python パッケージ準備
グローバルへのインストールに抵抗がある場合は仮想環境を作成して実行してください。
$ pip3 install opencv-python $ pip3 install openvino
おわりに
以上で「1. OpenVINO 環境構築(Ubuntu)」と「2. 顔認識と感情認識に使用するモデルを取得する」まで完了です。
「3. 映像全体から顔認識する」と「4. 顔部分のバウンディングボックスを切り取って感情認識を行う」については OpenVINO を使って感情認識する 〜実装編〜
で記述していきます。
なお、Ubuntu への MacOS からの Web カメラ入力と GUI 準備ができていないので、今回はファイル入力とファイル出力で感情認識を確認していきます。