プログラミング備忘録

仕事で覚えたことのまとめ

何とかして無料でPowerAutomateからHTTPリクエストしたかった人生でした

PowerAutomateからAWSに連携させたい

HTTPリクエストでもAWSQueでもいいから、なんとかしてFormの回答内容をAWSに連携させたい。

やりたいこと:サーバー版PowerAutomateでHTTPリクエストする

PremiumアカウントにすればHTTPリクエストもAWSコネクタも使用できるのでそれで解決するが、いかんせん会社で使用しているアカウントだとアカウントの権限をおいそれと変更できないですよね笑。 Windows10に内包されている無償版のアカウントで何とかできるんじゃないかと。だってHTTPリクエストぞ?自動化に必須じゃあないか。

無料ユーザーにはAPIもたたかせない、ってコト?

結論:私の力ではダメでした。 20210723

うん、無理だわこれ。以下今回検証した内容。もちろん、

検証したこと:Office ScriptをPowerAutomateから実行させる

Step1 とりあえずHTTPリクエストを飛ばす相手を探す

とりあえずGETメソッドで実行できれば問題ないはず・・・

今回使用するのは「Official Joke API」。

f:id:nigou2:20210723152926p:plain GETでリクエストするとsetup =”フリ”とPunchline="オチ"を返してくれます。

Step2 Office Scriptを準備する

OfficeScriptは通常のエクセルマクロよろしく、Web上のエクセルファイルとワンセットでの呼び出しになるので、OneDriveにファイルを適当に作ります。

※テストしたときの階層はこんな感じ

One Drive for Business(自分のファイル)
  ┗ 簡易作業
      ┗ MyWorkbook.xlsx

そのままOneDrive上でファイルを開くと、Excel for the Web で開けます。 特にセルなどは変更せず、リボンの「自動化」から「すべてのスクリプト」を押します。 f:id:nigou2:20210723154225p:plain

画面右側に立ち上がるコードエディターの「+新しいスクリプト」を押し、

function main(workbook: ExcelScript.Workbook)
{
  // Your code here
}

とだけ記載されたエディタが開けたら準備は万端です。

Step3 HTTPリクエストを行うOfficeScriptを記載する。

エディタのコードをすべて消し、以下を貼り付けます。

function main(workbook: ExcelScript.Workbook): Promise<void> {
  let fetchResult = await fetch('https://official-joke-api.appspot.com/jokes/random');
  let json: JSONData = await fetchResult.json();
  console.log(JSON.stringify(json));
}
interface JSONData {
  id: number;
  type: string;
  setup: string;
  punchline: string;
}

実行を押してテストすると、エディタの下のコンソールに結果が出力されました。 f:id:nigou2:20210723154638p:plain

名称を適当に変更し、スクリプトを保存したら準備完了です。あとはPower AutomateでこのOffice Scriptを実行させます。

Step4 PowerAutomateのFlowを作成する

とりあえず手動でフローを実行する簡単なつくりにします。

トリガーは「手動」、 f:id:nigou2:20210723154942p:plain アクションは「スクリプトの実行」 f:id:nigou2:20210723155028p:plain アクションの詳細を下記のように選択し f:id:nigou2:20210723155324p:plain 保存すれば完了です。

早速テストします。

・・・・・・

f:id:nigou2:20210723155925p:plain

Error!

結論

FetchAPIはOfficeScript単体では使えるが、Power Automateから実行させようとするとNot Defined扱いとなり、実行できない(?) axiosでのHTTPリクエストに至ってはOfficeScriptのエディタ時点で使えませんでした。 解決方法ご存じの方、助けてください・・・!

S3にファイルアップロードさせたい ~SDKを使ってみる~

目標

AWSCLIをインストールしていない人間でもファイルをS3にアップできるようにしたい。 社内の人間だけが利用できる状態だとベスト。

今回作るもの

ファイルを選び、ボタン押下で所定のバケットへファイルをアップロードするだけのHTMLの画面。

見栄えやセキュリティとかはいったん無視して、まずは基本骨子を作成する。

工程

  1. ファイルをアップするバケットを作る
  2. CognitoでUserPoolIdを取得する
  3. HTMLで画面を作る
  4. JavaScriptSDKでファイルアップロードのコーディングを行う
  5. HTMLにJavaScriptを連携する

Step1 ファイルをアップするバケットを作る

