20200818のAWSに関する記事は18件です。

AWS初心者が概要をざっくりまとめる(メモ書き)

はじめに

AWSについて最低限の知識を得るために、AWS認定資格の1つである「クラウドプラクティショナー」の対策本を読み、ざっくりまとめたいと思います。

■セキュリティ

AWSではセキュリティの責任の所在を、AWS社とユーザで分けている。
‐AWS対応:データセンターの設備・環境・ハードウェア、ハイパーバイザー
‐ユーザ対応:上記以外のもの(OS、アプリケーション、ユーザのID・パスワードなど)
ただしAWSが提供するサービス内容(マネージドかそうでないか)に依って線引きは異なり、基本的にはユーザが触れられない部分をAWS、それ以外をユーザが担当する形となっている。

「IAM」(クラウドへのアクセス管理サービス)を設定することで、様々なサービスへのアクセス権を一括で制御することができる。
そのほか、DDos攻撃から保護する「AWS Shield」や、ファイヤウォール機能を果たす「AWS WAF」などのサービスがある。

■リージョンとアベイラビリティゾーン

リージョンは全世界にあり、リージョン内には必ず2つ以上のアベイラビリティゾーン(AZ)が存在する。また、1つのAZは複数のデータセンターから構成されている。(データセンター単位、AZ単位で停電や自然災害などの障害が起こった場合の可用性を担保するため)
ユーザは任意のリージョンを選択して使用することができる。また複数のリージョンを使用することも可能。(東京とサンパウロなど)

■VPC

「Amazon Virtual Private Cloud」の略。プライベートなネットワーク環境。リージョン内の複数のAZをまたがって構築可能。
1つのVPCに対してインターネットゲートウェイを1つのみ作成する。
サブネットは、VPCで設定したIPアドレスの範囲内で、AZとIPアドレスを指定して作成する。リソースに応じて、外部接続できる「パブリックサブネット」と、外部接続せずにリソースを保護する「プライベートサブネット」に分けることが可能。

主なサービス

■EC2

「Amazon Elastic Compute Cloud」の略。サーバ。
主なメリット:
・必要な時に必要なだけ利用可能
→不足や遊びを減らして柔軟に対応できる。

・コストは使用した分だけ
→インスタンスの稼働時間単位で課金。アウト通信(リージョンの外部)で転送料金が発生。

・変更可能なインスタンスタイプから性能を選択
→運用しながら適切なタイプに変更可能。インスタンスタイプによって課金単価が異なる。

・セキュリティグループでトラフィック制御可能
→複数のインスタンスをセキュリティグループと設定し、トラフィックのインバウンド制御可能。

・数分で調達と起動が可能
・世界中のリージョンから起動場所を選択可能
・AMIによっていくつでも同じサーバを起動可能

■ELB

「Elastic Load Balancing」の略。負荷分散装置。
・ロードバランサータイプ
→HTTP・HTTPSのリクエストでは「Application Load Balancer」、それ以外のTCP通信では「Network Load Balancer」を用いる
・ヘルスチェック
→正常なインスタンスかの判断
・インターネット向け/内部向けの選択可能
→ELBのDNS名にパブリックIPアドレスとプライベートIPアドレスどちらが紐づくかで設定が変わる
・クロスゾーン負荷分散
→AZを超えて負荷分散することが可能

■Auto Scaling

EC2インスタンスを必要に応じて自動で増減することが可能。(数の増減=水平スケーリング)
どのようなインスタンスを、どこで、どのタイミングで起動するのかを事前に設定する。

■Lambda

ソースコードさえ用意すれば、自動で実行してくれるサービス。
主なメリット:
・サーバ構築/管理が不要
→OS、ミドルウェアインストール、セキュリティパッチ適用などの対応不要

・一般的な言語に対応
→C#、Java、python、Rubyなどで実行可能

・並列処理
複数リクエストを並列処理可能、自動でスケーリングを行う

・ミリ秒単位で課金
実行されている時間単位で課金され、待機時間は課金対象とならない

・他のAWSサービスとの連携
→S3へのデータアップロード、特定の時間などをトリガーとし、サービス同士をつなげることが可能

■S3

「Amazon Simple Storage Service」の略。完全マネージド型のオブジェクトストレージ。
主なメリット:
・ストレージ容量が無制限
→上限がないため、容量の不足を気にせず利用することができる。

・高耐久性
→オブジェクトは複数のAZに保存されるため、バックアップや冗長化等を意識しなくてよい(耐久性99.99999999999%)

・インターネット経由でアクセス可能

セキュリティ対策:
・アクセスコントロールリスト(ACL)
→バケット・オブジェクト単位で、読み取り・書き込み権限の制御可能
・バケットポリシー
→ACLよりも細かい単位(任意のディレクトリ以下のオブジェクトなど)で制限可能

料金体系:
・ストレージ料金
→1か月の平均保存料で算出。アクセス頻度が異なるストレージクラスやリージョンによって単価は変わる。
・リクエスト料金
→データのダウンロード・アップロードのリクエストで発生。
・データ転送料金
→リージョン外へ転送した場合に発生。

■RDS

「Amazon Relational Database Service」の略。
MySQL、Oracle、PostgreSQLなどのメジャーどころを利用可能。
EC2にDBをのせることも可能だが、その場合はミドルウェアの管理が必要となる。RDSではその部分が不要となる。また、バックアップもデフォルトで7日間自動で適用される。

■DynamoDB

非リレーショナルデータベース、NoSQL型のデータベースサービス。1つのデータは項目として格納され、キーに紐づく属性は動的で不定形。厳密なトランザクションには向かないが大量のアクセスがある場合には有効。

あとがき

かなりざっくり、そしてポイント絞っていますが、導入の導入くらい(?)は認知できたんじゃないかなと思っています。
(そもそもインフラ側の人間ではないので、インスタンスの意味がわからなかったりしましたが、それを知れただけでもヨシ!としましょうね。。)

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

RailsをAWS ECS(Fargate)でホストする環境構築のすべて【3. ECSへのデプロイ、SSMによる接続】

前記事

RailsをAWS ECS(Fargate)でホストする環境構築のすべて【2. Docker定義、ECRの設定】
https://qiita.com/polar_bear_tech/items/87f5795346d246a1e07c

ECRにコンテナイメージをプッシュするまでを書きました。
今回はECS周辺の設定を行い、デプロイします。
加えて、SSMを使用した操作も行います。

下準備

ECS用セキュリティグループの作成

ECS用のセキュリティグループを作成します。
インバウンドはALBから80ポートと、VPC endpointを介してSSMからの接続のため443ポートを開けています。
スクリーンショット 2020-08-18 21.00.58.png

タスク実行ロールの作成

IAM>ロール>ロールの作成から、タスク実行用のロールを作成していきます。

ECSTask用のユースケースを選択して次へ。
スクリーンショット 2020-08-18 19.01.11.png

スクリーンショット 2020-08-18 19.01.30.png

ECSのタスクを制御するのと、SSMによる操作を行うため、以下のポリシーをアタッチします。

  • AmazonECSTaskExecutionRolePolicy
  • AmazonSSMManagedInstanceCore
  • AmazonSSMAutomationRole
  • AmazonSSMDirectoryServiceAccess

スクリーンショット 2020-08-18 19.01.51.png

スクリーンショット 2020-08-18 19.02.50.png

"ecsTaskExecutionRole"みたいな名前を付けて保存します。

SSMアクティベーションコードの発行

System Manager>ハイブリッドアクティベーションから、アクティベーションの作成を行います。
スクリーンショット 2020-08-18 19.23.14.png

説明と、管理できるインスタンス数(30くらいあれば良いかと思います)、有効期限を入力して作成。
スクリーンショット 2020-08-18 19.24.02.png

作成したら、画面上部にアクティベーションコードとIDが表示されるので控えておいてください。
控え忘れた場合は、もう一度作成すれば大丈夫です。
スクリーンショット 2020-08-18 19.24.10.png

ECSタスク定義

ECS>タスク定義から、新しいタスク定義の作成を押下し、作成していきます。

起動タイプはFargateを選択。
スクリーンショット 2020-08-18 19.04.38.png

タスク定義名を入力。
スクリーンショット 2020-08-18 19.08.01.png

タスク実行ロールに、先ほど作成したタスクを設定。
タスクサイズは、EC2のmedium規模で設定しています。ここは任意のサイズです。
スクリーンショット 2020-08-18 19.08.28.png

コンテナの追加ボタンから、ECRにプッシュしたコンテナイメージを追加していきます。
まずはnginxから、イメージ欄にはECRの一覧画面に表示されているURIをコピーして貼り付けます。
メモリ制限を4GiB、CPUユニット数を1024(1vCPU)に設定します。
スクリーンショット 2020-08-18 19.10.15.png

次はrailsコンテナを追加します。
nginx同様にURIをペーストし、メモリ制限を4GiB、CPUユニット数を1024(1vCPU)に設定します。
起動時に実行するシェル(エントリポイント)もコマンドをカンマ区切りで記載。
スクリーンショット 2020-08-18 19.15.51.png
スクリーンショット 2020-08-18 19.17.06.png

環境変数を設定します。
スクリーンショット 2020-08-18 19.25.08.png

ここで、先ほど取得したSSMのアクティベーションコード・IDを下記の変数名でそれぞれ設定します。

  • SSM_ACTIVATION_CODE
  • SSM_ACTIVATION_ID

その他、必要に応じて下記を設定します。

database.ymlで環境変数からロードするようにしておく値

  • DATABASE_HOST
  • DATABASE_PORT
  • DATABASE_USER
  • DATABASE_PASSWORD

image.png

AWSのAPIアクセス用のキー情報

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

最後にスタートアップ依存順序をnginxのコンテナ側に追加します。
スクリーンショット 2020-08-18 19.26.24.png

コンテナを追加できたらこんな感じになります。
スクリーンショット 2020-08-18 19.27.02.png

以降は初期値のままで、作成まで進めます。

ECSクラスタ作成

ECS>クラスターからクラスターの作成を押下して、作成していきます。

テンプレートはFargate用の「ネットワーキングのみ」を選択。
スクリーンショット 2020-08-18 19.27.51.png

