20201127のAWSに関する記事は13件です。

AWSのIAMユーザーでCostExplorerやBillingにアクセスできないとき

困っていたこと

IAMユーザで請求情報にアクセスできない

毎回ルートユーザになって確認

問題点

  • めんどくさい

アカウント切り替えが本当に手間だった

  • セキュリティ的にまずい

ルートユーザ使うのはNG

解決策

Googleで検索したところ、3秒で解決。

やり方

①ルートユーザでログインし、AWSコンソールから「マイアカウント」に移動

②[IAM ユーザー/ロールによる請求情報へのアクセス] の横の[編集] をクリック

③[IAMアクセス有効化]チェックボックスをオンにし、[保存]をクリック

④IAMユーザで請求情報にアクセス可能に

下記リンク参照
AWS公式ドキュメント アクセス許可の管理の概要

まとめ

なんで今までやらなかったんだろう。。。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

aws cliでs3に再帰的にファイルをアップロードする時の記述

たまにしか使わなくて毎回忘れるのでメモとして残します。

再帰的にアップロードする記述

aws s3 cp ローカルのディレクトリ名 s3://バケット名/フォルダ名 --recursive

アップロードのときにpublic read付ける場合は--acl public-readをつける

aws s3 cp ローカルのディレクトリ名 s3://バケット名/フォルダ名 --recursive --acl public-read

バケットから再帰的にダウンロードする記述

aws s3 cp s3://バケット名/フォルダ名 ローカルのディレクトリ名 --recursive

バケットからバケットへ再帰的にコピーする記述

応用してバケットからバケットへも出来ます。

aws s3 cp s3://送信元バケット名/フォルダ名 s3://送信先バケット名/フォルダ名 --recursive

ついでにファイル数とかの確認

アップロードしたファイルの数があってるか等の確認に使える記述

aws s3 ls s3://バケット名/フォルダ名 --recursive --human --sum

以下のような結果が返ります。

2020-11-27 12:34:56   10 Bytes ファイル名
2020-11-27 12:34:56    1.2 KiB ファイル名
  :
2020-11-27 12:34:56  100.1 MiB ファイル名

Total Objects: 100
   Total Size: 999.9 MiB

参考

AWS CLI Command Reference/s3/cp

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

2020年のAmplify進化の軌跡

こんにちは!
本エントリは「AWS Amplify Advent Calendar 2020」の初日です。
カレンダー初っ端を飾る特別な日なので、AWS Amplifyって何が出来るのか、どんなプロダクトなのか、また初学者にとってどうやって勉強すれば良いのか、また最新情報のキャッチアップはどうすればいいのか、というのを深掘っていきたいと思います。

AWS Amplifyってなんなの?

これは今年のAWS Summit Onlineの kimyan_udon2 さんの発表(内容はこちら)がとてもイカしていたので、それを観てもらうととてもわかり易いです!

「Amplify」という言葉には複数の意味があります。
単純に「Amplify良いですよね!」とか言うと「うんうん、良いよね!でもAmplifのどれの話!?」となりがちです。
なのでポイントを簡単に紹介するのでここだけでも覚えて帰って下さいね。

Amplifyは4つの機能から構成される

以下画像の通り、Amplifyは「Amplifyライブラリ」、「UIコンポーネント」、「Amplify CLI」、「Amplify Console」の4つあります。
スライドには書いていませんが、スライドの中の上3つ「ライブラリ、UIコンポーネント、CLI」をまとめて「Amplify Framework」と呼んだりもします。こちらはOSSになっておりソースコードが公開されています(リンクは後述)
またAmplify ConsoleはCI/CDワークフローの管理やホスティング機能をもったAWSのサービスです。
スクリーンショット 2020-11-24 8.36.48.png

最新情報のキャッチアップ方法

Amplify Framework Docsを読み込む

基本的な話ですが、やはり公式ドキュメントを読むのが一番です!
https://docs.amplify.aws/

日本語まとめを見る

日本語で書かれているAWS Amplifyのツール、チュートリアル、記事などのリンク集です。
初学者の方はこちらから入るとわかりやすいかもしれません。
https://github.com/watilde/awesome-aws-amplify-ja

GitHubのコミット履歴からアップデート内容を確認する

amplify-cliを中心に以下のリポジトリも定期的に確認いただけると良いと思います!
* amplify-flutter
* amplify-ios
* amplify-android
* amplify-js

javascriptとiOS、Androidはmasterブランチではなく、mainブランチがデフォルトブランチになっているのも興味深いですね。
cliやflutterも今後はデフォルトブランチが変更される可能性があるので、上記リンクだけでなく全体をgit cloneして今後マージされそうなブランチを眺めてみるのも面白いと思います!

Slackで気軽に質問をする

