CloudFrontディストリビューション/ファイルの更新を強制する


146

AmazonのCloudFrontを使用して、Webアプリの静的ファイルを提供しています。

ファイルを更新する必要があること、または更新する必要がある単一のファイルを指摘する必要があることをCloudfrontディストリビューションに伝える方法はありませんか?

この問題の回避策として、logo_1.gif、logo_2.gifなどのファイルにバージョンを付けることをお勧めしますが、これはかなり愚かな解決策のようです。他に方法は絶対にありませんか?



余談ですが、静的ファイルにそのような名前を付けるのは馬鹿ではないと思います。私たちはそれを頻繁に使用しており、バージョン管理のファイルバージョンごとに自動で名前を変更することで、多くの頭痛の種を節約できました。
e's

1
交換する必要があるファイルがオンラインの1000の異なる場所にリンクされていない限り、@ eis。これらのリンクをすべて更新して頑張ってください。
ジェイクウィルソン

@Jakobudなぜその場合にリンクを更新する必要があるのですか?ファイルが変更されている場合、最新ではない特定のバージョンを参照しています。ファイルが変更されていない場合、以前と同じように機能します。
eis

6
場合によっては、会社が何かまたは何か他の種類のアイテムに間違った画像を投稿する際にミスを犯し、法律事務所から削除通知を受け取り、ファイルを置き換える必要がある場合があります。新しい名前で新しいファイルをアップロードするだけでは、この種の問題は修正されません。残念ながら、この問題は最近ますます一般的になっています。
Jake Wilson

回答:


134

朗報です。Amazonはついに無効化機能を追加しました。APIリファレンスを参照してください

これは、APIリファレンスからのサンプルリクエストです。

POST /2010-08-01/distribution/[distribution ID]/invalidation HTTP/1.0
Host: cloudfront.amazonaws.com
Authorization: [AWS authentication string]
Content-Type: text/xml

<InvalidationBatch>
   <Path>/image1.jpg</Path>
   <Path>/image2.jpg</Path>
   <Path>/videos/movie.flv</Path>
   <CallerReference>my-batch</CallerReference>
</InvalidationBatch>

9
無効化には時間がかかることに注意してください(私が読んだいくつかのブログ投稿によると、明らかに5〜30分です)。
Michael Warkentin 2012年

37
あなたはAPIリクエストを自分で作りたくない場合は、アマゾンコンソールにログインし、そこに無効化要求を作成することができますdocs.amazonwebservices.com/AmazonCloudFront/latest/...を
j0nesを

APIを使用して無効化を行う場合、無効化が有効になるまでにどれくらいの時間がかかりますか?
ill_always_be_a_warriors

20
1か月あたりの最初の1,000件の無効化リクエストの後、ファイルあたり0.005ドルかかることを覚えておいてください。aws.amazon.com
cloudfront

1
@MichaelWarkentin API createInvalidationリクエストを行った後も、更新が無効になるまでに5〜10分かかることがわかります。私はあなたのコメントの4年後にこのコメントを書いていることに注意してください。
ティムピーターソン2016年

19

3月19日の時点で、AmazonはCloudfrontのキャッシュTTLを0秒にすることを許可しているため、(理論的には)古いオブジェクトが表示されることはありません。したがって、S3にアセットがある場合、AWS Web Panel => S3 => Edit Properties => Metadataに移動し、「Cache-Control」の値を「max-age = 0」に設定します。

これはAPIドキュメントから直接です:

CloudFrontがオブジェクトをキャッシュするかどうか、およびその期間を制御するには、max-age =ディレクティブでCache-Controlヘッダーを使用することをお勧めします。CloudFrontは、指定された秒数の間オブジェクトをキャッシュします。(最小値は0秒です。)


新しいAWSコンソールUIのこの設定はどこにありますか?見つかりません。
ill_always_be_a_warriors 2013年

1
個々のファイルの設定を見つけましたが、バケットにアップロードされたもののTTLが0になるようにする設定はありますか?
ill_always_be_a_warriors 2013年

私は間違いなくバケット全体の設定にも興味がありますが、これはより速く/より良い解決策であることがわかりました。無効化リクエスト(およびAPIの残りの部分)は非常に混乱し、文書化が不十分です。これがすぐに機能する前に、ホイールを3時間回転させました。
2ビットの錬金術師