クラスター名を入力し、
CloudWatchでハードウェア監視を行いたい場合はCloudWatch Container Insightsにチェックします。
スクリーンショット 2020-08-18 19.28.51.png

作成したら、クラスターの管理画面になります。
スクリーンショット 2020-08-18 19.29.10.png

ECSサービス定義

最後!クラスター管理画面のサービスタブにある作成ボタンから、作成していきます。

起動タイプはFargate、タスク定義に先ほど作成したタスク定義を選択します。
リビジョンはlatestを選択。
タスク定義はバージョン管理されているので、これを更新したら最新を選んだり、前のリビジョンに戻したりできます。
サービス名を任意の内容で入力。
スクリーンショット 2020-08-18 19.29.54.png

タスク数は2とかにするとバランシングしてくれます。任意の個数指定してください。
デプロイに関してはCodeDeployを使用する場合はB/Gにするなど、任意です。
スクリーンショット 2020-08-18 19.30.29.png

ネットワークは最初に作成しておいたVPCを選択。
サブネットもECSコンテナをのせる予定の2つのサブネットを設定。
セキュリティグループは1つ目の記事で作っておいた、ECS用のセキュリティグループを適用。
パブリックIDの自動割り当ては、有効。(有効じゃないとSSMで接続できなかった気がする)
スクリーンショット 2020-08-18 19.31.09.png

ロードバランサも作っておいたものを選択しましょう。
ロードバランス用のコンテナは、nginxのコンテナを選択し、ロードバランサーに追加ボタンを押します。
スクリーンショット 2020-08-18 19.31.37.png
スクリーンショット 2020-08-18 19.31.58.png

ターゲットグループ名を作っておいたもので選択すると、全部自動入力されるかと思います。
スクリーンショット 2020-08-18 19.32.13.png

サービスの検出オプションは有効にしておきます。
スクリーンショット 2020-08-18 19.32.42.png
スクリーンショット 2020-08-18 19.32.53.png

オートスケーリングは任意で設定してください。
タスク平均のCPU・メモリの使用率や、タスクごとのリクエストの完了数を条件にしてオートスケーリングができます。
スクリーンショット 2020-08-18 19.32.59.png

作成して、タスクタブを開き、しばらくすると、RUNNINGになるかと思います!
スクリーンショット 2020-08-18 19.35.36.png

起動確認

EC2>ロードバランサーからDNS名をコピーして、ブラウザで確認しましょう。
スクリーンショット 2020-08-18 19.36.24.png

ルートはNginxのデフォルトを設定しているので、Nginxの初期画面がでました。
スクリーンショット 2020-08-18 19.37.06.png

SSMの操作

まだもうちょっとだけ。
System Manager>マネージドインスタンスを開くと、SSMで管理されているサーバが表示されます。
アクティベーションコードがうまく設定できていて、entrypoint.shでSSMのエージェントを起動できて、ネットワーク設定も開いていればオンラインとなっているハズです。
スクリーンショット 2020-08-18 19.37.38.png

選択し、アクションから「Start session」を押下すると、
スクリーンショット 2020-08-18 19.37.47.png

CUIが開きます。
Railsのコンテナに入れたので、これで操作可能なのですが、注意点として、ユーザーはssm-userというものになっています。
スクリーンショット 2020-08-18 19.38.36.png

sudoできるユーザーになっていますので、たとえばマイグレーションを行うとしたら、下記のコマンドで実行できます。

$ sudo -E bundle exec rake db:migrate RAILS_ENV=staging

ECSをSSMで管理する場合、課金対象になるかリファレンスから確実なところ読み取れなかったのですが、セッションマネージャでアクセスできるということは課金されると思います。
なので、使い終わったら登録解除しておくと、課金されませんので良いかも。
スクリーンショット 2020-08-18 19.43.06.png

最後に

入門できるまでが遠い門、まさにFargateでした。
こだわると、あとは下記が設定できると良いかと思います。

  • 環境変数はSystemManagerのパラメータストア使ったほうがいいです。
  • CodePipelineで自動デプロイ設定できます。
  • SSM接続のためのアクティベーションコード発行と環境変数への設定は、entrypoint.shでaws-cliつかってできたら手間が減る。

この記事としてはあくまで動作させるまでということで、以上です。

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

[AWS] Step Functionsで遊んでみる(SAM + Lambda) Part.4(結果をSQSに投げる)

Part.3のおさらい

Part3では、主に以下のことを行いました。

  • Lambdaでランダムな結果を返す
  • 結果に応じて、次に実行するタスクを変える
  • リトライ時は、しばらく時間が経ってから再実行する

今回は、その続きからはじめてみます。
ここから始める方は、
https://github.com/hito-psv/sam-demo-005
のコードをgit cloneしてもらっても大丈夫ですし、Part3からやってみてもらっても構いません。

今回のターゲット

  • Lamda関数の戻り値をSQSに投げる

をターゲットにしてみたいと思います。

SQSを定義する

まずは、template.ymlを修正し、

  • SQSの定義そのものを追加
  • SQSのポリシーを追加(Step Functionsから呼べるように)
  • Step FunctionsのポリシーにSQSアクセスを追加

です。
変更後のtemplate.ymlは、こんな感じです。

template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Role: !GetAtt HelloWorldFunctionRole.Arn
  HelloWorldFunctionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
        - arn:aws:iam::aws:policy/AWSStepFunctionsReadOnlyAccess
  StateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      DefinitionUri: step_functions/state_machine.json
      DefinitionSubstitutions:
        HelloWorldFunction: !GetAtt HelloWorldFunction.Arn
        SqsQueue: !Ref SqsQueue
      Role: !GetAtt StateMachineRole.Arn
  StateMachineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaRole
        - arn:aws:iam::aws:policy/AmazonSQSFullAccess
  SqsQueue:
    Type: AWS::SQS::Queue
  SqsQueuePolicy: 
    Type: AWS::SQS::QueuePolicy
    Properties: 
      PolicyDocument: 
        Id: !Ref SqsQueue
        Statement: 
          - Effect: Allow
            Principal: "*"
            Action: "SQS:*"
            Resource: !GetAtt SqsQueue.Arn
      Queues:
        - !Ref SqsQueue

SAMのテンプレートは、基本的にCloud Formationの定義と同等ですので、作成したリソースの情報は、!Ref!GetAtt関数で置き換えることができます。
あと、重要な点が一つあり、StateMachinePropertiesにあるDefinitionSubstitutionsに、SqsQueueの追加をお忘れなく。
これは、Step Functionsのステートマシン定義のファイルで参照する変数名に、値を渡してあげるために必要となります。

念のため、この部分です。

template.yml抜粋
  StateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      DefinitionUri: step_functions/state_machine.json
      DefinitionSubstitutions:
        HelloWorldFunction: !GetAtt HelloWorldFunction.Arn
        SqsQueue: !Ref SqsQueue
      Role: !GetAtt StateMachineRole.Arn

ステートマシンの定義を追加する

続いては、ステートマシンの定義です。
Part.3では、最後に「hello world 2」を呼び出し、終了していましたが、終了せずにSQSに返却値をSendMessageで送信するように修正してみたいと思います。

step_functions/state_machine.json
{
  "StartAt": "hello world 1",
  "States": {
    "hello world 1": {
      "Type": "Task",
      "Resource": "${HelloWorldFunction}",
      "Parameters": {
        "p1.$": $.p1,
        "p2.$": "$.p2",
        "p3": {
          "p3-1": 20,
          "p3-2": "xyz"
        },
        "all.$": "$"
      },
      "ResultPath": "$.hello_world_result",
      "OutputPath": "$",
      "Next": "check state"
    },
    "retry lambda": {
      "Type": "Task",
      "Resource": "${HelloWorldFunction}",
      "InputPath": "$",
      "ResultPath": "$.hello_world_result",
      "OutputPath": "$",
      "Next": "check state"
    },
    "check state": {
      "Type" : "Choice",
      "Choices": [
        {
          "Variable": "$.hello_world_result.body.message",
          "StringEquals": "hello world",
          "Next": "hello world 2"
        },
        {
          "Variable": "$.hello_world_result.body.message",
          "StringEquals": "retry",
          "Next": "wait state"
        }
      ],
      "Default": "fail state"
    },
    "wait state": {
      "Type": "Wait",
      "Seconds": 5,
      "Next": "retry lambda"
    },
    "hello world 2": {
      "Type": "Task",
      "Resource": "${HelloWorldFunction}",
      "InputPath": "$",
      "ResultPath": "$.hello_world_result",
      "OutputPath": "$",
      "Next": "send queue"
    },
    "send queue": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sqs:sendMessage",
      "Parameters": {
        "QueueUrl": "${SqsQueue}",
        "MessageBody.$": "$"
      },
      "End": true
    },
    "fail state": {
      "Type": "Fail",
      "Cause": "No Matches!"
    }
  }
}

変更部分のみの抜粋は、以下の場所です。

step_functions/state_machine.json抜粋
    "hello world 2": {
      "Type": "Task",
      "Resource": "${HelloWorldFunction}",
      "InputPath": "$",
      "ResultPath": "$.hello_world_result",
      "OutputPath": "$",
      "Next": "send queue"
    },
    "send queue": {
      "Type": "Task",
      "Resource": "arn:aws:states:::sqs:sendMessage",
      "Parameters": {
        "QueueUrl": "${SqsQueue}",
        "MessageBody.$": "$"
      },
      "End": true
    },

hello world 2では、ResultPath、OutputPathに戻り値を入れ直して、次のステートをsend queueにします。
send queueでは、作成したSQSのキューURLに対して、直前の出力内容をメッセージとして送信し、終了するように定義しています。

ステートマシンを実行してみる

マネジメントコンソールから、ステートマシンを実行してみましょう。
Part.3からの修正のため、入力値のp1、p2を使用するため、入力蘭を以下のように指定してください。

https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_427998_9aa27f7d-00f7-60d0-5088-bbcf49e0ffea.png

  • p1に、9999数値を指定
  • p2に「p2 strings.」という文字列を指定

結果をみてみる

Step Functions

まずは、ビジュアルフローを確認してみましょう。

sf4.png