Amplify Meetup #02で発表しました、Amplify Japan User Groupから登録いただいてコミュニティーメンバーに気軽に質問をしてみてください!

Amplifyイベントに参加する

(おおよそ)2ヶ月に一度、Amplifyイベントを実施しています!
ついに今年からAmplify Meetupを初開催し、たくさんのお客様に視聴いただきました!

以下に今年実施したイベントをまとめておきます。
* 11月
* Amplify Meetup #02
* 10月
* Amplify Hands-on
* 7月
* Amplify Meetup #01

2020年のアップデート

以下に今年の大きなアップデートをまとめてみました。



今年も熱いアップデートが多かったのですが、個人的にはAmplifyライブラリがSSR対応したことで、Next.jsやNuxt.jsなどでCognitoやAppSyncをサーバサイドでリクエストしてからレンダリングできるようになったことが嬉しかったです。(お客様からの要望が非常に多かった。。。)
またネイティブアプリ関連のアップデートも多く、2021年は様々なフロントエンドエンジニアの方々がAmplifyを利用してサービス開発の速度を爆上げするようなブログや発表を目にする機会が増えそうで楽しみですね!

それではまた!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Azure Data CatalogにAWSDataCatalogのデータをRegistration Toolを使って登録する

やりたいこと

AWSのGlueやAthenaの使っているAWSDataCatalogのデータもAzure Data Catalogに登録したい。

作業環境

  • Windows Server または Windows 10
  • Azure Data Catalog Registration Toolがインストール済み

Registration ToolにODBCがあるので、これを使ってAthenaからODBC経由でカタログデータを取得します。

image.png

手順

AthenaのODBCドライバインストール

以下のAWSの公式サイトからAthenaのODBCドライバをダウンロードします。
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/connect-with-odbc.html

インストーラーがダウンロードされますので、実行します。

画像のようなインストールが起動します。選択肢はインストール場所程度のなので、手順は省略します。

image.png

Registration Tool利用したデータカタログ同期

ODBCデータベースをデータソースとして選択

image.png

ODBC Driverのパラメータ入力

パラメータ入力画面が表示されるので以下のように入力して「接続」します。

この表の情報が、この手順で一番大事です。

項目 入力値
ドライバー Simba Athena ODBC Driver
接続文字列(※) AwsRegion=ap-northeast-1;S3OutputLocation=s3://your-bucket
データベース AwsDataCatalog
ユーザ [AWS Access Key]
パスワード [AWS Secret Access Key]

※ 接続文字列は最低限 AwsRegionS3OutputLocation が必要です。他の項目はODBC Driverのダウンロードページにあるドキュメントの Using a Connection String の項目に記載があります。

image.png

対象のテーブルを選択

接続が成功すると AwsDataCatalog というカタログ名がツリーのトップとして表示されます。

下にDBがぶら下がっているので、 machine_a というテスト用のDBの sensor_b_tab というテーブルの情報をAzure DataCatalogに転送してみようと思います。

設定項目に 「プレビューを含める」 と、 「データプロファイルを含める」 があります。大きなテーブルではこの項目の有効化は注意して行ってください。例えばNull値の数を数えるクエリが列数分流れたりと場合によっては課金対象が大きくなるかもしれません。今回の例では小さなテーブルなのでチェック付けてます

image.png

対象のテーブルを選んだら「登録」ボタンをクリックします。

テーブルのカタログ情報の登録処理

カタログ情報の取得と登録の処理が流れます。

image.png

上に太字で書いた通り、取得内容に、 「プレビューを含める」「データプロファイルを含める」を選択している際にはここで時間がかかる場合があります。この際にAthena側を見ると先程の注意書きに書いた通り、Null値の数を列毎に数えるクエリやデータを取得するクエリが流れているが確認できます。

image.png

カタログ情報の確認

AWSでの見え方

AWSのGlueでは以下のように見えるテーブルです。小さいものを選びました。

image.png

Azure DataCatalogでの見え方

最上位は AwsDataCatalog となっていて、Glueでいう DatabaseSchema という名前で表現されています。階層数は同じです。

image.png

image.png

今回はプレビューも含めるとしたので、プレビューデータも見えてます。

image.png

裏でAthenaで複数クエリで取得されていたプロファイル情報です。

image.png

(Tips)トラブルシュート

Registration Toolのログファイルの場所

実は、最初繋がらなかった時にエラー特定するためにログの場所を探すのに一番時間かかりました。

%appdata%\AzureDataCatalogErrorEventLogProd.log

ODBC Driverのログレベル設定

Driverログレベルを変更することも可能です。

自分で環境でINIファイルで設定する方法と、以下のようにODBCデータソースをセットアップして、接続文字列で指定する方法があります。WARNING以上を見ると権限の問題などエラーがある場合に原因を追及することが可能です。