33
クレイジーだと思いますが、TTLを0に、max-ageを0に設定すると、実際にはキャッシュなしでCloudFrontが使用されます。これにより、すべてのリクエストが常に更新を確認するオリジンに転送されませんか?本質的にCDNが役に立たなくなるのですか?
acidjazz

6
カスタムドメインで静的なSSL対応のS3サイトを作成するメカニズムとしてcloudfrontを使用している場合は、キャッシングは重要ではありません。また、私たちが議論しているこれらの問題は、開発フェーズでは0回キャッシングが適切であることです。
Dan G

10

Invalidation APIを使用すると、数分で更新されます。PHP Invalidatorを
調べてください。


これはまさに私が探していたものです。gitから自動デプロイするときに、これをBeanstalkappのWebフックにフックします!リンクをありがとう!
コインチルト2011

10

5分で自動更新セットアップ

はい、みんな。CloudFrontの自動更新(無効化)を実行する最善の方法は、ファイルがS3バケットにアップロードされるたびにトリガーされるLambda関数を作成することです(新しいファイルまたは再書き込み)。

これまでにラムダ関数を使用したことがない場合でも、それは本当に簡単です。ステップバイステップの指示に従うだけで、わずか5分で完了します。

ステップ1

https://console.aws.amazon.com/lambda/homeに移動し、[ ラムダ関数の作成 ]をクリックします

ステップ2

空白の関数(カスタム)をクリックします。

ステップ3

空の(ストロークされた)ボックスをクリックして、コンボからS3を選択します。

ステップ4

バケットを選択します(CloudFrontディストリビューションと同じ)

手順5

設定するイベントの種類を「作成したオブジェクト(すべて)」に

手順6

接頭辞と接尾辞を設定するか、それがわからない場合は空のままにします。

手順7

[ トリガーを有効にする ]チェックボックスをオンにして、[ 次へ ]をクリックします

手順8

関数に名前を付けます(例:YourBucketNameS3ToCloudFrontOnCreateAll

手順9

ランタイムとしてPython 2.7以降を選択します

手順10

デフォルトのpythonコードの代わりに次のコードを貼り付けます。

from __future__ import print_function

import boto3
import time

def lambda_handler(event, context):
    for items in event["Records"]:
        path = "/" + items["s3"]["object"]["key"]
        print(path)
        client = boto3.client('cloudfront')
        invalidation = client.create_invalidation(DistributionId='_YOUR_DISTRIBUTION_ID_',
            InvalidationBatch={
            'Paths': {
            'Quantity': 1,
            'Items': [path]
            },
            'CallerReference': str(time.time())
            })

手順11

https://console.aws.amazon.com/cloudfront/homeを開きます新しいブラウザータブでを、次のステップで使用するためにCloudFrontディストリビューションIDをコピーします。

手順12

lambdaタブに戻り、Pythonコードに_YOUR_DISTRIBUTION_ID_ではなくディストリビューションIDを貼り付けます。周囲の引用を保持します。

手順13

ハンドラーの設定:lambda_function.lambda_handler

手順14

役割のコンボボックスをクリックし、[ カスタムの役割を作成する]を選択します。ブラウザの新しいタブが開きます。

手順15

[ ポリシードキュメントの表示 ]、[ 編集 ] 、[ OK ]の順にクリックし、ロール定義を次のように置き換えます(現状のまま):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
          "cloudfront:CreateInvalidation"
      ],
      "Resource": [
          "*"
      ]
    }
  ]
}

手順16

[ 許可]をクリックします。これでラムダに戻ります。作成したロール名が[ 既存のロール]コンボボックスで選択されていることを再確認します。

手順17

セットメモリ(MB) 128へとタイムアウト 5秒です。

手順18

[ 次へ ]をクリックし、[ 関数の作成 ]をクリックします

手順19

準備できた!これで、ファイルをS3にアップロード/再アップロードするたびに、すべてのCloudFront Edgeロケーションで評価されます。

PS-テストするときは、ブラウザーがローカルキャッシュからではなくCloudFrontから画像を読み込んでいることを確認してください。

PSS-1か月あたりの最初の1000ファイルの無効化のみが無料であることに注意してください。制限を超える各無効化は$ 0.005 USDかかります。また、ラムダ関数の追加料金が適用される場合がありますが、非常に安価です。


各S3バッチの最後のアイテムだけですか?
Phil

