Forza la distribuzione di CloudFront / aggiornamento dei file


146

Sto utilizzando Amazon CloudFront per pubblicare file statici delle mie app Web.

Non c'è modo di dire a una distribuzione cloudfront che deve aggiornare il suo file o indicare un singolo file che dovrebbe essere aggiornato?

Amazon ti consiglia di versioni dei tuoi file come logo_1.gif, logo_2.gif e così via come soluzione alternativa per questo problema, ma sembra una soluzione piuttosto stupida. Non c'è assolutamente nessun altro modo?



come sidenote, non penso che sia stupido nominare file statici del genere. Lo abbiamo usato molto e la ridenominazione automatica secondo la versione del file nel controllo della versione ci ha fatto risparmiare un sacco di mal di testa.
eis,

1
@eis a meno che il file che devi sostituire non sia stato collegato a 1000 diversi luoghi online. Buona fortuna per ottenere tutti questi collegamenti aggiornati.
Jake Wilson,

@Jakobud perché i collegamenti dovrebbero essere aggiornati in quel caso? si riferiscono a una versione specifica, che non è l'ultima, se il file è stato modificato. Se il file non è stato modificato, funzionerà come prima.
eis

6
In alcuni casi un'azienda può commettere un errore nel pubblicare l'immagine sbagliata per qualcosa o qualche altro tipo di articolo in cui ricevono un avviso di rimozione da uno studio legale e devono sostituire il file. Il semplice caricamento di un nuovo file con un nuovo nome non risolverà quel tipo di problema, che purtroppo è un problema che è sempre più comune in questi giorni.
Jake Wilson,

Risposte:


134

Buone notizie. Amazon ha infine aggiunto una funzione di invalida. Vedi il riferimento API .

Questa è una richiesta di esempio dal riferimento 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
Nota che l'invalidazione richiederà del tempo (apparentemente 5-30 minuti secondo alcuni post di blog che ho letto).
Michael Warkentin,

37
Se non vuoi fare una richiesta API da solo, puoi anche accedere ad Amazon Console e creare una richiesta di invalidamento lì: docs.amazonwebservices.com/AmazonCloudFront/latest/…
j0nes

Per quelli di voi che usano l'API per effettuare l'invalidazione, approssimativamente quanto tempo impiega l'invalidazione a diventare effettiva?
ill_always_be_a_warriors il

20
Ricorda che questo costa $ 0,005 per file dopo le tue prime 1.000 richieste di annullamento al mese aws.amazon.com/cloudfront/pricing
TimS

1
@MichaelWarkentin Dopo aver effettuato una createInvalidationrichiesta API , vedo ancora che l'aggiornamento richiede circa 5-10 minuti per invalidare. Notate che scrivo questo commento 4 anni dopo il vostro.
Tim Peterson,

19

A partire dal 19 marzo, Amazon ora consente alla cache TTL di Cloudfront di essere 0 secondi, quindi (teoricamente) non dovresti mai vedere oggetti stantii. Quindi, se hai le tue risorse in S3, puoi semplicemente andare su AWS Web Panel => S3 => Modifica proprietà => Metadati, quindi imposta il valore "Cache-Control" su "max-age = 0".

Questo è direttamente dalla documentazione dell'API :

Per controllare se CloudFront memorizza nella cache un oggetto e per quanto tempo, ti consigliamo di utilizzare l'intestazione Cache-Control con la direttiva max-age =. CloudFront memorizza nella cache l'oggetto per il numero di secondi specificato. (Il valore minimo è 0 secondi.)


Dov'è questa impostazione nella nuova interfaccia utente della Console AWS? Non riesco a trovarlo
ill_always_be_a_warriors il

1
Ho trovato l'impostazione per un singolo file, ma esiste un'impostazione per farlo in modo che qualcosa caricato sul mio bucket abbia un TTL di 0?
ill_always_be_a_warriors il

Anche se sarei sicuramente interessato a un'impostazione a tutto tondo, ho trovato questa una soluzione più veloce / migliore. Le richieste di convalida (insieme al resto dell'API) sono molto confuse e scarsamente documentate e ho girato le ruote per 3 ore prima che funzionasse all'istante.
Two-Bit Alchemist