DSN=MyAthena;AwsRegion=ap-northeast-1;S3OutputLocation=s3://your-bucket

image.png

インストール後必要なLibraryが無い場合がある

以下のファイルなどが使われているのですが、正常にDriverがインストールされているように見えてライブラリが無い場合がありました。

C:\Program Files\Simba Athena ODBC Driver\lib\AthenaODBC_sb64.dll

再度インストーラーをダウンロードしてもライブラリが無い場合は以下のようなダウンロードリンクを取って別のバージョンをインストールすると上手くいく場合があります。

https://s3.amazonaws.com/athena-downloads/drivers/ODBC/SimbaAthenaODBC_1.1.5/Windows/Simba+Athena+1.1+64-bit.msi

関連URL

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda boto3でCognitoのユーザーを削除する

はじめに

AWS LambdaでCognitoのユーザーを削除します。
ランタイムはpythonです。
環境変数COGNITO_MAX_RESULTSには、50を指定します。
ユーザープールの数が50以下である事を想定しています。
Cognitoからユーザーを削除する場合、ループ処理となり、たまにコケることがあるため、リトライ処理を追加しています。

Lambdaのスクリプト

Lambda
import os
import boto3

cognito = boto3.client('cognito-idp', region_name='ap-northeast-1')

def handler(event, context):

    user_pool_name = 'ユーザープール名'
    user_ids = ['ユーザーID']

    # Cognitoからユーザーを削除する
    response = delCognitoUser(user_pool_name, user_ids)

    return response

    def getUserPoolId(user_pool_name):
        """[サービスに紐づくCognitoのユーザープールIDを取得する]

        Args:
            user_pool_name ([str]): [Cognitoユーザープール名]

        Returns:
            [str]: [CognitoユーザープールID]
        """

        # COGNITO_MAX_RESULTSの数だけ、ユーザープールの情報を取得する
        userPools = cognito.list_user_pools(
            MaxResults=int(os.environ['COGNITO_MAX_RESULTS'])
        )

        # サービス識別名に紐づくユーザープールIDを探索する
        for userPool in userPools['UserPools']:
            if userPool['Name'] == user_pool_name:
                return userPool['Id']

    def delCognitoUser(user_pool_name, user_ids):   
        """[Cognitoからユーザーを削除する]

        Args:
            user_pool_name ([str]): [Cognitoユーザープール名]
            user_ids ([list]): [ユーザーID]

        Returns:
            [list]: [Cognitoの結果]
        """

        # サービスに紐づくCognitoのユーザープールIDを取得する
        user_pool_id = getUserPoolId(user_pool_name)

        for user_id in user_ids:
            # Cognitoのユーザープールからユーザーを削除する

            while True:
                try:
                    response = cognito.admin_delete_user(
                        UserPoolId=user_pool_id,
                        Username=user_id
                    )
                    print(user_id)
                    print(response)
                except cognito.exceptions.TooManyRequestsException:
                    print('time wait 5 seconds')
                    time.sleep(5)  # 必要であれば失敗時の処理
                except cognito.exceptions.UserNotFoundException:
                    print('UserNotFoundException: ' + user_id)
                    break
                else:
                    break  # 失敗しなかった時はループを抜ける
            else:
                print('Do not delete: ' + user_id)
                continue  # リトライが全部失敗した時の処理

        return True
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda boto3でWAFのIP setsを更新する

はじめに

AWS LambdaでWAFのIP setsを更新します。
ランタイムはpythonです。
WAFはCLOUDFRONTのものとなるため、AWSリージョンはバージニア北部のus-east-1となります。
WAFのIP Setsの更新は、渡したIPアドレスのリストで上書きされるので、登録・更新・削除が同じメソッドとなります。
リストip_adressesは重複していても問題なく、WAFに登録されます。

Lambdaのスクリプト

Lambda
import boto3

waf = boto3.client('wafv2',region_name='us-east-1')