@Philコードはそのように記述されているため、バケット全体ではなく、新しくアップロードされたファイルのみが無効になります。複数ファイルのアップロードの場合、それらはそれぞれ個別に無効化されます。魅力のように機能します。
カイナックス2017年

このコードが期待どおりに機能する唯一の理由は、S3が通知ごとに1つのアイテムしか含んでいないためです。つまり、配列の長さは常に1であり、その結果、一度に複数のファイルをアップロードしても、まったく新しい通知が届きます。ファイルごと。どのような場合でも、バケット全体の通知は取得されません。それにもかかわらず、AWSがその動作を変更した場合、書かれたこのコードは準備ができていません。長さに関係なく、配列全体を処理するコードを書く方がはるかに安全です。これは、元の(悲しいことに)失敗した点でした。
Phil

AWSがイベントハンドラーを追加する唯一の理由は...まあ...イベントを処理するためです。なぜ彼らはそれを削除するのですか?新しいファイルがどのように追加されても、それはAPIのイベントをトリガーする必要があり、それが現在の動作方法であり、引き続き機能します。私は4年間AWSを使用していますが、AWSは何も変更していないため、以前のコードは機能しなくなりました。APIを変更しても、新しいスタンドアロンバージョンに変更しますが、以前のすべてのバージョンは常にサポートされています。その特定のケースでは、個人的なファイルイベントが削除されるとは思いません。それはおそらく世界中で何百万ものプロジェクトですでに使用されています。
カイナックス2017年

最初のコメントを誤解し、「数量」を意味する場合:1は最後の項目のみを追加します-配列内のすべての項目にFORループがあります。
Kainax 2017年

9

Bucket Explorerには、これを非常に簡単にするUIがあります。方法は次のとおりです。

バケットを右クリックします。「配布の管理」を選択します。
ディストリビューションを右クリックします。[Cloudfront無効化リストを取得]を選択し、[作成]を選択して新しい無効化リストを作成します。無効化するファイルを選択し、「無効化」をクリックします。5〜15分待ちます。


4

botoをインストールしている場合(これはpythonだけでなく、便利なコマンドラインユーティリティもインストールします)、cfadmin次の機能を提供するコマンドラインユーティリティまたは「cloud front admin」を提供します。

Usage: cfadmin [command]
cmd - Print help message, optionally about a specific function
help - Print help message, optionally about a specific function
invalidate - Create a cloudfront invalidation request
ls - List all distributions and streaming distributions

次のコマンドを実行して無効化します。

$sam# cfadmin invalidate <distribution> <path>

実際、cfadminは非常に便利なツールです。特に、console \ bash \ travis ciデプロイメントスクリプトからCloudFrontキャッシュをリセットする必要がある場合はそうです。BTWは、awsへのトラビス展開中にCoudFrontキャッシュをリセット/無効化する方法を投稿します
Mikita

3

このページ(「Cloudfront File Refresh」の最初の結果)にアクセスするすべての人にswook.netで利用可能な +アクセス可能なオンライン無効化ツールがあることを通知するために投稿するだけです

この新しい無効化機能は次のとおりです。

  • 完全にオンライン(インストールなし)
  • 24時間365日利用可能(Googleがホスト)で、メンバーシップは必要ありません。
  • 履歴のサポートとパスチェックにより、ファイルを簡単に無効化できます。(多くの場合、初めて無効化した後、数回クリックするだけです!)
  • また、リリースポストを読むとわかるように、非常に安全です。

完全な開示:これを作成しました。楽しんで!


2
申し訳ありませんが、クレデンシャルが保存またはリークされていない「あなたが言う」ことでさえ、第三者に彼のクレデンシャルを決して与えるべきではありません。リモートのアマゾン認証か何かを実装できますか?
d.raev

少なくともこれをhttpsの背後に置く必要があります。
Oliver Tynes、2015年

オンラインツールは一般的に便利ですが、サードパーティツールに資格情報を提供することは、有効なセキュリティ上の懸念事項になります。公式のWebコンソールまたは公式のCLIツールを使用することをお勧めします
RayLuo

2
他人の安全のために、私はこの答えに反対票を投じています。決して資格情報を求めてはいけません
Moataz Elmasry 2016年

3

これを行う非常に簡単な方法の1つは、FOLDERバージョン管理です。