成功していることが確認できます。
もちろん「send queue」も実行されています。

SQS

続いて、SQSにメッセージが送信されているかを確認してみましょう。

SQSの管理画面からキューを選択します。

sqs1.png

続いて「メッセージを送受信」ボタンを押します。

sqs2.png

キューにメッセージが1件あるので「メッセージをポーリング」ボタンを押して取り出してみましょう。

sqs3.png

IDをクリックしてメッセージの中身をみてみましょう。

sqs5.png

本文タブを選択すると、メッセージの中身が確認できます。
Lambdaからの戻り値がSQSに送信されてきたことが確認できました!

sqs6.png

まとめ

今回は、SQSをタスク実行してみましたが、他にも多数のAWSサービスガStep Functionsからタスク実行できます。
いずれも気をつけないといけないのは

  • 実行ロール(Step Functions側、サービス側(必要に応じて))の設定
  • ステートマシン定義ファイルへの、必要な情報の引き渡し(DefinitionSubstitutions

です。それ以外は、サービスによってパラメータは異なりますが、考え方はそう大きく違いはありません。
Step Functionsをうまく活用することで、サーバーレスなサービスをワークフロー的に流すことがとても簡単にできます。
Step Functions自体は、まだまだ進化が続いているので、これからますます利用機会が増えるかもしれませんね。

サンプルコードリポジトリ

https://github.com/hito-psv/sam-demo-007

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

【GitHub×AWS】Permission denied (publickey). fatal: Could not read from remote repository.でGit pushできない時の対処法

前提条件

・AWS Cloud9(IDE)を使用
・GitHubをコードのバージョン管理として使用

エラー内容

$ git push origin master
Permission denied (publickey). fatal: Could not read from remote repository.  Please make sure you have the correct access rights and the repository exists.

「公開鍵がないため、許可が却下されました。リモートリポジトリから読み込めません。正しいアクセス権限があるか、レポジトリが存在しているか確認して下さい。」という内容。

原因

GitHubに公開鍵の登録がないため、アクセス権限がなく拒否をされてしまった。

対処法

SSH鍵の作成

1.下記コマンドを入力。your_email@example.comはGitHubで登録しているメールアドレスに置き換える。

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

2.Enter a file in which to save the keyで何も入力せず、エンターを押す。こうするとデフォルトのファイルの場所に作成される。

> Enter a file in which to save the key (/home/you/.ssh/id_rsa): [Press enter]

3.パスワードを設定する。確認も含めて2回入力する。

> Enter passphrase (empty for no passphrase): [Type a passphrase]
> Enter same passphrase again: [Type passphrase again]

ssh-agentにSSH鍵を追加

1.バックグラウンドでssh-agentを起動させる。

$ eval "$(ssh-agent -s)"
> Agent pid 59566

2.ssh-agentにSSH鍵を追加させる。

$ ssh-add ~/.ssh/id_rsa

SSH鍵をGitHubアカウントに追加

1.公開鍵の内容を下記のコマンドで表示。表示されたものをコピーする。この時スペースや改行などが入ると認識できないため、入らないように注意する。

cat ~/.ssh/id_rsa.pub

2.GitHubに行き、Settingsを選択。
スクリーンショット 2020-08-18 12.57.28.png

3.SSH and GPG keys>SSH keys> New SSH keyを選択。
スクリーンショット 2020-08-18 12.58.57.png

4.Titleに名前をつけて(なんでも良い)、Keyに先ほどコピーした公開鍵を貼り付ける。万が一無駄なスペースなどが入ってしまったら、この時点で削除する。そしてAdd SSH keyボタンを選択する。
スクリーンショット 2020-08-18 13.01.49.png

エラーが出ずに鍵が作成されたら成功。

SSHの疎通確認

1.下記のコマンドを実行し、最後の方に...successfully authenticated...が表示されればSSHの疎通がされたことが確認できる。

$ ssh -T git@github.com

こうして鍵を登録したアカウントの権限があるリポジトリが、操作できるようになる。

参考
https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent
https://docs.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account
https://utano.jp/entry/2017/10/amazon-linux-github-ssh-key/

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

50過ぎのオッサンが、AWS認定セキュリティ - 専門知識(SCS)に合格した日記

はじめに

2020年3月にソリューションアーキテクト - プロフェッショナル(SAP)に合格した。AWSの勉強は継続しようと思っていたが、(業務でバリバリ使っているわけではなく、)漠然とやっていても続かないので、今回も試験を目標とすることにした。AWS認定試験の専門知識の中から「セキュリティ」を選んだ。クラウドになってセキュリティは最も重要テーマであるということ(建前)と、Web上の合格体験記などを見ていると専門知識の中では比較的取りやすいというようなことも書いてあったため(本音)である。やはり試験を受けるからには受かりたいのである。今回は、コロナの影響で試験会場が閉鎖されてしまい、一時期試験が受けれないとか、在宅勤務になったことで勉強する環境ががらっと変わったりいろいろあったが、今回も1回目の受験で無事合格することができた。もちろん今回もガッツリ勉強したことで勝ち取った合格である。

使用した教材

日記

2020年3月某日 - 勉強スタート!

まず情報を集める

Amazonで「AWS認定セキュリティ - 専門知識」の日本語のテキストや問題集を探したが、見つけられなかった(※)。なので、今回もKindleの英語版のテキストと問題集を探した。そこで、見つけたものは"使用した教材"に書いている。その中でも「Zean Vora本」が素晴らしい。この本は、SCS試験の5つのドメイン毎に章が作られ、各章は、スナップショットをたくさん使って操作例を含めて説明していて、とても理解しやすい。また、章末にはその理解を確認する問題も用意されている。問題数は多くないが、今回はこの本を中心に進めることにした。ちなみに、著者のZean Voraは、Udemyで、AWS Certified Security Specialty 2020の作成者である。もちろん、「Zean Vora本」をやりつつ問題集もガッツリやる。
(※)今は、要点整理から攻略する『AWS認定 セキュリティ - 専門知識』(Compass Booksシリーズ) 2020/7/9発行、という教科書的な本がある。

勉強法

今回は、「Zean Vora本」という教科書的なテキストを使うので、勉強法として3本線ノート術を使うことにした。ちなみにここで使った3本線ノート術とは、以下のようなやり方である。ノートは見開きで使う。左ページにはテキストの内容をまとめる。右ページは、縦に半分にわけ、右ページの左側には、大切なポイントをまとめ、右ページの右側には暗記することを記述する。こうすることで、右側のページをみれば、必要なところを効率よく復習できるわけである。単語カードを使うのは前回うまくいったので継続する。3本線ノート術の右ページに書いた内容を問題形式にして単語カードに書いて覚えることにした。単語カードは常に持ち歩き、折に触れ、それを見るようにしている。この方がノートを見返すより目にする回数が多くなるので、自分には覚えやすい。ちなみにスマホの単語カードアプリも使ったことがあるが、やはりペンで紙に書く方が覚えられる気がする。これはオッサンが昭和生まれだからかもしれないが。

勉強スタート

「Zean Vora本」を読み、内容を3本線ノート術のノートにまとめていった。「Zean Vora本」は、各章の章末に6~18個の問題がある。第一弾「50過ぎのオッサンが、5ヶ月間勉強しまくってAWS CLF,SAA,SAPに合格するまでの日記」にも書いたが、私は石橋を叩いて渡る性格なので、これくらいの問題数では全く安心できない。SCSの問題として見つけたのが、"使用した教材"に書いた「サンプル問題」「Exam Readiness」「IP Specialist本」「skillcert pro本」である。なので、これをやった。本は違っても同じような問題がいくつかあり、なんとなくSCSの問題の傾向が見えてきた(気がする)。もちろん間違えた問題は、一旦ノートにまとめておき、そのノートから単語カードに転記し、それを何度も見直すことを行った。

2020年5月某日 - 模擬試験を受験

そこそこ自信もついてきたので、SCSの模擬試験を受けてみるとことにした。SCSの模擬試験は4000円(税別)だが、AWS CLF、SAA、SAPと受かっており、それの特典としてそれぞれ模擬試験の無料受講券があり、まだ使っていなかったので、これを使って模擬試験を受けることにした。結果は80%。合格ラインは750点/1000点なので、ちょっとヤバい。模擬試験では、それぞれの問いに対して自分の回答があっていたかどうかはわからない。ただし、ドメイン毎の正答率は教えてもらえるので、ドメイン単位で自分の弱点がわかる。「Zean Vora本」は、ドメイン毎の章構成なので、弱点の部分のノートを中心に見直した。手持ちの問題集はほぼ覚えたので、Black Beltで最終確認することにした。SAPの勉強をしていた時に、pdfをiPadに入れていたので、それを読んだ。Black Beltは、KMS、IAMなどSCSに関連する部分を中心に復習した。

2020年5月某日 - 試験が受けれない

そうこうしているうちに緊急事態宣言が発令され、試験が受けられなくなった。試験が受けられなくなったことで、SCSの勉強も何をすればよいかもわからなくなり、なんとなく一旦止めてしまった。

2020年7月某日 - 再始動

Qiitaを日々眺めていると、AWS認定セキュリティ専門知識(SCS)を、1年の空白期間を経て取得したやったことまとめを見つけた。とても参考になり、また試験を受けようという気分になってきた。そこで、まず、8月某日に受験、その1週間前に模擬試験を受験することに決め、Qiitaのサイトを参考に2週間で総仕上げすることにした。ここでのやったのは、Qiitaのサイトに書かれていたBlack Beltの再見直しと、ホワイトペーパーを読むことである。最初の1週間でそれを実施し、2回目の模擬試験で腕試しをし、その結果をもとに今回メインで使っている「Zean Vora本」を見直すことにした。

2020年7月某日 - 模擬試験2回目

7月某日に2回目の模擬試験を受けた。前の試験に合格したときの特典が残っていたので、それを活用した。結果は95%だった。大分、自信がついてきた。この頃、「AWS Web問題集」にSCSが追加されたので、これもやった。

2020年8月某日 - SCS受験し、合格

試験前は、単語カード、ノートの見返しの中心に行った。2020年8月初旬にSCSを受けた。終了時は、たぶん合格しているだろうというくらいだった。試験がおわって「合格」の二文字を見たときはホッとした。後日スコアを確認すると831だった。SAAのスコア 867よりは低く、SAPのスコア 797よりは高い。自分の実力値のような気がする。ちなみに試験は朝一に受けることにしている。朝一だと人も少ないし、元気があるところで受けられるからである。50過ぎのオッサンは午後になるとだんだん疲れてくるのである。

どれだけ勉強したのか

期間は、3月下旬から5月上旬と、7月中旬~8月上旬にかけての2週間なので、全部で1.5か月くらい。ユニークな問題数は約600問。今回は、問題集よりは、「Zean Vora本」とBlack Beltを中心に勉強した。

参照したBlack Belt一覧

API Gateway、Lambda、S3/S3 Glacier、Cognito、EC2、SES、SNS、VPC、VPC Advanced、Directory Service、Kinesis、Certificate Manager、Athena、Macie、IAM、Organizations、CloudWatch、WAF、Shield、GuardDuty、CloudFront、Inspector、System Manager、CloudTrail & Config、Trusted Advisor、CloudHSM、KMS

参照したホワイトぺーバー一覧

AWS KMSのベストプラクティス

おわりに

オッサンが試験勉強だけでAWS SCSに合格できたという体験記はこれで終わりである。SCS試験の準備をしたことでセキュリティ観点の知識は(実践力は別として)かなり深まったと思う。AWS CLF、SAA、SAPに加え、今回のSCSで4つのAWSの資格を取得したことになる。ここまでくると、今の知識を生かしつつ、取得する資格も増やしていこうかなとか考えたりもしている。現在、ずっと在宅勤務になっており、そこでの生活リズムもできてきて、試験勉強もうまく入れ込めるようになってきた。ちなみに今回勉強した場所は、ほぼ10割自宅である。当然、在宅勤務をしつつ勉強することになるが、たまに昼食を作るとかちゃんとやっていれば家で勉強してても怒られないのである。

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

HTTP -> HTTPSのリダイレクトはELBで行う方がスマートかもしれない (Nginxでリダイレクトを行う方法あり)

やりたいこと

AWSのロードバランサー(ELB)を使用しており、ELBにSSL証明(ACM)を付与し、httpsアクセスが可能な状態で
httpリクエストをhttpsにリダイレクトする設定をしたい

前回記事でNginx公式docを調べていると、
すべてのトラフィックに対してif...といった処理を行うことは負荷の観点から望ましくないということを学んだ

wwwなしの、SSL(https)にリダイレクトしたいときのNGINXの設定 -Route 53 + ELB (ACM) + EC2構成- - Qiita

今回は、web server(Nginx)を使用せずともELBでHTTP -> HTTPSリダイレクトが可能だという事がわかったので、実践しメモを残します
(以下、方法2が今回の内容です)

環境

以下のような環境を想定しています
- DNS (Route 53) -> ELB -> EC2 (NGINX -> Puma)
- SSL証明: ACM
- ELB <-> Nginx (port: 80)
- Rails 6 (config/environments/production.rb: config.force_ssl = true)

注意すること

単純にwebサーバー(Nginx)でリダイレクトするとうまくいかない

以下の記事で書きましたが、
HTTPリクエストも、HTTPSリクエストもELBからの転送に対してwebサーバー(Nginx)はport 80でlistenされているということに注意が必要

wwwなしの、SSL(https)にリダイレクトしたいときのNGINXの設定 -Route 53 + ELB (ACM) + EC2構成- - Qiita

このような条件で単純にNginxで

server {
    listen 80;
    return 301 https://$host$request_uri;

とすると
HTTPリクエスト -> ELB(port 80) -> Nginx(listen 80) -> (上記設定によりリダイレクト) ->
-> HTTPSリクエスト -> ELB(port 443) -> Nginx(listen 80) -> (再リダイレクト) ->
-> HTTPSリクエスト...
とリダイレクト繰り返すことになってしまう

方法1 NginxでのリダイレクトをHTTPリクエストの場合のみに限定

公式 doc
ELB を使用して HTTP トラフィックを HTTPS にリダイレクトする

上記参考に
HTTPSリクエストに対してはNginxでリダイレクトを行わないようにする必要があるというのが以前殴り書いた記事の意図

HTTP > HTTPSへのリダイレクト設定後にNGINXがリダイレクトを繰り返す問題への対応 - Qiita

以下のように書くことでHTTPSリクエストでない場合のみリダイレクトすることができる

server {
    listen 80;
    if ( $http_x_forwarded_proto != 'https' ) {
      return 301 https://$host$request_uri;
    }

ただしELBから転送されてきたトラフィックは全てport 80でlistenされているので
この方法だと全てのトラフィックに対してif...処理が適応される

方法2 ELBでHTTPSリダイレクト

webサーバーの前にELBのみでHTTPSリダイレクトができるそうです

方法1では全てのトラフィックに対して都度if以下の処理が行われるため
非効率的で、こちらの処理のほうが無駄がないように思います

参考: 公式doc
Application Load Balancer を使用して HTTP リクエストを HTTPS にリダイレクトする

上記参考に設定すると以下のようになります
スクリーンショット 2020-08-18 16.34.38.png

HTTP: 80 -> HTTPS: 443へリダイレクト
HTTPS: 443 -> Target-group (EC2, web serverへ)

希望するHTTP-> HTTPSリダイレクトが実現できております

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

DynamoDBの定義をコピーして新テーブルを作る(複数個)

AWSのDynamoDB、使っていますか?

今回は・・・
わけあってもともとあるテーブルたちの名前を一部リネームしたものをそのまま複製したい!
(中身は空で良い)
となり、手で1つずつ定義を設定して作るのは面倒なので、PHPでさくっとやってみました。

●流れ●
① AWS SDKを使えるようにする
 https://github.com/masayuki0812/dynamodb-php-wrapper
② listTablesでDynamoの一覧を取得
③ ②をforeachで回し、各テーブルの定義をdescribeTableで取得
④ リネームしたテーブル名と取得した定義を使ってcreateTable

●実際のコード●
※FuelPHPで実装しています
※SDKの処理を取得するために、一度Modelを通していますがお好みで・・・

        // Dynamoテーブルのテーブル名を一覧で取得
        $data = Model_Dynamo_Base::listTables(); // いい感じの場所でsdkの「listTables」を呼び出してください
        foreach ($data['TableNames'] as $index => $base_tablename) {
        // リネーム処理
                $tabelname = str_replace(test,test2,$base_tablename);
                // 1テーブルごとにテーブル定義を取得
                $base_table_data = Model_Dynamo_Base::describeTable($base_tablename); // いい感じの場所でsdkの「describeTable」を呼び出してください
                // 作成したいテーブル名に変更
                $base_table_data['Table']['TableName'] = $tabelname;
                // キャパを読み取りも書き込みも調整
                $base_table_data['Table']['ProvisionedThroughput']['ReadCapacityUnits'] = 1;
                $base_table_data['Table']['ProvisionedThroughput']['WriteCapacityUnits'] = 1;
                $params = $base_table_data['Table'];
                // テーブル作成
                $bbb = Model_Dynamo_Base::createTable($params); // いい感じの場所でsdkの「createTable」を呼び出してください
            }
        }

dynamodb-php-wrapperに追記する形で作っています

    public function listTables($ExclusiveStartTableName = null, $limit = null)
    {
        $params = array();
        if (!is_null($ExclusiveStartTableName)) {
            $params['ExclusiveStartTableName'] = $ExclusiveStartTableName;
        }
        if (!is_null($limit)) {
            $params['limit'] = $limit;
        }
        $response = $this->client->listTables($params);
        return $response;
    }

    public function describeTable($tableName)
    {
        $params = array();
        if (!is_null($tableName)) {
            $params['TableName'] = $tableName;
        }
        $response = $this->client->describeTable($params);
        return $response;
    }

    public function createTable($param) {
        $this->client->createTable($param);
    }

こんな感じです。
あまり参考資料がなかったので苦戦しましたが、出来てしまうとかなり楽でした。

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

EC2でRailsを起動する(手動デプロイ)

日記がてら。

EC2でのRails起動までの準備を着々と進めていき、
いざ起動コマンド!と思いきや

image.png

master failed to start, check stderr log for details
というエラー分が出て起動失敗。

stderrとはなんぞ?と思い調べてみるとconfig/unicorn.rbに
image.png
という部分が。
なるほどエラーログというものがあるのか。

lessコマンドを使用することでファイルの中身を除けるらしいのでターミナルで打ち込んでみることに。
すると
image.png
この青ラインが何度も出ていることに気づいた。

まずcredentialなるものについてファイルを覗くも、全く触ったことのないファイルだったので一旦後回し。
その上のaccess_key、secret_access_keyに何かありそうだ。
調べていくうちに起動までの手順を一つ抜かしていたようで、ターミナルにsudo vim /etc/environmentと打ち込み、
image.png
こちら2点を追記することであっさり解決。

ここまで調べたり試したりで所要時間3時間。

もしEC2でRails起動しないことでお悩みの方は上記の点の確認と、
・ローカル→GiuHubへのpushのし忘れはないか(mergeまで確認)
・GithubからEC2への反映(git pull origin master)のし忘れは無いか
・EC2サーバー側でエラーログの内容を確認し、原因を見つけたか
・カリキュラム通りの記載ができているか
・データベースは正しく起動しているか
・EC2サーバー側の環境変数は正しく設定できているか
・EC2インスタンスの再起動を行ってみる
を確認してみることをお勧めします。

またインスタンスの再起動は最初よくわからず全く別のインスタンスを作成したりとかしちゃったので、その場合はいらないインスタンスで右クリック→インスタンスの状態→終了で問題なく終わらせられます。
すぐには消えないけど24時間程度で消えるそうです。

誰かの参考になれば幸いです。

master failed to start, check stderr log for details
bundler: failed to load command: unicorn_rails
Aws::Sigv4::Errors::MissingCredentialsError: Cannot load Rails.config.active_storage.service:
missing credentials, provide credentials with one of the following options:

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

BIツール Re:dashの実行環境をAWS上に作成してみた

BIツールの比較検証を行った際に、AWS上にRe:dashの検証実行環境を作成しましたので、その際の手順を以下に纏めておきます。

AWS設定

◆VPC作成

① まず初めに、以下の設定を行い、VPCを作成します。(指定のないものはデフォルト設定です。)
VPC設定
② VPCが作成されると、以下の通りに表示されます。
VPC一覧
以上で、VPCの作成は終了です。


◆サブネット作成

① 次に、パブリックサブネット1つとプライベートサブネット2つ1を作成します。

  1. パブリックサブネット パブリックサブネット設定
  2. プライベートサブネット プライベートサブネット設定1 プライベートサブネット設定2 ② サブネットが作成されると、以下の通りに表示されます。 サブネット一覧 以上で、サブネットの作成は終了です。

◆インターネットゲートウェイ作成

① 以下の設定を行い、インターネットゲートウェイを作成します。(指定のないものはデフォルト設定です。)
igw設定
② インターネットゲートウェイが作成されると、以下の通りに表示されます。
igw一覧
③ 次に、作成したインターネットゲートウェイを選択し、[アクション] - [VPCにアタッチ] を選択します。
vpcアタッチ1
④ 作成したVPCを選択し、インターネットゲートウェイのアタッチを行います。
vpcアタッチ2
⑤ アタッチすると、以下のように表示されます。
igw一覧attach
以上で、インターネットゲートウェイの作成は終了です。


◆ルートテーブル作成

① 以下の設定を行い、ルートテーブルを作成します。(記載のないものはデフォルト設定です。)
ルートテーブル設定
② 作成されたルートテーブルを選択し、サブネットの関連付けタブ内の「サブネットの関連付けの編集」ボタンを押下します。
サブネット関連付け
③ 作成したパブリックサブネットを選択し、保存します。
関連付けサブネット選択
④ 保存すると、下記のように関連付けされます。
サブネット関連付け終了
⑤ 次に、ルートタブの「ルートの編集」ボタンを押下します。
ルート編集ボタン押下
⑥ パブリックサブネットから外部へのルーティングを追加します。
  「ルートの追加」ボタンを押下し、以下の設定を行います。
ルート追加
⑦ 保存すると、以下のように表示されます。
ルート一覧
以上で、ルートテーブルの作成は終了です。


◆セキュリティグループ作成

① 下記の設定を行い、EC2インスタンスのセキュリティグループを作成します。(指定のないものは、デフォルト設定です。)
EC2sg設定
「ルール追加」ボタンを押下し、インバウンドルールを設定します。
インバウンド設定
③ セキュリティグループが作成されると、以下のように表示されます。
インバウンドルールEC2
④ 続いて、RDSのセキュリティグループを作成します。
RDSsg設定
⑤ セキュリティグループが作成されると、以下のように表示されます。
インバウンドルールRDS
以上で、セキュリティグループの作成は終了です。


◆EC2インスタンス(Webサーバ)作成

「インスタンスの作成」ボタンを押下します。
② Redash用のAMIを検索します。(今回は、東京リージョン用のAMIを選択)
  https://redash.io/help/open-source/setup#aws から使用するAMIを検索欄に入力して検索を行い、選択します。
AMI選択
③ インスタンスタイプを選択します。(T2.microだと動かないので、t2.small以上を選択します。)
インスタンスタイプ選択
④ インスタンスの詳細設定を行います。(指定のない項目はデフォルト設定です。)
インスタンス設定1
⑤ 続いて、ストレージの追加設定を行います。(デフォルト設定のままで大丈夫です。)
インスタンス設定2
⑥ 続いて、セキュリティグループの設定を行います。
インスタンス設定3
⑦ 最後に、インスタンス作成の確認を行い、「起動」ボタンを押下します。
インスタンス設定4
⑧ キーペア作成に関するダイアログが表示されますので、新しいキーペアの作成を選択し、キーペアのダウンロードを行います。
​ ※ダウンロードしたキーペアは、今後rLoginやTera Term等でEC2にアクセスする際に必要となりますので、大切に保存しておいてください。
​ ダウンロード終了後、インスタンスの作成を行います。
キーペア作成
⑨ 作成が完了すると、以下のように表示されます。(チェック合格になると完了)
インスタンス一覧
以上で、EC2インスタンスの作成は終了です。


◆RDS作成

① 以下の設定を行い、RDSの作成を行います。(指定のないものはデフォルト設定です。)
DB選択
DB認証情報設定
DB接続情報設定
DBVPCsg設定
DB追加設定
② RDBが作成されると、以下のように表示されます。(ステータスが利用可能になると完了)
DB一覧
以上で、RDSの作成は終了です。

AWSの設定は以上になります。

Re:dash検証実行環境構成(AWS)

今回、Re:dash検証用に上記で作成した実行環境の構成は、以下の通りです。

本番環境で運用する際には、可用性の向上やインスタンスのスケールアップなどの対応が必要になります。
システム構成


  1. プライベートサブネットにRDSを配置するには、サブネットが2つ必要になるため 

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

GKE <-> EKS コマンド対応表

個人的なメモです。随時更新。

$ gcloud auth list <-> aws sts get-caller-identity
$ gcloud container clusters list <-> aws eks --region=ap-northeast-1 list-clusters
$ gcloud container clusters list <-> eksctl get cluster
$ gcloud container clusters get-credentials <cluster-name> --region xxx <-> aws eks --region=ap-northeast-1 update-kubeconfig --name=<cluster-name>
$ gcloud container clusters resize num-nodes=0 <-> aws eks delete-nodegroup  --cluster <cluster-name> --nodegroup <nodepool-name> // 0個に指定はできさなそうなのでノードプール削除する
$ gcloud container images xxx <-> aws ecr describe-repositories
$ gcloud container images xxx <-> aws ecr list-images  --repository-name "repo name"

番外編

gcloud redis list <-> aws elasticache describe-cache-clusters --show-cache-node-info
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLServerのバックアップファイルをRDSへインポートする

SQLServerのバックアップファイルをRDSへインポートすることになりました。以前よりは簡単になったといわれておりますが、だいぶはまったのでメモに残しておこうと思います。

ドキュメント

今回の作業にあたり、こちらのドキュメントを参考にしました。
SQL Server データベースのインポートとエクスポート(AWS ユーザーガイド)
RDS for SQL Server へのインポート

「権限がない」と怒られる

ところが、この通りに実行したはずが以下のエラーが出てしまいます。

Msg 50000, Level 16, State 0, Procedure rds_restore_database, Line 37
Database backup/restore option is not enabled yet or is in the process of being enabled. Please try again later.

「あとでもう一度実行してみてください」とありますが、翌日に実行しても同じだったのでどうやらうまくいっていないようでした。

ドキュメント(英語)

メッセージで調べたところ、こちらのページが出てきました。それを参考に修正すると正常にインポートが完了しました。

何がだめだったのか?

まあいろいろあったのですが...

IAMロールが正しくない

こちらにも詳しくまとめられておりました。IAMロールに「AWSBackupServiceRolePolicyForRestores」を追加します。
RDS for Microsoft SQL Serverに.bakをリストアするとエラーになる

オプショングループのエンジンがそろっていない

option_group.png

オプショングループで「エンジン」「メジャーエンジンのバージョン」を設定しますが、使用しているデータベースと一致する必要があります。そのために「関連付けられた DB インスタンスとスナップショット」に表示されませんでした。

成功!

これらを修正することで無事データのエクスポートが完了しました。めでたしめでたし。

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

Amplify DataStoreを使ったチャットアプリサンプル

今回は、前から気になっていたAmplify DataStoreを使ったWebアプリを作ってみます。
Amplify DataStoreはデータの書き込み、読み取り、監視するための永続的なストレージリポジトリです。ネットワーク接続が利用可能であればデータをAppSyncと同期し、接続しない場合はローカルデータストアとしても利用ができます。

Reactチャットアプリ雛形作成

npx create-react-app chatapp --template typescript
cd chatapp
yarn start

ブラウザにいつものが出ます。
image.png

とりあえずApp.tsxの不要なものを消しておきます。

App.tsx
import React from 'react';
import './App.css';

function App() {
  return (
    <>
      ここに後でchatアプリ作るよ
    </>
  );
}

export default App;

とりあえず表示はこんな感じ。
image.png

Amplify DataStore設定

次にamplify CLIを使ってapiを作って行きますが、その前にamplifyはバージョン更新が激しいので古いバージョンのCLIを使っていると利用したいオプションがサポートされていないこともあるので、作業の前に念の為ご自身の利用しているCLIをバージョンを確認しておきます。私が使ったのは以下のバージョン。

amplify --version
4.27.2

では、まずは初期化から。

amplify init

ここからが本題。DataStoreを使うAPIを作ります。今回はサンプルなのでほぼデフォルト設定ですが、以下の項目を指定する点がポイントです。

Do you want to configure advanced settings for the GraphQL API
→Yes, I want to make some additional changes.
Configure conflict detection?
→Yes
Select the default resolution strategy
→Auto Merge

amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: chatapp
? Choose the default authorization type for the API API key
? Enter a description for the API key: 
? After how many days from now the API key should expire (1-365): 7
? Do you want to configure advanced settings for the GraphQL API Yes, I want to make s
ome additional changes.
? Configure additional auth types? No
? Configure conflict detection? Yes
? Select the default resolution strategy Auto Merge
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, des
cription)
? Do you want to edit the schema now? Yes

AppSyncとの同期時の競合検出と解決については以下3つの動作がサポートされています。

 Auto Merge 
 Optimistic Concurrency 
 Custom Lambda 

Auto Merge

データの競合を検出すると自動でデータをマージし、クラウド上とクライアントのローカルストレージ上のデータを更新します。デフォルトは「Auto Merge」が選択されています。

Optimistic Concurrency

データの競合を検出すると、クライアントからのリクエストを拒否します。

Custom Lambda

データの競合を検出すると、独自定義したLambdaを起動させることができます。

特に理由がなければAuto Mergeを選択して良いと思います。

詳しく知りたい方は公式の「Conflict Detection and Resolution」章あたりを参照すると良いでしょう。

スキーマはシンプルに以下のようにします。(説明簡単にするため相当雑に作ってます...)

schema.graphql
type Message @model {
  id: ID!
  text: String!
}

ファイルを保存してバックエンドへプロビジョニングします。

amplify push
? Are you sure you want to continue? Yes
? Do you want to generate code for your newly created GraphQL API No

次に、以下のオプションを実行するとDataStoreのmodelが生成されます。

amplify codegen models

image.png

チャットアプリへDataStoreを組み込む

必要なライブラリを追加します。

yarn add aws-amplify @aws-amplify/datastore

App.tsxに実装を加えます。

App.tsx
import React, { useState, useEffect } from 'react';
import './App.css';
import awsconfig from './aws-exports'
import Amplify, { DataStore } from 'aws-amplify'
import { Message } from './models';
Amplify.configure(awsconfig)

const App = () => {
  const [messages, setMessages] = useState<Message[]>([])
  const [inputValue, setInputValue] = useState('')
  useEffect(() => {
    fetchMessage()
    DataStore.observe(Message).subscribe(fetchMessage);
  }, [])
  async function fetchMessage() {
    const data = await DataStore.query(Message)
    setMessages(data)
  }
  async function sendMessage(text: string) {
    await DataStore.save(new Message({ text }))
    setInputValue('')
  }
  const handleOnChange = (value: string) => {
    setInputValue(value)
  }
  return (
    <>
      {messages && messages.map((message, index) => {
        return (
          <div key={index}>
            {message.text}
          </div>
        )
      })}
      <input type='text' value={inputValue} onChange={(e) => handleOnChange(e.target.value)} />
      <button onClick={() => sendMessage(inputValue)}>送信</button>
    </>
  );
}

export default App;

表示はこんな感じ。ちょーシンプル。

image.png

試しに複数ブラウザからアクセスし一方をオフラインにしてメッセージを送信してみましょう。オンライン復帰後メッセージが自動的にマージされることが確認できるかと思います。

まとめ

DataStoreを使うことで非常に簡単にクラウドへのデータ同期と競合解消する実装ができました。また、GraphQLのquery文が抽象化されるためよりスッキリとした実装になります。
複雑なquery条件が必要なケースなどではまだ制約がありそうですが、簡単なアプリなら十分に利用できますね。
また機会があれば、もう少し複雑なスキーマでも試してみようかと思います。

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

ECSのタスク定義でボリュームのマウントをする時のパラメータの書き方

ボリュームプロパティ

事前にVolumesプロパティで、マウント先であるインスタンス側のボリュームを、パスを指定して命名しておく。

  Properties:
    Volumes:
      - Name: host_volume
        Host:
          SourcePath: /var/log

マウントパラメータ

マウント自体はmountPointsパラメータで定義される。
SourceVolumeパラメータには先ほど定義したマウント先のインスタンスのボリューム名を入れる。
この時、SourceVolumeで指定できるのは、Volumesプロパティで定義されたものだけなので注意。
ContainerPathパラメータにはマウントするコンテナ内のボリュームのパスをそのまま書けばよい。
ReadOnlyパラメータはデフォルトでfalse

        MountPoints:
          - SourceVolume: host_volume
            ContainerPath: /var/data/buffer
            ReadOnly: true

タスク定義

以下が全体像の例

TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    Volumes:
      - Name: host_volume
        Host:
          SourcePath: /var/log
    ContainerDefinitions:
      - Name: xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample:latest
        Image: samples/sample-container-agent:latest
        Memory: 128
        MountPoints:
          - SourceVolume: host_volume
            ContainerPath: /var/data/buffer
            ReadOnly: true
        Environment:
          - Name: ENV
            Value: development
        Essential: false

cf.

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html

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

macからEC2にSSH接続したら、Bad configuration option: identifyfile?/ terminating, 1 bad configuration optionsが出てしまった時の対処法

@nakmさん: AWSのEC2にmacからSSHする方法

こちらの記事を参照して、設定した際に、
Bad configuration option: identifyfile?

terminating, 1 bad configuration options

が出てきてしまいました。
対処に時間をかけてしまったので、自分が解決したケースをシェアさせて頂きます。

秘密鍵ファイルの移動をしてSSH接続を試みたところ....

ssh -i ~/.ssh/<秘密鍵ファイル名> <ユーザー名>@<接続先IP>

以下のエラーが返ってきました。

.../ .ssh/config: line 6: Bad configuration option: identifyfile?

.../ .ssh/config:terminating, 1 bad configuration options

configファイルの設定は以下の通りで、一見問題が無いように思えました。
※エラーで指摘された6行目は、identifyFile <ファイル名>
※EC2に接続する際のポート番号は"22"でOK。

image.png

結論"identityFile"にしなければならなかった

最初に生成されているファイルが、identi"f"yFileと記述されていましたが、接続時にはidentityFileと記述する必要がありました。

image.png

これで無事接続が可能です。

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

aws apache rds

ec2にログイン

アパッチをyumでインストール

RDS

private subnet の作成

ip 10.0.20.0/24
internet gateway と接続しない。
RDSを作るとき用にもう一つ
ip 10.0.21.0/24も作る。availability zoneを違うところにして

RDSの作成

まず、セキュリティグループの設定
データベース用の作成
xxxx-db-sg あたりにして
vpc の選択
inbound rule
type MYSQL/Aurora
Source webように作ったもの

RDSに移動
database create

DB instance identifierに名前を入れて
Credentials Settings
Master user
password 設定

connectivity

VPC

vpc-sg

availability zone の設定

追加の設定

db name db-dev
sg の設定

ssh

terminal で
login
mysql install

database endpoint 確認。

mysql -h endpoint -uroot

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

AWS Lambda上でGCCを動かす。

はじめに

オンラインジャッジをサーバーレスで構築してみたかったので、まずLambda上でGCCを動くようにしました。

環境

Node.js 12.x

GCCが動作するのに必要なもの

  • GCC: 本体。
  • Binutils: GASとか。
  • GLibC: ヘッダーファイルやランタイムなど。

普通の環境ではGCCのみコンパイルすれば動かすことができます。
ですがLambdaの中には最小限のソフトウェアしかインストールされていないため、いくつか別にインストールする必要があります。

インストール先

最初に思いつくであろう方法がプログラムを含めたZIPファイルに一緒に含めてGCCをアップロードする方法です。
ただその場合ZIPファイルの容量制限がかなり厳しいので、結構機能制限しないとGCCをアップロードすることはできません。
またGCCだけで容量がいっぱいいっぱいになるため、他のコンパイラをインストールすることができないというデメリットもあります。
そのため今回はGCCをインストールしたEFSを用意して、LambdaにマウントすることでGCCを動作可能にすることとしました。

インストール方法

EFSに書き込むにはEC2を使うのが手軽なため、EC2でコンパイルとインストールを行いました。
またt2.microではメモリが足りなかったため、今回はt2.smallを使っています。

1. EFSの作成

Amazon Management Consoleもしくは、aws-cliを用いて作成して下さい。

2. EC2へEFSをマウント

以下のコマンドを実行します。

sudo mount -t efs -o tls,iam ファイルシステムID マウントポイント

ここからはEFSを/mnt/compilers/にマウントして、gccを/mnt/compilers/usrにインストールするものとして進めます。

3. コンパイルするためにEC2にGCCなどをインストールする

何をインストールしたか記録をとるのを忘れていました。
頑張って探してみてね。

4. Makeのインストール

EC2(Amazon Linux)のMakeはバージョンが古く、Binutilsをmakeするときに怒られるので新しいバージョンをインストールします。

cd
wget http://ftp.jaist.ac.jp/pub/GNU/make/make-4.3.tar.gz
tar -xf make-4.3.tar.gz
mkdir build-make
cd build-make
../make-4.3/configure
make
sudo make install

5. GCCのインストール

cd
git clone git://gcc.gnu.org/git/gcc.git
mkdir build-gcc
cd build-gcc
../gcc/configure \
    --prefix=/mnt/compilers/usr \
    --with-local-prefix=/mnt/compilers/usr \
    --enable-languages=c++ \
    --disable-shared \
    --disable-lto \
    --disable-gcov \
    --disable-threads \
    --disable-bootstrap \
    --disable-multilib
make
sudo make install

6. BinUtilsのインストール

cd
git clone git://sourceware.org/git/binutils-gdb.git
mkdir build-binutils
cd build-binutils
../binutils-gdb/configure --prefix=/mnt/compilers/usr
make
sudo make install

7. GLibCのインストール

cd
git clone git://sourceware.org/git/glibc.git
mkdir build-glibc
cd build-glibc
../glibc/configure --prefix=/mnt/compilers/usr
make
sudo make install

AWS Lambdaにマウント

EFSをLambdaにマウントするためにはEFS側にアクセスポイントを作成する必要があります。
また、Lambda側もVPC Lambdaに変更して下さい。
そうすると、LambdaにEFSをマウントすることができるようになりますのでEC2と同じパス(今回は/mnt/compilers)にEFSをマウントしてください。
なお、VPC Lambdaにはいろいろと制限があることに注意して下さい。

動作確認

テストコード
const { promisify } = require('util');
const fs = require('fs');
const child_process = require('child_process');

const exec = promisify(child_process.exec);

exports.handler = async (event, context) => {
    fs.writeFileSync("/tmp/Main.c", "#include<stdio.h>\nint main() { puts(\"Hello world\"); }");
    return await exec('/mnt/compilers/usr/bin/gcc /tmp/Main.c -o /tmp/a.out && /tmp/a.out');
};

実行すると…

Response
{
  "stdout": "Hello world\n",
  "stderr": ""
}

おわりに

これを使ってサーバーレスでオンラインジャッジを組んでコンテストサイトを作ろうと思っています。

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

AWS LakeFormationの使い所とサービス設計を理解する

なぜこの記事を書くのか

AWS re:Invent 2018 で歓声とともに発表されたAWS LakeFormationですが、約1年半経っても有効活用がされているという話をあまり聞きません。私は根本的にはLakeFormationの「サービス設計がよくない」ことが原因だと思いますが、そもそも情報が少なすぎることも要因の1つだと思います。(最近発売された書籍「AWSではじめるデータレイク」もLakeFormationの説明は少ないです。)そのため、使い方・機能を、それぞれマクロ・ミクロの視点から少し整理してみようと思います。結果的にまとまりのよくない記事になってしまいましたが、利用判断の一助になれば幸いです。

  • なお本記事では以下の機能については触れません。
    • 他社データカタログ機能との比較
    • Blueprints機能
    • GlueやIAMの互換性まわり
    • 運用設計

まずはマクロな視点から説明します。

LakeFormationを利用したほうがいいケース

  • 利用ユーザ側が以下の条件に多く当てはまる場合は、LakeFormationの利点が得られると思います。(上から重要な順に記載)
    • AWSのIAMに精通しているエンジニアがいない
      • またはユーザ部門でセルフサービスとしてデータレイクを運用したい
    • 最低3名程度のデータ管理チームを立てることができる
    • データカタログ機能にあまり期待しなくてよい
    • 新しくデータレイクを構築しようとしている
    • LakeFormationの学習コストおよび利用ユーザへの啓蒙コストを払うことができる

LakeFormationの利点

  • データレイクの複雑なIAM設計の多くから解放される
    • これに尽きると思います。ただしすべてLakeFormationで完結できるとは限りませんので、IAM設計ができる人を用意しておく必要はあります。特に以下のようなところでIAM設計が必要になります。
      • データパイプラインのうち両端(インプット/アウトプット寄りのところ)
        • これはLakeFormationがIAMの「代理」的な動きをすることに起因します。
          • 代理的な動き(IAMロールのassume)ができない多くのサードパーティツールとの連携ではメリットを活かせないことがあります。
      • LakeFormationのユーザ(ペルソナ)に設定するIAMの設計
    • 複雑なIAM設計のイメージは以下がわかりやすいと思います。
    • 利点の大きさはLakeFormationなしでデータレイクを作ってみないとわかりづらいと思います。AWSのデータレイクはリージョンサービスであるS3が中心になります。リージョンサービスはインターネットに隣接する位置にあるため、アクセス制御のミスが命取りになりえます。S3の主たるアクセス制御機能はバケットポリシーです。
      • バケットポリシーは「リソースベースポリシー」に分類されるものです。ユーザやロールに付与する「アイデンティティベースポリシー」と異なります。ただ条件によって両者がOR演算、またはAND演算で関連しあいます。それゆえ、データレイク(S3)へのアクセスを考えるときには、以下の両方を考えなければいけません。
        1. データの置き場 → バケットポリシー(リソースベースポリシー)で制御
        2. データの利用者 → IAMポリシー(アイデンティティベースポリシー)で制御
      • https://www.slideshare.net/AmazonWebServicesJapan/20190129-aws-black-belt-online-seminar-aws-identity-and-access-management-iam-part1/50
      • 通常、同一アカウント同士であればバケットポリシーとIAMポリシーはOR演算になります。OR演算はどちらか一方が明示的なAllowを通せばOKになってしまうため、緩い認可ロジックといえます。制御をしっかりやるにはバケットポリシーは明示的なdenyをかけたうえで例外を追加していくというような複雑な条件が必要になります。(例外のためにnot系の条件を多用する場合はド・モルガンの法則の理解も必要です。)
    • 複雑な設計が必要ということは、それだけセキュリティの抜け穴が発生しやすいというリスクがあるということにほかなりません。また、そのリスクを回避するためには適切なスキルを持つエンジニアの確保コストが必要である、ということを意味します。クラウド専業のSIerに勤めている私からみても、IAMポリシーを使いこなすことのできるエンジニアは稀少ですので、確保は困難なことが多いと思います。不確実性の海を渡るため、デジタルトランスフォーメーションの要であるデータレイクが必要なのに、セキュリティリスクを抱えたままで、かつ回避できるエンジニアも確保できない、というときに浮上してくるのがLakeFormationです。ただしLakeFormationそのものの学習コストもそれなりに高いため、汎用的なIAMポリシーの学習コストとのトレードオフを思うと、それなりにデータ分析経験の厚みのある組織でないとマッチしないのではないかと思います。

利用に際し、まず考えるべきこと

LakeFormationがカバーする範囲は、データレイクのごく一部。

image.png

  • 上図はLambdaアーキテクチャを採用した、IoT寄りな小・中規模データレイクの参考図です。
  • LakeFormationはデータレイクの一部でしかありません。LakeFormationがカバーしない要素は、ぱっと思いつくだけでも以下のようなものがあります。
    1. データパイプライン(INPUT/OUTPUT)の設計
    2. データストアの設計
    3. S3の構造設計
    4. ETL処理(Glueジョブコーディング)
    5. BIのダッシュボード
    6. 業務レベルの利用フロー整備
  • ここでは深堀りしませんが、どれもボリュームの大きい設計要素です。とくに[1.データパイプラインの設計]がもっともハードな要素です。「LakeFormation」という名前が人に抱かせるイメージに惑わされないように、設計要素を見極めてから計画を立てる必要があります。

ユーザ側のデータレイク利用スキームに以下の3種の役割を組み込むことができるか

  • LakeFormationは以下のようなペルソナ(人間の役割)を想定して設計されています。社内リソースが確保できるか、文化的にも業務フローに組み込むことができそうか、検討してから導入することをおすすめします。
# ペルソナ名 役割
1 データレイク管理者 データ全体の管理者。窓口や啓蒙活動などを担う。
「データスチュワード」とも呼ばれる。
2 データエンジニア 生データを使いやすい形に加工し提供する人。
コーディングスキル持ち、メンテナンスもできるSRE的な人が担う
3 データ分析者 加工されたデータを利用する人。
BIなど見える化のスキルを持つ人が担う。
Athenaだけ利用できるIAMユーザであったり、QuickSightが利用するIAMロールであったり、様々。 (なお「IAMプリンシパル」とは、IAMユーザやIAMロールのことを指す)
  • 上記役割はAWSの公式資料では「ペルソナ」と呼ばれています。

  • 3人以上用意できなくても、たとえば以下のような兼任であれば、LakeFormationのアクセス制御の利点が活かせます。

    • [1. データレイク管理者]と[2. データエンジニア]を一人が兼任する
    • [2. データエンジニア]と[3. データ分析者]を一人が兼任する
    • しかし一人で1,2,3すべてを兼任するような場合は、むしろLakeFormationの機能が足かせになると思います(将来的に人が増えるからしばらく一人でデメリットを受容する、という割り切りもアリです)。
  • 2番目の「データエンジニア」というのが少し曲者です。AIやデータ活用基盤をすでにもっている組織であれば耳慣れた言葉ですし、チームも存在するかもしれません。LakeFormationは費用対効果を考えるとデータレイク導入前に利用検討することが望ましいのですが、データレイク導入前の段階で「データエンジニア」というロールを確保できている組織は多くは無いと思います。しかしながらLakeFormationを理解するためには、このAWSにおける「データエンジニア」の役割を意識することが不可欠です。

ここから機能をミクロな視点で説明していきたいと思います。

LakeFormationによってアクセス制御がどのように変わるのか

LakeFormationがない場合

急がば回れの精神で、S3から最も遠い位置にあるQuickSightから、Athena+Glueを経由してS3に行く例で考えてみます。

image.png

  • QuickSightは[aws-quicksight-service-role-v0]という、サービスが自動生成するIAMロール(サービスリンクロール)を使ってS3にアクセスしようとします。
    • S3へのアクセス許可はQuickSightの設定[QuickSightの管理]->[セキュリティとアクセス権限]からバケットを選択することで可能になります。
      • 上記に登録されたS3バケットは、[aws-quicksight-service-role-v0]ロール内の[AWSQuickSightS3Policy]ポリシーに自動で登録されます。
    • ここではS3にアクセスする主体はQuickSightのIAMロールであるため、AthenaやGlueのことはあまり考える必要はなく、S3のバケットだけを気にしていれば良いシンプルな構造になっています。一方でこの構造は関所のようなものがなく、エンドツーエンドの認証認可になっています。つまりアクセス元のポリシーでS3へのアクセスが制御できてしまう(※)ため、データアクセスのガバナンスが効きづらいことが懸念されます。
      • ※先に書いたようにS3バケットポリシーで明示的なDenyを行わない限り、IAMポリシーだけで許可を入れられてしまいます。
      • なお、QuickSightのEnterpriseEditionであればQuickSightユーザ単位でS3アクセス制御ができますが、そのようにアクセス元サービスの機能に頼ってその機能のありなしにヤキモキするよりも、一元的なガバナンスの効く関所のようなものがあったほうが楽ですよね。

LakeFormationがある場合

ではLakeFormationを使うとどのように変化するか見ていきます。

  • 初期設定として以下の作業を行います。
    • まず、LakeFormationの[DataLake Locations]に、アクセスしたいS3バケットを登録します。
      • すると代理的にS3にアクセスするロールが、指定したバケットにアクセスできるようになります。
    • つぎにLakeFormationの[Data permissions]設定を行い、Glueデータベース/テーブルへの許可を、QuickSightのロールに対して付与します。

LakeFormationの設定は以下のような構造になります。

image.png

  • つまり、LakeFormationで認証認可がいったん中断し、異なるチェック機構が「ハイジャック的に」介入するようになります。
    • 例えていうなら駅員(LakeFormation)が客(IAMプリンシパル)の行き先を確認し、許可台帳(Data permissions)をチェックして、行き先(DataLake Locations)にあわせた許可バッヂ(IAMロール)を客の胸に貼り付けるような動きです。
  • 実際のチェック機構を絵にしたのが以下イメージ図です。

image.png

  • S3にたいしての認証の主体が、QuickSightのIAMロールから、LakeFormationのIAMロールに代理的に切り替わっていることがわかります。その交通整理を行うのがLakeFormationだということになります。ガバナンスの効く関所ができたようなイメージです。
  • LakeFormationを用いる例では、QuickSightのロールにS3バケットへのアクセス許可を追加する必要がありません。
    • [AWSQuickSightS3Policy]ポリシーにS3バケットを登録する必要がなくなり、LakeFormation側の制御に統合できます。
    • つまり客は行き先ごとの許可証を自分で毎回申請する必要がなく、行きたいところを駅員に伝えればよいだけになります。
利用有無 S3アクセス認可の違い デメリット
LakeFormationを利用しない
(IAMによるアクセス制御)
アクセス元のIAMにS3バケットへの許可が必要 S3バケットポリシーを適切に設定しないと新規IAMポリシーでデータにアクセスされる危険性
LakeFormationを利用する
(LakeFormationによるアクセス制御)
アクセス元のIAMにS3バケットへの許可が不要 LakeFormationの設定として、Glueテーブルへの認可が必要

LakeFormationの機能について

そもそも

ここでいったんスタート地点に立ち戻って考えてみます。

  • そもそも従来の[IAMによるアクセス制御]があるなかで、後続サービスであるLakeFormationがアクセス制御を追加で行うにはどうすればいいのでしょうか。S3全体に強制的にバリアのようなものをかけて[IAMによるアクセス制御]を阻害してしまったら既存システムへの影響が大きすぎます。影響を抑えるには「この場所がLakeFormationで管理したいS3パスだ」というように限定的に宣言する他ありません。その宣言こそが「DataLake Locations」という機能です。

  • 当然、特定のS3パスをバリアしたあとは、ファイアウォールのようにアクセス元に許可させる設定も必要です。それが[Data permissions]という機能です。ここまではわかりやすい話です。

Glueテーブルの位置づけ

  • LakeFormationのややこしいところがここからです。[Data permissions]は、S3のパスにたいして許可するのではなく、Glueテーブルにたいして許可をする必要があります。つまり、許可をするまえに予めデータカタログを作りテーブルスキーマを定義しておかないといけないということです。なぜこのような面倒なしくみになっているのでしょうか。おそらくアクセス制御をデータベース単位、テーブル単位、のみならずカラム単位で行えるようにするためだと考えられます。テーブルスキーマが存在しないとカラム単位で制御ができないからです(※)。
    • ※ちなみに特定のカラムを見せたくない場合は、アクセス制御ではなくGlueジョブで先に消してしまうという手もアリです。
    • Glueデータベース、Glueテーブル(テーブルスキーマ)をあわせてAWSデータカタログという言葉でまとめてみます。
    • AWSデータカタログはあくまでメタデータであり、データの実体ではない、仮想的な存在です。ポインタのようなものであり、1データストレージに複数のメタデータを作成できます。
区分 オントロジー LakeFormationにおける捉え方
データストレージ ・データの実体 ・S3のパス(スキーマ情報なし)
メタデータ
(AWSデータカタログ
・仮想的な存在
・実体を補足的に説明する情報
・データの場所を示すポインタ 
・Glueデータベース(Glueテーブルのまとまり)
・Glueテーブル(スキーマ情報やリネージなどのビジネスドメイン情報)
  • 上記のようにLakeFormationは「メタデータ=Glueテーブル」として設計してあります。データを登録するためにはテーブルを作成し、しかも面倒なことにテーブルスキーマも同時に定義しなければ作成ができません。(テーブルスキーマの認識は手動の他にGlueクローラでも可能ですが、面倒であることに変わりはありません。)
    image.png

    • このようにLakeFormationでは、データカタログを使うために、Glueテーブルが重要な役割を担う構造になっています。このGlueテーブルの位置づけこそが[Data Locations](※)という最も分かりづらい機能を理解するのに重要な認識となります。
    • ※名称的にも[Data Locations]と[Datalake Locations]は紛らわしく誤解を招きやすいです。

Data Locationsとは

  • まず、ポインタであるデータカタログ(Glueテーブル)を、データエンジニアが無制限に作れる場合を考えます。LakeFormationにおいては、Glueテーブルがデータストレージの実体を指し示すゲートのような役割を担うため、ユーザにデータを公開する道をデータエンジニアが自由に作れてしまうことになります。具体的な例として、1つの[Datalake Locations]の配下に、別の部署に見せたくない機密情報が含まれているS3パスがあるケースを考えます。そのようなとき、別の部署に勝手にデータを提供してほしくないS3パスを、許可制に切り替えるのが[Data Locations]です。

    • [Data Locations]は、データに対しての「読み書き」の権限を制御する機能ではありません。特定の場所への「テーブル作成」を制御する機能です。
    • デフォルトではこの制御は無効化されています。制御を有効化したい場合は、[Data Locations]にS3パスと、そこへのテーブル作成を許すIAMプリンシパルを登録することで防御ができます。つまりこれはセキュリティの追加レイヤーを提供するものであり、使わないという選択肢もあるということです。
  • 絵にしてみると以下のような関係になっています。

image.png

  • 繰り返しになりますが、実データへのゲートとなるGlueテーブルを作る権限は、アクセスのためのパイプライン敷設と同義であるため、セキュリティ上とても重要です。それを制限できるようになる機能が[Data locations]です。

ペルソナ視点から理解する

  • ペルソナ視点でLakeFormationの機能・操作とマッピングしてみます。
ペルソナ LakeFormation上の登録 主に扱う機能 LakeFormation上の役割 操作例
データレイク管理者 [Data lake administrators]に登録されたIAMユーザ/ロール [Data lake locations],
[Database creators],
[Data Locations]
S3バケットを登録したり全体の権限を管轄する ・[Data lake locations]にS3バケットを登録する。
・IAMプリンシパルを作成したり、[Database creators]にデータエンジニアを登録する。
・データエンジニアからの要請に応じて[Data Locations]の設定を行う。
データエンジニア [Database creators]に登録されたIAMユーザ/ロール
[Crawlers],
[Jobs],
[Data permissions]
AWS内のデータパイプライン形成やそのアクセス制御を行う ・Glueでデータを登録(カタログ化)する。
・[Data permissions]でデータ分析者にGlue上のデータベース・テーブルへのアクセスを許可する
データ分析者 [Data permissions]に登録されたIAMユーザ/ロール - データを利用する ・IAMユーザ/ロールに付与されている[Data permissions]の権限でGlueのテーブルにアクセスする
  • 上表はあくまで一例ですので、運用設計によっては付与するポリシーのアレンジが必要になります。ただ大枠として3つのペルソナを想定してユーザ設計を行うとLakeFormationと親和性があがります。

さいごに

  • 記事を書いてみて改めて思いましたが、やはりシンプルに説明することが難しい、学習コストの高いサービスだと感じます。
  • S3にたいしてのアクセス制御はエンタープライズレベルに可能なのですが、謳い文句の「安全なデータレイクを数日で構築」ができるかと問われると、できないと思います。データレイクに必要な設計要素にたいし、サービスのカバー範囲が狭いためです。
    • Blueprintsの種類が増える、もしくはAIでメタデータを自動認識するなど機能が拡張されていけば名実一体に近づくと思いますので期待したいです。
  • 現サービスレベルでの使い所としては、例えば「すでにAWSのデータレイクが構築できておりアクセス制御周りだけを強化したい」というようなフェーズで、リプレイスとして導入するのは有効な気がします。(そのようなフェーズであれば学習コストの妥当性が醸成されていると思います。)
  • 個人的には、LakeFormationはスモールスタートを支援すべく、利用ユーザにとって「データエンジニア」を意識しなくてもよい(透過的で、かつGlueのデータベースやテーブル概念と分離された)サービス設計にすべきであったと思います。今更それは難しいでしょうから、他のサービスを拡充させたうえで疎結合なサービス構造にしてみるのもいいかもしれません。たとえばこんなふうに・・・

    • AWS DataLake(総称)
      • Amazon DataCatalog(新サービス)
      • AWS CatalogControl(旧AWS LakeFormation)
      • AWS DataControl(新サービス)
    • ・・・あくまで勝手に考えたプロダクトデザインです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Organizationsの概念がよく分からなかった理由

AWSを触り始めて、3ヶ月程の初心者ですが、つい最近までAWS Organizationsの概念があまり理解できていませんでした。しかし、今回実際にAWS Organizationsを個人利用ではありますが実際に使ってみて概念と使い方がわかりました。そこで、なぜいまままで理解が深まらなかったか、理解できるようにするにはどうすればよいのかを説明していきます。

理解ができなかった一番の要因

理解ができなかった理由としては
【AWSアカウントを1つしか持たなかったことで複数アカウントを使用する理由が分からなかった】
ということがあります。僕はまだ、学生の独学での利用なので、アカウント1つで十分に勉強ができていました。なので、業務で部署ごとなどにアカウントを複数所持しているのであれば、このAWS Organizationsのメリットや使い方はすんなり理解できると思います。

AWS Organizationsはこんな事ができる!

・AWS Organizationsによって、いちいちクレジットカード情報や住所を入力しなくても新規アカウントが作成できる。
・アカウントを用途別にあわせた階層的なグループ化でまとめ一元管理ができる。
・新規作成したアカウントにはOrganizationAccountAccessRoleが作成されており、マスターアカウントから新規のアカウントにAssumeRoleできる。
・SCPにより、より強固なアクセス権限の設定が可能。

もっと機能はあります!

AWS Organizationsを使う前に習得しておくべきこと

まず、このAWS Organizationsはセキュリティ関係の設定をしっかりとおこなわないとアカウントの侵入の被害により莫大な請求を求められてしまう可能性が非常に高いです。なので、AWS Organizationsは個人利用であればしっかりとセキュリティ対策を行うか、作成後にアカウントごと削除するなどの方法をとったほうが良いです。
そしてAWS Organizationsを使うのであれば以下の概念は細かく理解しておきましょう。

IAM

とくにポリシーの付与の対象。AssumeRoleについて。
個人的にはAWS Organizationsのアカウント=IAMグループ、OU=SCP(ポリシー)と考えると理解しやすいとおもいます。

アカウント管理のためのAWS各種サービス
↓参考にしてみてください

俺のAWSセキュリティ管理
AWSアカウントを作成したら最低限にやること(アカウント保護)

できるなら個人利用でも使ってみてほしい

個人利用では、マルチアカウントをする理由があまりないかもしれません。ですが、実際に使う使わないでは、得れる理解度が全然違います。管理に多少お金はかかりますが、会社に入ったら多くの企業で使用しているサービスだと思うので、予習して損はないはずです。

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