def handler(event, context):

    ip_set_name = 'IP Sets名'
    ip_adresses = ['IPアドレス']

    response = update_ip_addresses(ip_set_name, ip_adresses)

    return response

    def update_ip_addresses(ip_set_name, ip_adresses, scope='CLOUDFRONT'):
        """[指定したIPアドレスでWAFを更新する]

        Args:
            ip_set_name ([str]): [IP sets名]
            ip_adresses ([list]): [IPアドレス]
            scope ([str], optional): [スコープ]. Defaults to CLOUDFRONT.

        Returns:
            [dict]: []
        """

        try:
            # IP setsの更新情報を取得する
            ip_set_info = get_ip_set_info(ip_set_name)

            response = waf.update_ip_set(
                Name=ip_set_name,
                Scope=scope,
                Id=ip_set_info['IPSet']['Id'],
                Addresses=ip_adresses,
                LockToken=ip_set_info['LockToken']
            )
        except waf.exceptions.WAFOptimisticLockException:
            update_ip_addresses(ip_set_name, ip_adresses)

        return response

    def get_ip_set_info(ip_set_name, scope='CLOUDFRONT'):
        """[指定したIP setsの詳細情報を取得する]

        Args:
            ip_set_name ([str]): [IP sets名]
            scope ([str], optional): [スコープ]. Defaults to CLOUDFRONT.

        Returns:
            [dict]: [指定したIP setsの詳細情報]
        """

        response = waf.get_ip_set(
            Name=ip_set_name,
            Scope=scope,
            Id=get_filtering_ip_sets()[ip_set_name]['id'] 
        )
        return response

    def get_filtering_ip_sets():
        """[取得したIP setsの情報をフィルタリングする]

        Returns:
            [dict]: [フィルタリングしたIP setsの情報]
        """

        ip_sets_dict= {}
        for ip_set in get_all_ip_sets():
            ip_sets_dict[ip_set['Name']] = dict(
                id=ip_set['Id'],
                lock_token=ip_set['LockToken']
            )
        return ip_sets_dict

    def get_all_ip_sets(scope='CLOUDFRONT', limit=100, next_marker=None):
        """[全てのIP setsの情報を取得する]

        Args:
            scope ([str], optional): [スコープ]. Defaults to CLOUDFRONT.
            limit ([int]): [取得上限値]
            next_marker ([list]): [次の取得マーカー]. Defaults to None.

        Returns:
            [list]: [IP setsの情報]
        """

        all_ip_sets = []

        # 初回実行の場合
        if next_marker is None:
            ret = waf.list_ip_sets(Scope=scope, Limit=limit)
        # 次のデータが存在する場合
        else:
            ret = waf.list_ip_sets(Scope=scope, Limit=limit, NextMarker=next_marker)

        if 'NextMarker' in ret:
            all_ip_sets = ret['IPSets'] + get_all_ip_sets(next_marker=ret['NextMarker'])
        else:
            all_ip_sets = ret['IPSets']

        return all_ip_sets
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SmallTrainを使って簡単な転移学習を実行

今回は先日オープンソース化したGeek Guild社が提供しているSmallTrainを使って
簡単な転移学習を実行したレビューをします。
(本記事はGeekGuild様より依頼を受けて書いています)

記事作成にあたり公式HPに記載されているチュートリアルを参考にしています。

作成するモデルの概要

SmallTrainの学習デモを応用して自作の熊の画像認識を行うモデル、熊: 0 , 哺乳類(猫,鹿,犬,馬): 1 , 乗り物(飛行機,車,船,トラック): 2 として認識するモデルを作成します。

環境構築

今回はAWSのGPUインスタンス上で実行しています。
方法については以下を参照してください。

1つ目のリンクについてはGPUインスタンス使用のための制限緩和のリクエストについての説明のため必要がなければ2つ目のリンクのみ参照してください。
リンク先にも記載がありますがGPUインスタンスの利用額はCPUのものより高額のため利用の際は注意が必要です。

データの準備

学習のための画像を準備します。熊以外の画像についてはデモで使用されているCIFAR10の画像を流用しています。
SmallTrainのソースに含まれるconvert_cifar_data_set.pyを参考に作成しました。
CIFAR-10とCIFAR100ではフォルダ構成が異なっており多少工夫が必要ですが画像ファイルの仕様は同一のため比較的簡単にデータを準備することができます。
こちらで今回の記事で利用した修正後のソースを公開しておりますのでご自身で差し替えて頂く(/var/smalltrain/tutorials/image_recognition/convert_cifar_data_set.py)か公開しているブランチをクローンして頂ければと思います。
※注意:今回はあえて上書きしているため以前のチュートリアルが実行できなくなります。以前の状態に戻すには再度オリジナルのSmallTrainをcloneしてください

熊の画像

CIFAR-100を利用しています。
CIFAR-100では熊の画像はClassは3に分類されており、このクラスの画像のみ取得しています。
再定義後のクラスは0としています。

データセット作成

チュートリアルのこちらのページを参考に作成します。
データセット定義ファイル(/var/data/cifar-10-image/data_set_def/train_cifar10_classification.csv)に以下の行が作成されるようにします。

data_set_id,label,sub_label,test,group
/var/data/cifar-10-image/data_batch_1/data_batch_1_i90000_c0.png,0,0,0,TRAIN
...
/var/data/cifar-10-image/data_batch_5/data_batch_5_i90099_c0.png,0,0,0,TRAIN
/var/data/cifar-10-image/test_batch/test_batch_i90000_c0.png,0,0,1,TRAIN
...
/var/data/cifar-10-image/test_batch/test_batch_i90099_c0.png,0,0,1,TRAIN