33
Fammi impazzire ma impostare TTL su 0 e max-age su 0 sta davvero utilizzando CloudFront senza memorizzazione nella cache, non inoltrerebbe tutte le richieste all'origine controllando costantemente gli aggiornamenti? Essenzialmente rendendo inutile la CDN?
acidjazz,

6
Se stai solo utilizzando cloudfront come meccanismo per avere un sito S3 statico abilitato per SSL con un dominio personalizzato, la memorizzazione nella cache non ha importanza. Inoltre, questi problemi che stiamo discutendo è che nelle fasi di sviluppo la memorizzazione nella cache 0 volte è buona.
Dan G,

10

Con l'API di invalidamento, viene aggiornato in pochi minuti.
Dai un'occhiata a PHP Invalidator .


Questo e 'esattamente quello che stavo cercando. Ho intenzione di agganciarlo ai web-hook di Beanstalkapp durante la distribuzione automatica da git! Grazie per il link!
cointilt

10

Configurazione dell'aggiornamento automatico in 5 minuti

Ok ragazzi. Il modo migliore per ora per eseguire l'aggiornamento automatico di CloudFront (invalidazione) è creare la funzione Lambda che verrà attivata ogni volta che un file viene caricato nel bucket S3 (uno nuovo o riscritto).

Anche se non hai mai usato le funzioni lambda prima, è davvero facile: segui le mie istruzioni passo-passo e ci vorranno solo 5 minuti:

Passo 1

Vai su https://console.aws.amazon.com/lambda/home e fai clic su Crea una funzione lambda

Passo 2

Fai clic su Funzione vuota (personalizzata)

Passaggio 3

Fare clic sulla casella vuota (accarezzata) e selezionare S3 dalla combo

Passaggio 4

Seleziona il tuo bucket (come per la distribuzione CloudFront)

Passaggio 5

Impostare un tipo di evento su "Oggetto creato (tutto)"

Passaggio 6

Imposta Prefisso e Suffisso o lascialo vuoto se non sai di cosa si tratta.

Passaggio 7

Seleziona la casella Abilita trigger e fai clic su Avanti

Passaggio 8

Assegna un nome alla tua funzione (qualcosa del tipo: YourBucketNameS3ToCloudFrontOnCreateAll )

Passaggio 9

Seleziona Python 2.7 (o successivo) come Runtime

Passaggio 10

Incolla il seguente codice anziché il codice Python predefinito:

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())
            })

Passaggio 11

Apri https://console.aws.amazon.com/cloudfront/home in una nuova scheda del browser e copia il tuo ID di distribuzione CloudFront per utilizzarlo nel passaggio successivo.

Passaggio 12

Torna alla scheda lambda e incolla il tuo ID di distribuzione invece di _YOUR_DISTRIBUTION_ID_ nel codice Python. Mantieni le citazioni circostanti.

Passaggio 13

Imposta gestore : lambda_function.lambda_handler

Passaggio 14

Fai clic sulla casella combinata ruolo e seleziona Crea un ruolo personalizzato . Verrà aperta una nuova scheda nel browser.

Passaggio 15