通常のバケット同様に作成し、アクセス許可のタブから一番下のCross-Origin Resource Sharing (CORS)を編集します。

CORSは複数のオリジン間におけるHTTPリクエストの許可情報、すごいざっくり表現するならAWS以外のWebページからのHTTPリクエストを許容するか、という設定になります。ここが空白だと、HTMLとJavaScriptを作って画像をアップするというHTTPリクエストを行ってもバケット側が拒否してしまいます。

そのため、編集のボタンを押し下記のJsonを貼り付け、リクエストを許可させます。

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]

なおこの時、ブロックパブリックアクセスはすべてONで問題ないです。

f:id:nigou2:20210719101858p:plain

Step2 CognitoでUserPoolIdを取得する

AWSのコンソールにログインした後、Cognitoにアクセスし、左側のIDプールの管理ボタンを押します。 f:id:nigou2:20210717161909p:plain

表示される画面で# 目標 AWSCLIをインストールしていない人間でもファイルをS3にアップできるようにしたい。 社内の人間だけが利用できる状態だとベスト。

工程

  1. ファイルをアップするバケットを作る
  2. CognitoでUserPoolIdを取得する
  3. HTMLで画面を作る
  4. JavaScriptSDKでファイルアップロードのコーディングを行う
  5. HTMLにJavaScriptを連携する

Step1 ファイルをアップするバケットを作る

通常のバケット同様に作成し、アクセス許可のタブから一番下のCross-Origin Resource Sharing (CORS)を編集します。

CORSは複数のオリジン間におけるHTTPリクエストの許可情報、すごいざっくり表現するならAWS以外のWebページからのHTTPリクエストを許容するか、という設定になります。 ここが空白だと、HTMLとJavaScriptを作って画像をアップするというHTTPリクエストを行ってもバケット側が拒否してしまいます。

そのため、編集のボタンを押し下記のJsonを貼り付け、リクエストを許可させます。

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]

Step2 CognitoでアイデンティティプールIDを取得する

Cognitoって何?

AWSアカウントの認証情報がなくてもAWSソリューションを使用できるようになるアイデンティティプール(トークンのようなもの)を発行する。このアイデンティティプールには必要十分のIAMロールを紐づけておく必要がある。

アイデンティティプールの設定方法

AWSのコンソールにログインした後、Cognitoにアクセスし、左側の「IDプールの管理」ボタンを押します。 f:id:nigou2:20210717161909p:plain

表示される画面で「新しいIDプールの作成」を押し、IDプール名を入力します。 またこの時、認証されていないIDに対するアクセスの許可のチェックボックスをONにします。 f:id:nigou2:20210717162404p:plain

次に、Cognitoで発行されるIAMロールを確認します。

f:id:nigou2:20210717163955p:plain

新規で発行されるアイデンティティプールに紐づき新規で作成されるIAMロールについて表示されます。 この後各種AWSのリソースを触れるようにロールにポリシーを設定するので、(デフォルトではPutEventsのみ許可) 検索しやすいように名称を変更しても構いません。

画面右下の「許可」のボタンを押したらアイデンティティプールの作成は完了です。

「AmazonCognitoでの作業開始」と表示されたページが表示されますので、プラットフォームのプルダウンから「javaScript」にします。

AWS認証情報の取得」の枠に下記が表示されます。実際にJavaScriptをコーディングする際に使用しますので、コピーしておきます。

// Amazon Cognito 認証情報プロバイダーを初期化します
AWS.config.region = 'ap-hogehoge-1'; // リージョン
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'ap-hogehoge-1:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
});

アイデンティティプールの使用するIAMロールのポリシーを変更

AWSの検索窓などからIAMのコンソールを表示し、左にある「ロール」を選択します。 f:id:nigou2:20210719095926p:plain 表示される検索窓に、先ほどCognitoのアイデンティティプールを作成したときに同時に発行されているIAMのうち、 認証なしアクセスのときに使用されるロール(UnAuthなどとついているもの)を検索します。

f:id:nigou2:20210719100247p:plain 押下後に表示される画面の中程にある「ポリシーをアタッチします」という青いボタンを押します。

ポリシーのリストが表示されるので、検索窓に「AmazonS3FullAccess」を入力し、チェックボックスを入れて、画面右下の「ポリシーをアタッチ」のボタンを押します。 f:id:nigou2:20210719100805p:plain これで、Cognitoで発行されるアイデンティティプールはS3のファイルにアクセスできるようになりました。