CIFAR100のデータはバッチに分けられていないのでdata_batch_1からdata_batch_5まで均等に分けるようにします。
番号を90000から振っているのはdata_batch_1とtest_batchの9から始まるデータのみを使った同時実行されるスモールデータ学習利用のためです。

熊以外の画像

CIFAR-10を利用しています。
10個のClassを2種類に分けて再定義しています。

元のClass 今回のClass
3,4,5,7 (猫,鹿,犬,馬) 1 (哺乳類)
0,1,8,9 (飛行機,車,船,トラック) 2 (乗り物)

Class1と2でデータ数を揃えるため2(鳥),6(カエル)は除外しています。
データセット定義ファイル(/var/data/cifar-10-image/data_set_def/train_cifar10_classification.csv)に以下の行が作成されるようにします。

data_set_id,label,sub_label,test,group
/var/data/cifar-10-image/data_batch_1/data_batch_1_i0_c2.png,2,2,0,TRAIN
...
/var/data/cifar-10-image/data_batch_5/data_batch_5_i90099_c0.png,0,0,0,TRAIN
/var/data/cifar-10-image/test_batch/test_batch_i0_c1.png,1,1,1,TRAIN
...
/var/data/cifar-10-image/test_batch/test_batch_i90099_c0.png,0,0,1,TRAIN

画像ファイル自体はデータセット定義ファイルに記載されているパスに格納します。
元のClassの画像はbatchあたり1000個あるためClass0:Class1:Class2のデータ比率は100:4000:4000となります。
Class0の画像だけ少ないデータセットとなっています。

学習の実行

SmallTrainをAWSのGPUインスタンスで動かすページの
「dockerイメージを実行します。」以降を実施します。

実行結果の確認

チュートリアルにあるように学習後の予測結果を確認します。(less /var/data/smalltrain/results/report/IR_2D_CNN_V2_l49-c64_TUTORIAL-DEBUG-WITH-SMALLDATASET-20200708-TRAIN/prediction_e35999_all.csv)

DateTime,Estimated,MaskedEstimated,True
/var/data/cifar-10-image/test_batch/test_batch_i0_c1.png_0,1,0.0,1
/var/data/cifar-10-image/test_batch/test_batch_i1_c2.png_0,2,0.0,2
/var/data/cifar-10-image/test_batch/test_batch_i2_c2.png_0,2,0.0,2
/var/data/cifar-10-image/test_batch/test_batch_i3_c2.png_0,2,0.0,2
/var/data/cifar-10-image/test_batch/test_batch_i4_c2.png_0,2,0.0,2
...
/var/data/cifar-10-image/test_batch/test_batch_i90095_c0.png_0,0,0.0,0
/var/data/cifar-10-image/test_batch/test_batch_i90096_c0.png_0,0,0.0,0
/var/data/cifar-10-image/test_batch/test_batch_i90097_c0.png_0,0,0.0,0
/var/data/cifar-10-image/test_batch/test_batch_i90098_c0.png_0,0,0.0,0
/var/data/cifar-10-image/test_batch/test_batch_i90099_c0.png_0,0,0.0,0

上記の例では分類が正しく行われていることが確認できます。もちろん
以下の表はtest accuracyと個別の画像の精度をまとめており、画像はTensorBoardのtest accuracyのグラフとなっています。
今回の検証は5時間程度の計算の結果となっています。気軽に画像認識モデル作成が体験できます。

epoch 15999 35999
test accuracy 0.9762 0.973
熊画像以外の精度 0.9826 0.9723
熊画像のみの精度 0.46 0.73

test_accuracy.png

熊画像以外のデータ数が非常に多いため熊画像以外の精度が高く、test accuracyに大きく寄与しています。
test accuracyが最大なのはepoch15999ですが熊画像のみの精度が0.46と低くなっています。
epoch35999はtest accuracyは少し低いですが熊画像のみの精度が0.73と大きく向上していることが分かります。

今回はデモの設定をそのまま流用しているためチューニングすれば精度は上がるはずです。
画像とデータセット定義ファイルを準備するだけで簡単に画像認識モデル作成がきるのでぜひ試してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】AWSデプロイ中にCould not find aws-eventstream-1.1.0 in any of the sources Run `bundle install` to install missing gems.

EC2内でDBを作成しようとしたところエラーが出て詰まったので忘備録として書きます

EC2内でデータベースを作成しようと下記のコマンドを実行したところ
ターミナル(EC2内で実行)
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ rails db:create RAILS_ENV=production
Could not find aws-eventstream-1.1.0 in any of the sources
Run `bundle install` to install missing gems.