Fare clic su Visualizza documento politico , fare clic su Modifica , fare clic su OK e sostituire la definizione del ruolo con quanto segue (così com'è):

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

Passaggio 16

Fai clic su Consenti . Questo ti restituirà a una lambda. Controlla che il nome del ruolo appena creato sia selezionato nella casella combinata Ruolo esistente .

Passaggio 17

Impostare Memory (MB) su 128 e Timeout su 5 sec.

Passaggio 18

Fai clic su Avanti , quindi fai clic su Crea funzione

Passaggio 19

Sei bravo ad andare! Ora, ogni volta che caricherai / ricaricherai qualsiasi file su S3, verrà valutato in tutte le posizioni di CloudFront Edge.

PS: durante il test, assicurati che il tuo browser stia caricando le immagini da CloudFront, non dalla cache locale.

PSS - Si noti che solo i primi 1000 file di invalidazione al mese sono gratuiti, ogni invalidazione oltre il limite costa $ 0,005 USD. Potrebbero essere applicati costi aggiuntivi per la funzione Lambda, ma è estremamente economico.


Solo l'ultimo articolo di ogni lotto S3?
Phil

@Phil Il codice è scritto in questo modo, quindi solo i file appena caricati verranno invalidati, non un intero bucket. In caso di caricamento di più file, ciascuno di essi verrà invalidato separatamente. Funziona come un fascino.
Kainax,

L'unico motivo per cui questo codice funziona come previsto è perché S3 al momento includeva solo un elemento per notifica, ovvero la lunghezza dell'array è sempre felicemente 1, e di conseguenza, anche se carichi più file in una volta sola, ricevi una notifica completamente nuova per file. Non ricevi comunque una notifica per l'intero bucket. Tuttavia, questo codice come scritto non è pronto qualora AWS cambi quel comportamento. Molto più sicuro scrivere codice che gestisca l'intero array, indipendentemente dalla lunghezza, che era il mio punto originale (purtroppo mancato).
Phil

L'unico motivo per cui AWS aggiunge gestori di eventi è ... beh ... per gestire gli eventi. Perché dovrebbero rimuoverlo? Indipendentemente da come è stato aggiunto un nuovo file, dovrebbe attivare l'evento per API ed è così che funziona ora e continuerà a funzionare. Sto usando AWS da 4 anni e non hanno mai cambiato qualcosa, quindi il codice precedente ha smesso di funzionare. Anche se cambiano API, la cambiano in una nuova versione autonoma, ma tutte le versioni precedenti rimangono sempre supportate. In quel caso particolare, non credo che l'evento di file personale verrà mai rimosso. Probabilmente è già utilizzato da milioni di progetti in tutto il mondo.
Kainax,

Nel caso in cui fraintendessi il tuo primo commento e intendi che 'Quantità': 1 aggiungerà solo l'ultimo articolo - c'è un ciclo FOR per ogni articolo dell'array.
Kainax,

9

Bucket Explorer ha un'interfaccia utente che lo rende abbastanza facile ora. Ecco come:

Fai clic con il tasto destro del mouse sul secchio. Seleziona "Gestisci distribuzioni".
Fai clic con il tasto destro sulla tua distribuzione. Selezionare "Ottieni elenco di invalidazione Cloudfront" Quindi selezionare "Crea" per creare un nuovo elenco di invalidazione. Seleziona i file da invalidare e fai clic su "Invalida". Attendi 5-15 minuti.


4

Se hai installato boto (che non è solo per Python, ma installa anche un sacco di utili utilità da riga di comando), offre un programma di utilità da riga di comando specificamente chiamato cfadmino 'cloud front admin' che offre le seguenti funzionalità:

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

Invalidi le cose eseguendo:

$sam# cfadmin invalidate <distribution> <path>

In realtà cfadmin è uno strumento molto utile, soprattutto se è necessario ripristinare la cache CloudFront dallo script di distribuzione console \ bash \ travis ci. A proposito ecco il post su come resettare \ invalidare la cache di CoudFront durante la distribuzione di travis su aws
Mikita Manko,

3

Pubblicando solo per informare chiunque visiti questa pagina (primo risultato su "Aggiornamento file Cloudfront") che è disponibile un invalidatore online di facile utilizzo + accesso disponibile su swook.net

Questo nuovo invalidatore è:

  • Completamente online (nessuna installazione)
  • Disponibile 24x7 (ospitato da Google) e non richiede alcun abbonamento.
  • C'è il supporto per la cronologia e il controllo del percorso per permetterti di invalidare facilmente i tuoi file. (Spesso con pochi clic dopo aver invalidato per la prima volta!)
  • È anche molto sicuro, come scoprirai leggendo il suo post di rilascio .

Divulgazione completa: l'ho fatto. Divertiti!


2
scusate, ma anche "dite" le credenziali non archiviate o sottratte ... non si dovrebbe mai dare le proprie credenziali a terzi. Potrebbe essere implementata un'autenticazione amazon remota o qualcosa del genere?
d.raev,

Dovresti metterlo almeno dietro https.
Oliver Tynes,

Gli strumenti online sono generalmente utili, ma fornire credenziali a strumenti di terze parti sarà un valido problema di sicurezza. Suggerirei di utilizzare la console Web ufficiale o lo strumento CLI ufficiale .
RayLuo,

2
Per la sicurezza degli altri, sto votando a fondo questa risposta. Non dovresti mai chiedere alle persone le loro credenziali
Moataz Elmasry,

3

un modo molto semplice per farlo è il versioning FOLDER.

Quindi, se i tuoi file statici sono centinaia ad esempio, mettili semplicemente in una cartella chiamata per anno + versioning.

per esempio uso una cartella chiamata 2014_v1 dove dentro ho tutti i miei file statici ...

Quindi nel mio HTML inserisco sempre il riferimento alla cartella. (ovviamente ho un PHP incluso dove ho impostato il nome della cartella.) Quindi cambiando in 1 file cambia effettivamente in tutti i miei file PHP ..

Se voglio un aggiornamento completo, devo semplicemente rinominare la cartella in 2014_v2 nella mia fonte e cambiare all'interno del php includendo in 2014_v2

tutto l'HTML cambia automaticamente e richiede il nuovo percorso, la cache MISS cloudfront e la richiede alla fonte.

Esempio: SOURCE.mydomain.com è la mia fonte, cloudfront.mydomain.com è CNAME per la distribuzione cloudfront.

Quindi il PHP ha chiamato questo file cloudfront.mydomain.com/2014_v1/javascript.js e quando voglio un aggiornamento completo, semplicemente rinominare la cartella nella fonte in "2014_v2" e cambio l'inclusione di PHP impostando la cartella su "2014_v2" .

In questo modo non ci sono ritardi per l'invalidazione e NESSUN COSTO!

Questo è il mio primo post in StackOverflow, spero di averlo fatto bene!



2

In rubino, usando la gemma della nebbia

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

anche in caso di invalidamento, sono necessari ancora 5-10 minuti per l'elaborazione e l'aggiornamento dell'annullamento su tutti i server edge di Amazon


Mi hai appena salvato la vita!
Fábio Batista,

2

l'attuale CLI AWS supporta l'invalidazione in modalità anteprima. Eseguire una volta nella console quanto segue:

aws configure set preview.cloudfront true

Distribuisco il mio progetto Web usando npm. Ho i seguenti script nel mio 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"
}