たとえば、静的ファイルが数百ある場合、それらすべてをyear + versioningによって呼び出されるフォルダーに配置するだけです。

たとえば、2014_v1という名前のフォルダーを使用します。ここには、すべての静的ファイルがあります...

したがって、私のHTML内には常にフォルダーへの参照を入れます。(もちろん、フォルダ名を設定した場所にPHPインクルードがあります。)1つのファイルを変更すると、実際にはすべてのPHPファイルが変更されます。

完全な更新が必要な場合は、フォルダーの名前を2014_v2に変更してソースに変更し、php include内を2014_v2に変更します

すべてのHTMLが自動的に変更され、新しいパス、cloudfront MISSキャッシュが要求され、ソースに要求されます。

例:SOURCE.mydomain.comは私のソース、cloudfront.mydomain.comはcloudfrontディストリビューションへのCNAMEです。

したがって、PHPはこのファイルをcloudfront.mydomain.com/2014_v1/javascript.jsと呼び、完全に更新したい場合は、フォルダーをソースの名前を「2014_v2」に変更し、フォルダーを「2014_v2」に設定してPHPインクルードを変​​更します。

このように、無効化の遅延はなく、コストもかかりません!

これは、stackoverflowでの最初の投稿です。うまくできたことを願っています!



2

Rubyでは、fog gemを使用

AWS_ACCESS_KEY = ENV['AWS_ACCESS_KEY_ID']
AWS_SECRET_KEY = ENV['AWS_SECRET_ACCESS_KEY']
AWS_DISTRIBUTION_ID = ENV['AWS_DISTRIBUTION_ID']

conn = Fog::CDN.new(
    :provider => 'AWS',
    :aws_access_key_id => AWS_ACCESS_KEY,
    :aws_secret_access_key => AWS_SECRET_KEY
)

images = ['/path/to/image1.jpg', '/path/to/another/image2.jpg']

conn.post_invalidation AWS_DISTRIBUTION_ID, images

無効化の場合でも、すべてのアマゾンエッジサーバーで無効化の処理と更新に5〜10分かかります


あなたは私の命を救った!
ファビオ・バティスタ

2

現在のAWS CLIはプレビューモードでの無効化をサポートしています。コンソールで次のコマンドを1回実行します。

aws configure set preview.cloudfront true

npmを使用してWebプロジェクトをデプロイします。私には次のスクリプトがありますpackage.json

{
    "build.prod": "ng build --prod --aot",
    "aws.deploy": "aws s3 sync dist/ s3://www.mywebsite.com --delete --region us-east-1",
    "aws.invalidate": "aws cloudfront create-invalidation --distribution-id [MY_DISTRIBUTION_ID] --paths /",
    "deploy": "npm run build.prod && npm run aws.deploy && npm run aws.invalidate"
}

上記のスクリプトを配置すると、次の方法でサイトを展開できます。

npm run deploy

1
'aws.invalidate'コマンドにアスタリスクが必要だと思います。に変更--paths /してください--paths /*。私のものもあなたのもので、ディストリビューションを無効にすることはありませんでした...
ヘラルド・スミット

1

AWSを使用している場合は、おそらく公式のCLIツールも使用します(遅かれ早かれ)。AWS CLIバージョン1.9.12以降では、ファイル名のリストの無効化がサポートされています。

完全な開示:これを作成しました。楽しんで!


デッドリンク- 404にリード:(バージョン1.9.12がリリースノート(から欠落しているように私はそれを更新することはできませんaws.amazon.com/releasenotes/?tag=releasenotes%23keywords%23cli
SlyDave

おい、thtatはほぼ3年前にリリースされたバージョンでした。最新バージョンを試してみてください。機能はまだ残っています。(完全な開示:AWS CLIで作業しなくなりました。)
RayLuo

ああ、わかりました。すべてのリリースノートの中で奇妙なことに、1.9.12しかありません:D(これは、リンクを更新できないことについて私が得ていたものです)。コメントは、私が行ってAWS CLIのリリースノートを見つける必要があったように、ここでその方法を見つけた人にとっては、よりヒントになりました。害、ファウルはありません。
SlyDave

0

CloudFrontに移動します。

ID /ディストリビューションをクリックします。

[無効化]をクリックします。

「無効化の作成」をクリックします。

巨大な例のボックスに*と入力し、無効化をクリックします

できた

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.