とエラー
どうやらどのソースでもaws-eventstream-1.1.0が見つかりませんでしたbundle installを実行して、不足しているgemをインストールします。と言われているよう...
まずGemfileをのぞくが
Gemfile
gem "aws-sdk-s3", require: false

一番下に記述はしっかりあることを確認。

Gemfile.lockをのぞきにいくが
63行目に以下の記述は入っている
Gemfile.lock
aws-eventstream (1.1.0)

bundleinstallのし忘れかと思い履歴を見るがしっかりEC2内にて参考資料通り実行済み、
作業を一度ふり返るが特にミスした形跡も見当たらずもちろんググってみるがあまり参考になる記事も見つけられず。
どうやら開発環境ではaws-eventstream (1.1.0)は存在するが本番環境では適用されてないのだとあたりをつけて

念のためもう一度bundle install
ターミナル(EC2内)
[ec2-user@ip-10-0-0-25 <リポジトリ名>]$ bundle install
Using actionmailer 6.0.3.3
Using actiontext 6.0.3.3
Using public_suffix 4.0.6
Using addressable 2.7.0
Using ast 2.4.1
Fetching aws-eventstream 1.1.0
Installing aws-eventstream 1.1.0
Fetching aws-partitions 1.399.0
Installing aws-partitions 1.399.0
Fetching aws-sigv4 1.2.2
Installing aws-sigv4 1.2.2
Fetching jmespath 1.4.0
Installing jmespath 1.4.0
Fetching aws-sdk-core 3.109.3
Installing aws-sdk-core 3.109.3
Fetching aws-sdk-kms 1.39.0
Installing aws-sdk-kms 1.39.0
Fetching aws-sdk-s3 1.85.0
Installing aws-sdk-s3 1.85.0

と、どうやらinstall されていなかったようです。
再度
ターミナル(EC2内)
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ rails db:create RAILS_ENV=production
Created database '<データベース名>'

と成功!!
今回原因はbundleinstallし忘れだったようだが、他のgemはしっかり反映されてたのでそれが原因突き止められなかったがしっかり一つ一つ検証していき可能性を消していく作業が大事だと感じた。
同じような症状で悩まれるかたに是非参考になればと思い書かせていただきました。最後まで読んでいただきありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Serverless Frameworkを使用して AWS Lambdaにデプロイ