※もし特定のバケットにのみアクセスさせる、あるいはファイルを置くのみにしたい場合は、上記方法ではなくポリシーの作成を行う必要があります。

Step3 HTMLで画面を作る

<html>
    <head>
    <title>Sample</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>

        <div class="container" >
            <div class="content">
                <div>
                ファイル選択
                </div>
                <input type="file" id="getfile-button" multiple /> 
            </div>
            <div class="content">
                <button id="upload-button">アップロード</button>
                <div id="results"></div>
            </div>
        </div>
    </body>
</html>

実際の画面 f:id:nigou2:20210717144255p:plain

この時、inputタグとbuttonタグにはIDを付与しておきます。

Step4 JavaScriptを用意する

下記のJSファイルを準備します。

// S3の認証情報
AWS.config.region = 'ap-northeast-1'; 
AWS.config.credentials = new AWS.CognitoIdentityCredentials({IdentityPoolId: 'XXXXXXXX'});

// アップするS3のバケット、フォルダ情報
var bucket = new AWS.S3({params: {Bucket: 'upload_bucket'}});
var foldername = 'myFolder';
var rightNow =  new Date();
var format_date = rightNow.toLocaleDateString();
var format_time = rightNow.toLocaleTimeString();
var folder_Path = foldername + '/' + format_date + '/' + format_time

// HTML側のオブジェクト
var getfile_button = document.getElementById('getfile-button');
var upload_button = document.getElementById('upload-button');
var results = document.getElementById('results');

// アップロードボタン押下時の動作
upload_button.addEventListener('click', function() {
  var file = getfile_button.files[0];
  if (file) {
      for (let i=0 ; i < getfile_button.files.length;i++ ){
          var tgtfile =getfile_button.files[i];
          var params = {Key:folder_Path + "/"+ tgtfile.name, ContentType: file.type, Body: file};
          bucket.putObject(params, function (err, data){
              results.innerHTML = err ? 'ERROR!' : 'uploaded';
          });
          results.innerHTML = 'error';
      };    
  } else {
      results.innerHTML = 'no file';
  };

})

// S3の認証情報の2行に、Cognito設定時にコピーした認証情報そのままです。

// アップするS3のバケット、フォルダ情報の1行目にアップするバケット、2行目のfoldernameバケット直下のフォルダの名称、folder_Pathはボタン押下差荒れた日時をもとにファイルを分けるために使用しています。

// アップロードボタン押下時の動作以降は、ボタンに対してイベントを付与し、アップ対象として指定したファイルの分だけbucket.putObjectを繰り返します。

Step5 HTMLにJavaScriptを連携する

最後にHTML側の</body>の直前に

    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.922.0.min.js"></script>
    <script src="上記のJSのパス"></script>

を記載すると、HTMLにScriptが連携されます。

公式を見ながら設定していきます。

まとめ

あとはこのHTML、JSファイルを社内の人間しかアクセスできない場所に置くなど、セキュリティ面だけ整理すれば、CLIを持っていなくても

AWSコンテンツへのアクセスを限定開放する黒田如水の画像下さい!!!!(3)CloudFrontでマルチオリジンを設定する

あらすじ

黒田家のAWSのS3にあるファイルやAPIを特定の相手のみが利用できる形で公開するために、CloudFrontを使ってみよう。 だって、亡き友竹中半兵衛重治が言い残したのだから...(エモポイント)

前回CloudFrontのDistributionを作った黒田如水は、今回一つのDistributionから複数のコンテンツへアクセスできるよう設定する。

CloudFrontとは

S3やAPIAWSのアカウントを持っていない人でも、条件に合致するならアクセスできるようにする、という仕組みです。 もしくはWeb上のアクセスの関所。

Distributionとは

DistributionはCloudFront上に置かれた関所一つ一つになります。 この関所を通過することで、バケットポリシーやリソースポリシー上はアクセスをブロックしていたとしても、コンテンツを配布することが可能です。

DistributionOriginをさらに追加する(マルチオリジンを設定する) v20210531

AWSコンソールでCloudFrontを開き、対象のDistributionのIDをクリックし、画面上部のタブからOrigins and Origin Groupsをクリックします。

f:id:nigou2:20210710164608p:plain

表示される画面からCreate Originをクリックします。

OriginAPI Gatewayを追加設定する場合(APIのマルチオリジン)