Avendo gli script sopra in atto puoi distribuire il tuo sito con:

npm run deploy

1
Penso che tu abbia bisogno dell'asterisco nel tuo comando 'aws.invalidate', cambia --paths /in --paths /*. anche la mia era come la tua e non ha invalidato la distribuzione ...
Herald Smit,

1

Se stai utilizzando AWS, probabilmente usi anche il suo strumento CLI ufficiale (prima o poi). AWS CLI versione 1.9.12 o successiva supporta l'annullamento di un elenco di nomi di file.

Divulgazione completa: l'ho fatto. Divertiti!


Dead link - porta a un 404 :( e non riesco ad aggiornarlo poiché nelle note di rilascio manca la versione 1.9.12 ( aws.amazon.com/releasenotes/?tag=releasenotes%23keywords%23cli )
SlyDave

Amico, thtat era una versione rilasciata quasi 3 anni fa. Prova l'ultima versione e la funzione è probabilmente ancora lì. (Informativa completa: non lavoro più sulla CLI AWS.)
RayLuo,

oh lo so, ho trovato strano che tra tutti i rilasci, non esiste solo 1.9.12: D (che è quello che stavo ottenendo per non essere in grado di aggiornare il collegamento). Il commento è stato più di un suggerimento per chiunque abbia trovato lì, come ho fatto io e dovevo trovare i rilasci per la CLI AWS. Nessun danno nessun inganno.
SlyDave,

0

Vai a CloudFront.

Fai clic sul tuo ID / Distribuzioni.

Fai clic su Invalidations.

Fai clic su Crea invalida.

Nella casella di esempio gigante digitare * e fare clic su invalidato

Fatto

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.