環境

  • Mac OS Catalina 10.15.7
  • AWS Lambda
  • Serverless Framework standalone (
    • Framework Core: 2.11.1 (standalone)
    • Plugin: 4.1.2
    • SDK: 2.3.2
    • Components: 3.3.0

Serverless Framework スタンドアロンのインストール

nodeのバージョン依存に関係なく使用するため、npmでのインストールではなくスタンドアロンを使用した
Get started with Serverless Framework Open Source & AWS に記載の通り

curl -o- -L https://slss.io/install | bash

AWSのクレデンシャルの設定

AWS - Credentialsを参考にCredentialを作成し、それをローカルに適用する.
適用の方法はいくつかあるが、環境変数に設定する方法で対応した

sls plugin install -n serverless-python-requirements

serverless.ymlを作成

service: funcname

plugins:
  - serverless-python-requirements
package:
  individually: true
  exclude:
    - package.json
    - package-lock.json
    - ./**

custom:
  pythonRequirements:
    usePipenv: false
    dockerizePip: true

provider:
  name: aws
  runtime: python3.8
  stage: dev
  region: ap-northeast-1

functions:
  fnc:
    runtime: python3.8
    handler: funcname.handler
    package:
      include:
        - "src/*.py"

dockerize Trueの場合

Dockerのインストールが必要なので、Dockerをインストールする -> 参考

packageのインストール

必要なパッケージをインストールする

serverless-python-requirements

serverless-python-requirements はpythonの依存パッケージをインストールするための仕組み
serverless.yml と共にrequirements.txtを配置しておくと依存パッケージをまとめてLambdaにアップロードしてくれる

sls plugin install -n serverless-python-requirements

AWS Lambdaにデプロイ

sls deploy -v
# -v:ログの詳細表示

AWS Lambda削除

sls remove -v

参考

qiita-Serverless FrameworkでAWS Lambdaをデプロイ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS ElasticsearchService のインデックス自動削除

(ただのメモです)
IMSで30日でインデックス削除するインデックスポリシーを作成し、インデックステンプレートでインデックス作成時に自動でアタッチするようにする

KibanaやKibanaのDev Toolsで操作

インデックスポリシー作成

インデックスポリシー名:all_delete
内容:30日で削除

スクリーンショット 0002-11-27 8.42.32.png

{
    "policy": {
        "policy_id": "all_delete",
        "description": "Demonstrate a hot-warm-delete workflow.",
        "last_updated_time": 1606349256304,
        "schema_version": 1,
        "error_notification": null,
        "default_state": "hot",
        "states": [
            {
                "name": "hot",
                "actions": [],
                "transitions": [
                    {
                        "state_name": "delete",
                        "conditions": {
                            "min_index_age": "30d"
                        }
                    }
                ]
            },
            {
                "name": "delete",
                "actions": [
                    {
                        "delete": {}
                    }
                ],
                "transitions": []
            }
        ]
    }
}

テンプレート更新

テンプレートへの部分的な変更適用ができないので(多分)、既存のテンプレートがあればそれを元に、変更箇所を追加してPUTでテンプレートをまるごと作り直す。上書き更新的な感じ

今回既存のCloudTrailテンプレートがあったので、それを"GET _template/log-aws-cloudtrail"して、出力結果に以下を追加した。そしてそれをPUT

"opendistro.index_state_management.policy_id": "all_delete"

PUT _template/log-aws-cloudtrail
{
    "index_patterns" : [
      "log-aws-cloudtrail-*"
    ],
    "settings" : {
      "index" : {
        "mapping" : {
          "total_fields" : {
            "limit" : "3000"
          },
          "ignore_malformed" : "true"
        }
      },
      "opendistro.index_state_management.policy_id": "all_delete"
    },
    "mappings" : {
      "properties" : {
        "additionalEventData.vpcEndpointId" : {
          "type" : "keyword"
        },
        "requestParameters.instanceType" : {
          "type" : "keyword"
        },
        "eventID" : {
          "type" : "keyword"
        },
        "requestParameters.filter" : {
          "type" : "text"
        },
        "awsRegion" : {
          "type" : "keyword"
        },
        "responseElements.lastModified" : {
          "type" : "date"
        },
        "requestParameters.maxResults" : {
          "type" : "integer"
        },
        "responseElements.version" : {
          "type" : "keyword"
        },
        "responseElements.role" : {
          "type" : "text"
        },
        "errorCode" : {
          "type" : "keyword"
        },
        "requestParameters.MaxResults" : {
          "type" : "integer"
        },
        "requestParameters.sort" : {
          "type" : "keyword"
        },
        "requestParameters.endTime" : {
          "format" : "MMM dd, yyyy hh:mm:ss a||epoch_millis",
          "type" : "date"
        },
        "requestParameters.bucketPolicy.Statement.Principal" : {
          "type" : "text"
        },
        "requestParameters.sortBy" : {
          "type" : "text"
        },
        "requestParameters.startTime" : {
          "format" : "MMM dd, yyyy hh:mm:ss a||epoch_millis",
          "type" : "date"
        },
        "requestParameters.DescribeFlowLogsRequest" : {
          "type" : "text"
        },
        "requestParameters.maxItems" : {
          "type" : "integer"
        },
        "requestParameters.attribute" : {
          "type" : "text"
        }
      }
    },
    "aliases" : { }
}

確認

適当にインデックス作成

PUT log-aws-cloudtrail-2021-01-01/ 

テンプレートのマッピングに該当するインデックスが作成され、テンプレートに追加したポリシーがアタッチされるか!?
index_state_managementにpolicyがアタッチされていることがわかります

GET log-aws-cloudtrail-2021-01-01/
          "ignore_malformed" : "true"
        },
        "opendistro" : {
          "index_state_management" : {
            "policy_id" : "all_delete"
          }
        },
        "number_of_shards" : "3",

KibanaのIMSからもpolicyのall_deleteがアタッチされてるのがわかります

スクリーンショット 0002-11-27 8.36.16.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python3 PermissonError解決策

今回python3で簡易アプリケーションを作成後AWS EC2でデプロイしようとした時に発生したエラーについて原因と解決策を書いてみました


エラー内容

Djangoの管理サイトからPostsアプリケーションで投稿を行うと

スクリーンショット 2020-11-27 7.29.41.png
PermissonError
スクリーンショット 2020-11-27 6.41.32.png


原因

Filezillaを使用してローカルからサーバーへプロジェクトをアップロードする際に

$sudo unzip [プロジェクト名].zip

としていたためrootがオーナーになっておりsudoをつけてroot権限で解凍してしまったのが原因で、サーバープロセスから書き込みが出来なくなっていた。

スクリーンショット 2020-11-27 6.50.31.png


解決策1

アップロードしたプロジェクトを一回削除してsudoを使用せず、プロジェクトのzipファイルを解凍し直す方法

$unzip [プロジェクト名].zip

sudoを使わないコマンドで実行すると一般ユーザーであるubuntuユーザーがオーナーとしてファイル群が生成される


解決策2

パーミッションを変更する方法

$sudo chown -R ubuntu:ubuntu [プロジェクト名]

を実行することでオーナーを変更できる

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS GlueのCrawler(クローラ)をAWS CDKで生成する

概要

  • S3にたくさん投入したデータをAthenaでサクッと分析・集計できるようにする際、Glue Crawlerが非常に便利。
  • CDKで構築した例はまだあまりなかったので記事化。

S3の設定について

  • 先日の記事で考察したが、S3はいまのところ手動設定したものを利用しても良いように思う。

Glueの設定について

ソースコード例

たとえばこんな感じ。

import * as cdk from '@aws-cdk/core';
import * as iam from '@aws-cdk/aws-iam';
import * as glue from '@aws-cdk/aws-glue';
import * as s3  from '@aws-cdk/aws-s3';

export class MyStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const myBucketName = 'my-bucket';
    const myCrawlerName = 'myCrawler';
    const myCrawlerRoleName = 'myCrawlerRole';
    const myAthenaDBName = 'my_db';

    const myBucket = s3.Bucket.fromBucketName(this, myBucketName, myBucketName);

    const myCrawlerRole = new iam.Role(this, myCrawlerRoleName, {
      assumedBy: new iam.ServicePrincipal('glue.amazonaws.com')
    });
    myCrawlerRole.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole'));
    myCrawlerRole.addToPolicy(
      new iam.PolicyStatement({
        effect: iam.Effect.ALLOW,
        resources: [`${myBucket.bucketArn}/path-to-object-parent/*`],
        actions: ["s3:GetObject", "s3:PutObject"]
      })
    );

    const myCrawler = new glue.CfnCrawler(this, myCrawlerName, {
      role: myCrawlerRole.roleArn,
      databaseName: myAthenaDBName,
      targets: {
        s3Targets: [{ path: `${myBucket.s3UrlForObject()}/path-to-object-parent/` }]
      },
      configuration: '{"Version": 1.0, "Grouping": {"TableGroupingPolicy": "CombineCompatibleSchemas"}}'
    });
  }
}

まだ良くわからないこと

わかる方いらっしゃいましたら教えてほしいです。

  • Constructの「id」の活用方法。今のところ適当。
  • S3もCDKで管理できたら良いけど、CDK(というかIaC?)の利点を活かせるやりかたは今のところ不明。
  • TypeScriptはまだ1週間ほどしか触っていないので、いろいろ不安。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【実験】AWS Workspacesで3つのサブネットにそれぞれ配置できるか?

AWS Workspacesで3つのサブネットにそれぞれ配置できるか?

On-PremにあるAD環境をAWSにリフトアップしてみようと検証を試みた記録です

前提条件

  • 同一認証基盤を利用したい
  • ネットワークセグメントが3つある

検証環境のイメージ

以下のような構成で検証を進めました。

機能としてはセカンダリといいつつつ、
ターシャリ(3番目)もアタッチ可能なVPCのセカンダリCIDRを使います。
Associating a secondary IPv4 CIDR block with your VPC

AWS Integration ap-northeast-1 (1).png

結論

  • 不可能でした
    • Workspacesで利用する認証基盤として以下の3つを用意しましたが、いずれも認証で利用可能なサブネットが2つまでしか選択できないため、一つの基盤で運用はできないことが分かりました

検証画像

3パターンのディレクトリサービスを立ち上げました。

image.png

例)SimpleAD

Registerで色々見ましたが、ポップアップが出てくるが選択可能なサブネットは2つまでしか選べない。

image.png

その他

ADConnector でターゲットとして予定していたEC2について

予め利用するサブネットごとにENIを用意して、EC2のプライベートIPアドレスは固定化します

image.png

AWS公式ドキュメントにあるElastic Network Interfaceに従って、
今回、NICを4つ採用する(インスタンス通信用1つ、Workspaces用だった3つ)ため、
t3.xlarge 以上のインスタンスが必要となります。

実際、Windowsで起動したインスタンスにもNICを接続して問題なく通信ができるところまで確認できました。
ADDSをインストールするため、 getmac /Vipconfig /allでOSが認識しているインターフェースとIPアドレスの範囲を間違えないようにOS上からもIPアドレス固定化しました。

image.png

まとめ

今回検証してみて、元々On-Premで出来ていたからクラウドでも出来るだろうとの見切り発車ではなく、
軽く作ってみようとクラウドらしくスモールかつクイックにやってみることの重要性を改めて感じました。
今回は、目的である環境の移設については、改めて構成検討から始めようと思います。

1台で賄っていたユーザをSimpleADを2台に分散するとして、おおよそ72USDなので、
分散管理になっていくかなとぼんやり考えています。

Simple AD スモールディレクトリへの月々の課金 (30 日後または 1,500 時間の無料トライアル期間終了後)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む