Origin Domain Nameに、APIのステージを除いたエンドポイントのURLを入力します。 この時、Origin Pathは空白にします。 Minimum Origin SSL ProtocolTLSv1.2Origin Protocol PolicyHTTPS Onlyにします。

f:id:nigou2:20210710164813p:plain

ここまで出来たら右下のCreateを押します。

このオリジンにアクセスを分岐させるために、Behaviorsを更新します。 画面上部のタブからBehaviorの編集画面に移動し、Create Behaviorを押します。 f:id:nigou2:20210710164906p:plain

Path Groupに、先ほどのAPIのステージを入れ、/*をつなげます。 Origin and Origin Groupは先ほど設定したオリジンを、 Viewer Protocol PolicyHTTP and HTTPSを入力します。 このCloudFrontを通して実行を許可させるAPIのメソッドに対応して、 Allowed HTTP Methodsも変更します。(迷ったら3つ目のものでOK)

f:id:nigou2:20210710165043p:plain

以上を設定したら右下のCreateを押します。

補足

考え方としては

Cloud Frontのドメイン => ステージを除いたエンドポイントURL Behavior       => ステージ名

のような対応になります。

OriginにS3バケットを追加設定する場合(S3のマルチオリジン)

前提として、以下のような構造のバケットをマルチオリジンにします。 バケット直下にCloudFrontを経由して配信したいファイルをまとめておくフォルダを作成します。

S3
┣ myBucket -バケット-
┃    ┣ test.png                   -画像A-
┃  ┗ s3test
┃    ┣ test.png        -画像B-
┃      ┗  test2.png
┗ ...

Originを追加します。この時、Origin Pathは空白にします。 f:id:nigou2:20210710165321p:plain

Behaviorを追加します。この時、Path Patternに、Originに指定したバケットのフォルダオブジェクトの名前を入力します。

f:id:nigou2:20210710165349p:plain

以上を設定したら右下のCreateを押します。

補足

バケットの中のコンテンツにたどり着くまでの手順の考え方ですが、 Originの振り分けに使用されたPathPatternは無視されず、リクエストに残ります。

振り分けとオリジンの取得の結果、 HTTPリクエストのCloud_Front_Domain / Behavior_PathPattern / test.png が cloudfront-to-s3-test-aoki/ Behavior PathPattern / test.png に替わるので、 cloudfront-to-s3-test-aoki直下のtest.png(画像A)を取得するのではなく、 Behavior_PathPatternと一致するフォルダの中のtest.png(画像B)を取得します。

Origin Pathを空白にしている理由は、このリクエストの考え方が一層ややこしくなるからです。

逆に言えば、複数のS3バケットをマルチオリジンを設定する場合、配信コンテンツの入っているフォルダ名は、バケットをまたいで重複できない、ということになります。

ここまででできたこと

リクエスト内容に応じて対応するコンテンツを配信する仕組み (関所を通らなければ辿り着けない場所の追加)

やらないといけないこと

アクセス制限のルールの設定 (関所の門番を働かせる)

f:id:nigou2:20210710165439p:plain

f:id:nigou2:20210710165451p:plain

流石「今世の張良」とうたわれた名軍師、黒田如水。 複数コンテンツのアクセス時に通過する場所がCloudFrontに集まっていることの利便性を理解している・・・

次は作ったDistributionにアクセスルールを紐づける工程になります

AWSコンテンツへのアクセスを限定開放する黒田如水の画像下さい!!!!(4)AWSWAFのアクセスルールをCloudFrontに適応する

あらすじ

黒田家のAWSのS3にあるファイルやAPIを特定の相手のみが利用できる形で公開するために、CloudFrontを使ってみよう。 だって、亡き友竹中半兵衛重治が言い残したのだから...(エモポイント)

前回CloudFrontから複数のコンテンツへのアクセスを可能にするマルチオリジンを実現した黒田如水、今回は肝心のアクセス制限ルールを適用するようだ。

大まかな流れ

  • WAFの中のIP SetでIPアドレスAWSに登録する。
  • 登録したIPアドレスを元に、IPアドレスアクセス許可(ないし拒否)のルールを作る
  • 作成したアクセス許可ルールをCloudFrontに適用する

アクセス制限のためのルールを作成する v20210607

ここではCloudFrontの外の仕組みである、WAFというサービスを使用します。 このWAFで作成したアクセス制限のルールを、CloudFrontDistributionに適用する、という流れです。

ルールに使用するIPアドレスを登録する

サービス一覧からAWSWAFを立ち上げます。 f:id:nigou2:20210710173327p:plain

左のペインから IP setsを選び、画面右上のCreate IP setを選びます。 f:id:nigou2:20210710173406p:plain

IPアドレスを入力します。 RegionはデフォルトからGlobalに変更してください。 IP addressesにアクセスを許可する(あるいは拒否する)IPアドレスを入力します。

f:id:nigou2:20210710173454p:plain

アクセスルールを作る

画面左のペインからWeb ACLを選び、画面左上のCreate web ACLを押下します f:id:nigou2:20210710173531p:plain

表示される画面のうちResource typeは 今回のようにCloudFrontに対して適用するルールの場合は CloudFront distributionに必ず設定してください。

f:id:nigou2:20210710173639p:plain

Nextを押し、表示される画面のAddRuleのプルダウンから Add my own rules and rule groupsを選択します。

f:id:nigou2:20210710173747p:plain

下図の画面が表示されるので Rule TypeからIP Setを選び、 ル―ルの名前の入力とルールが適用されるIPセットのプルダウンの選択を済ませます。 最後にActionの箇所でプルダウンから選択した IPセットにしたいして動作(ここでいうとCloudFrontのアクセス)を 許可(Allow)するのか、拒否(Block)するのかを選びます。 ここでは、IPセットのみアクセス可能にしたいので、Allowとします。

f:id:nigou2:20210710173814p:plain

右下のAdd ruleでルールの作成を終了します。 最後に戻ってきた画面でBlockを選びます。

f:id:nigou2:20210710173840p:plain

これで、IPアドレスに合致するものはアクションが可能、合致しないIPアドレスの場合はアクションを拒否、というルールが出来ました。

次のSet rule priorityは、複数のルールを登録した場合の処理の優先順位です。 1つしかルールを作成、設定していないので、何もせずNextを押します。 さらに次のConfigure metricsは、CloudWatch上の表示を決める部分なので、デフォルト値で問題ないです。

最後に、Review and create web ACLで、自分の作成したルールを確認し、画面最下部のCreate web ACLで完了です。

作ったアクセスルールをCloudFrontに設定する

CloudFrontに戻り、ルールを適用するDistributionを開き、Editのボタンから編集画面に移動します。 f:id:nigou2:20210710173926p:plain

開いた画面のAWS WAF Web ACLのプルダウンから、先ほどAWFで作成したルールを選んで、右下の「yes,Edit」で完了です。 f:id:nigou2:20210710174019p:plainf:id:nigou2:20210710174019p:plain

テスト

登録したIPアドレスでアクセスすると図のように正常にアクセスが、

f:id:nigou2:20210710174342p:plain

それ以外でアクセスすると下記のようなアクセス拒否のメッセージが表示されます。

403 ERROR
The request could not be satisfied.
Request blocked. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: **********************************

できたこと

一つのアクセスルールを複数のS3、APIゲートウェイに適用する。

f:id:nigou2:20210710174443p:plain

まとめ

  • 旗印がIPアドレス、つまりWeb上の所属を表す
  • CloudFrontに適用したAWFのルールが門番となり、通行を許可したり、拒否したりという判断を行っている。
  • アクセス時のBehaviorが目的となるOriginへの分岐をつかさどる
  • Originはコンテンツそのものを表す。

黒田家のその後

慶長5年9月、ついに関ヶ原にて石田三成徳川家康が衝突。

黒田如水とその息子長政はAWSというクラウドストレージに寝返りに必要な情報を置き、その成果を十分に発揮。 家康は戦後、黒田長政の右手を三度取って礼を言ったとされる。

このことを聞いた如水は息子に対し「その間左手は何をしていたのか」と長政に尋ねた。自分なら家康○して天下を取るだろうに。

長政は答えて言う。

「某しかAWSのアカウントを持っていない故、福島殿のファイルを代わりにアップしていた」

豊前の大名黒田家の受難は続く。

AWSコンテンツへのアクセスを限定開放する黒田如水の画像下さい!!!!(2)CloudFrontを設定する

あらすじ

黒田家のAWSのS3にあるファイルやAPIを特定の相手のみが利用できる形で公開するために、CloudFrontを使用する。

亡き友、竹中半兵衛重治が残した言葉を胸に刻み・・・(エモポイント)

CloudFrontとは

S3やAPIAWSのアカウントを持っていない人でも、条件に合致するならアクセスできるようにする、という仕組みです。 もしくはWeb上のアクセスの関所。

設定をしていく ver20210531

AWSコンソールからCloudFrontを立ち上げる

コンソールにログイン後、一番上の検索フィールドでCloudFrontと入力します。 サービスに表示されるCloudFrontを押下しましょう。 f:id:nigou2:20210710152846p:plain

下図のように左上にCloudFrontと表示される画面が立ち上がります。

f:id:nigou2:20210710152917p:plain

今回の目的 Distribution を作る

Distributionとは

Distributionとは、Web上に置かれるアクセスの関所そのものを指します。 Distributionの設定要素はいくつかありますが、

Origin
関所を通ってアクセスを許可するAWSの何か(APIやAPIなど)
Behabior アクセスをどのOriginに振り分けるかのルール

の2つだけ押さえておけば一旦は大丈夫です。 逆に言えば、Distributionを作成する際に、最低でも一つずつOriginBehabiorは必要になります。

Distribution初期設定

画面左のペインから一番上のDistributionsを押下します。 f:id:nigou2:20210710153056p:plain

表示された画面の一番上部のCreate Distributionを押下します。 f:id:nigou2:20210710153115p:plain

英語で記載されたページに遷移したかと思います。 f:id:nigou2:20210710153132p:plain

一応、英文の内容ですが

以下のことがしたい場合はDistributionを作成します。
・静的および動的コンテンツ (.html、.css、.php、グラフィック ファイルなど) の配布を高速化します。
・HTTP または HTTPS を使用してメディア ファイルを配布します
・オブジェクトを追加、更新、または削除し、Web フォームからデータを送信します。
・ライブ ストリーミングを使用して、イベントをリアルタイムでストリーミングします。

ファイルをオリジン (Amazon S3 バケットまたはウェブサーバー) に保存します。
ディストリビューションを作成した後、ディストリビューションにオリジンを追加できます。

つまりDistributionでできることを説明しています。Get Startedしましょう。 するとやたら入力ボックスのある画面が表示されます。 f:id:nigou2:20210710153156p:plain

ただし、これを全部入力する必要はありません。 ここで行うのは上から、前掲の必須の2要素、OriginBehavior、最後にDistibutionの設定になります。

Origin設定

OriginにS3バケットを設定する場合

先頭のOriginDomainNameの枠をクリックし、プルダウン表示される中から対象のバケットを選びます。 f:id:nigou2:20210710153324p:plain 加えてバケット内の特定のフォルダオブジェクトを対象に取りたい場合は、Origin Pathにスラッシュとフォルダ名を記載します。 f:id:nigou2:20210710153338p:plain

Restrict Bucket AccessはYesにします。

Origin Access Identityはそのまま、Grant Read Permissions on BucketYes, Update Bucket Policyとします。 これをしないと、S3側のバケットポリシーが更新されず、Distributionからのアクセスも弾いてしまうので注意が必要です。

また、Distributionの初期設定が終わったらバケットのアクセス状態は公開になっていることを確認してください。 f:id:nigou2:20210710153728p:plain これがONになっていると、Distributionからのアクセスも拒否されてしまいます。

OriginにAPI Gatewayを設定する場合

エンドポイントのURLのうち、ステージ名以降を除いた部分をOriginDomainNameの枠に貼り付けます。 f:id:nigou2:20210710154053p:plain 勝手にhttps://が省略されますが問題ございません。 加えてOrigin Pathにスラッシュとステージ名を記載します。 f:id:nigou2:20210710154117p:plain

共通

Enable Origin Shield は指定しなくても大丈夫です。 指定すると、Origin Shield Regionを指定できるようになります。 Origin Shield Regionを指定すると、レイテンシが小さくなる=そのリージョンに通信が最適化される、らしいです。

f:id:nigou2:20210710153417p:plain

Origin IDを入力します。デフォルトで入るものは長いので、管理する際に分かりやすい文字列に差し替えることをお勧めします。 f:id:nigou2:20210710154142p:plain

Minimum Origin SSL ProtocolTLSv1.2Origin Protocol PolicyHTTPS Onlyを指定します。 詳細が気になる方は「こちら(外部)」を確認してください。 f:id:nigou2:20210710154208p:plain

他、接続のタイムアウト、レスポンスのタイムアウト、ヘッダー指定もありますが、基本はデフォルト値で大丈夫です。

Behavior設定

Viewer Protocol PolicyHTTP and HTTPSにします。HTTPリクエスト、HTTPSリクエストいずれも可という状態です。 Allowed HTTP Methods は許容するHTTPリクエストの種類です。POSTされて動くAPIをOriginに指定しているのであればに一番下のものにしないと動かないので、何も考えず一番下のものでいいと思います。

f:id:nigou2:20210710154316p:plain

その他は一切操作は不要ですが、Real-time Log Configurationについては, リアルタイムでログを蓄積したい、且Kinesisを導入しているなら有効化が可能です。 参考

Distribution設定

ここについても基本的には操作は不要です。 強いて言うと下図のAWS WAF Web ACLは、後から使用します。

f:id:nigou2:20210710154345p:plain これが、Distributionに対して適用するアクセス制限のルールをつかさどります。 ※逆に言うとDistributionを作成するだけだと門番がいない関所を立てたにすぎないので注意

最後に画面最後のCreate Distributionを押下したら完成です。

テスト

再び、左のペインからDistributionsに戻ります。 Create Distributionsの下に、今まで作ったDistributionが並んでいるので、作成したもののIDをクリックします。 f:id:nigou2:20210710154443p:plain

下図のような画面が表示されたら、Domain Nameをコピーしましょう。 f:id:nigou2:20210710154839p:plain

OriginにS3バケットを設定した場合

ブラウザのURLにDomain Name/[ファイル名]を入力します。

例)

Origin Domain Nameを「my_bucket」、Origin Pathを「my_folder」、Domain Nameを「hogehoge.cloudfront.net」と設定しているとします。

画像ファイルであるhttps://my_bucket.s3-ap-northeast-1.amazonaws.com/my_folder/myImage.pnghttps://my_bucket.s3-ap-northeast-1.amazonaws.com/my_folderまでがDomain Nameであるhogehoge.cloudfront.netで代替されているので、 ブラウザにはhogehoge.cloudfront.net/myImage.pngと入力します。

OriginにAPI Gatewayを設定した場合

実際にHTTPリクエストを実行して動作を確認します。 例えばPOSTメソッドのAPIなら下図のようになります。

f:id:nigou2:20210710160238p:plain

もし、POSTしたにもかかわらずThe request could not be satisfied.のようなHTML形式のアラートが返った場合は タブのBehaviorAllowed HTTP MethodsでPOSTが許可されているか確認して下図の通りに設定してください。 f:id:nigou2:20210710160302p:plain

ここまででできたこと

関所と、関所を通らないと辿り着けない場所1個の設定

やらないといけないこと

アクセス制限のルールの設定 (関所に門番を立てる) 関所を通らなければ辿り着けない場所の追加

f:id:nigou2:20210710160352p:plain

f:id:nigou2:20210710160407p:plain

流石「今世の張良」とうたわれた名軍師、黒田如水。今時点で使い道がイメージできている・・・・ 次は複数のコンテンツをCloudFrontに紐づかせる、通称マルチオリジンについてです。

参考

Distribution作成時の設定内容:もっとちゃんとしたやつ

AWSコンテンツへのアクセスを限定開放する黒田如水の画像下さい!!!!(1)CloudFrontって何?

序文

慶長3年、太閤豊臣秀吉崩御。天下人を失った諸大名は徳川、石田の2つの陣営に分かれて政争を始める。 そんな折、九州豊前の大名にして織豊に仕えた名軍師、黒田如水は・・・

S3に格納したファイル、Lambda関数の展開に頭を悩ませていた。

ファイル、家臣にも展開したい。API、同盟相手にも使ってみてもらいたい。が、いずれも敵対する他の大名に見られるわけにはいかない秘中の秘。どうにか安心できる相手にのみファイルやAPIの利用権限を与えられないものだろうか。

そして亡き友、竹中半兵衛重治の遺した言葉を思い出す。

CloudFrontがよいぞ」

目的

S3に格納されている画像ファイルやHTML、RestAPIを、自社の人間に限定して展開したい。 ただし展開対象はAWSCLIはおろかAWSアカウントすら持っていないとする。

CloudFrontとは

Amazon CloudFront は、データ、動画、アプリケーション、および API をすべてデベロッパーにとって使いやすい環境で、低レイテンシーの高速転送により世界中の視聴者に安全に配信する高速コンテンツ配信ネットワーク (CDN) サービスです。 Amazonの説明

分かりやすく説明すると、S3やAPIAWSのアカウントを持っていない人でも、条件に合致するならアクセスできるようにする、という仕組みです。

一応ですが、S3やAPI単位でそれぞれにアクセスを制限する方法もあります。 S3であればバケットポリシーAPIであればリソースポリシーがアクセス時の制限を規定しています。 下図のように特定のリソースについてアクセス可能な相手を制限することも可能ですが、複数のバケットAPIのアクセス条件を一元的に管理することはできません。

f:id:nigou2:20210710150656p:plain
今のままでもよいが、管理が面倒ではある

都度都度APIバケットを解放する度、に設定が必要な上、アクセス制御の条件が変わるたびにバケットAPIを1つ1つ編集しなければなりません。 f:id:nigou2:20210710150534p:plain

戦国きっての名軍師の黒田如水さんはこう考えました。

複数の守城がある場合、敵の進行経路を隘路に制限し、そこにて防陣を敷くべし。 同じアクセス制限のルールを複数に同時に適用するなら、アクセスについての関所を設けるべし。

ということで、複数のリソースについてアクセス制限を同時同義にて行う関所の役割を果たすのがCloudFrontというわけです。

f:id:nigou2:20210710151006p:plain
関所の管理で一元管理

一つ一つのS3やAPIのポリシーを設定する必要もありませんから、管理コストを下げることができます。

f:id:nigou2:20210710151056p:plain

マジですぞ、黒田殿。

TeamsのWebHookのメッセージで改行する方法

まずはこの画像を見ていただきたい

f:id:nigou2:20210710122631p:plain
WebHookのメッセージ

このようにTeamsのメッセージででフォントやリンクを設定する際に、

通常のメッセージなら

f:id:nigou2:20210710123037p:plain

のように書式を設定できますが、WebHookの場合はどうなんでしょう。

使うもの

Microsoft Teams

メッセージを自動で投稿する対象。

WebHook

Teamsのチャネルに設定し、発行されるURLにデータをPOSTするとチャネルに自動でメッセージを送ることができる。

PowerShell

HTTPリクエストのテストに使用する。

Step1 チャネルにWebHookを追加する

WebHookを追加したいチャネルの「・・・」からコネクタを選択し、 f:id:nigou2:20210710125517p:plain

「Incoming Webhook」を選択します。 f:id:nigou2:20210710125635p:plain この時、青いボタンが「追加」になっている場合は コネクタを追加するかの確認画面が立ち上がったりますので「OK」を押します。

再度WebHookを追加したいチャネルの「・・・」からコネクタを選択し、 青いボタンが「構成」になっているのを確認し、押します。 f:id:nigou2:20210710125902p:plain

名前と画像を編集し、左下の「作成」ボタンを押します。 f:id:nigou2:20210710130050p:plain

メッセージを送る際に使用するURLがは行されるので、それをコピーしてから左下の「完了」を押します。 f:id:nigou2:20210710130304p:plain

これでWebHookの設定は完了です。

Step2 WebHook経由でメッセージを送る

※WebHookの発行したURLは「https://hogehoge/webhookb2/fugafuga/IncomingWebhook/poepoe」として説明を続けます。

テストを兼ねてメッセージを送ってみます。 PowerShellで下記のコマンドを実行すると、

$url = "https://hogehoge/webhookb2/fugafuga/IncomingWebhook/poepoe"
$postText = @{
                title = "test-title"
                text="test-message"
                } | ConvertTo-Json -Compress
$body = [Text.Encoding]::UTF8.GetBytes($postText)

Invoke-RestMethod -Method Post -Uri $url -Body $body -ContentType 'application/json'```

下図のように実行されます。 f:id:nigou2:20210710132046p:plain

フォントやリンクのないメッセージであればこれで終了です。

# Step3 本文に書式を設定する

WebHookにPOSTするBODYにマークダウン記法で記載することで、自動投稿メッセージ本文の書式を設定できます。 以下に例を載せておきます。

$postText = @{
                title = "test-title"
                text="**太字**
                <br>
                <font color='red'>赤いフォントの文字</font>
                <br>
                [リンク先](https://www.google.com)"
                } | ConvertTo-Json -Compress

f:id:nigou2:20210710132913p:plain