2020.11.16 mise à jour Version Alibaba Cloud Je l'ai fait.
TL;DR Le code HTML dans lequel SSI (include virtual) est décrit est stocké dans un compartiment spécifique de S3, et les sources de l'inclusion sont combinées par Lambda, puis stockées dans un autre compartiment.
Etant donné que S3 est un service d'hébergement de site statique, il ne peut en principe pas être traité dynamiquement côté serveur. Bien sûr, le côté CDN (CloudFront), qui est la destination de la mise en cache après cela, ne peut pas non plus être utilisé.
Dans ce cas, je pense que la méthode standard consiste à créer un environnement de développement local, à les conserver dans des fichiers séparés localement et à les combiner lors de la compilation, mais S3 + est un site existant qui utilisait à l'origine SSI. Malheureusement, ce flux ne peut pas être introduit pour tous les projets, y compris lors du transfert vers CloudFront.
Donc, si SSI a été utilisé à l'origine, j'ai essayé de l'ajuster du côté AWS afin qu'il puisse être utilisé tel quel sans le remplacer tel quel.
(En principe, les paramètres IAM ont été terminés)
En gros, je me réfère à cet article et je le personnalise moi-même. Faire des choses de type SSI avec S3 et Lambda
Sur le site de référence, j'étais un peu inquiet de devoir ajouter .ssi
comme suffixe à l'extension du fichier d'origine.
Un seau pour la température est préparé séparément et ajusté afin qu'il puisse être traité sans ajouter de suffixe.
Fondamentalement, les seuls services que nous utilisons sont S3 et Lambda. CloudFront si nécessaire.
S3 Préparez deux compartiments pour le téléchargement temporaire des fichiers et un compartiment pour la publication.
Le nom peut être n'importe quoi. Cette fois, c'est "s3-ssi-include".
Le nom peut être n'importe quoi. Cette fois, c'est "s3-ssi-include-base".
On suppose que les autorisations d'accès sont définies de manière appropriée. Le compartiment temporaire stocke les fichiers et n'est transmis qu'au compartiment public, il n'est donc pas nécessaire de le publier. Si vous utilisez également CloudFront pour votre bucket de publication, vous n'avez pas besoin de le publier.
Depuis la page de détails du bucket pour temp, allez dans "Propriétés" -> "Notification d'événement" -> "Créer une notification d'événement". La fonction Lambda est maintenant lancée lorsque le fichier est téléchargé (événement PUT)
--Type d'événement: PUT --Destination: fonction Lambda
Après avoir sélectionné jusqu'à, effectuez le réglage une fois. Plus tard, après avoir créé la fonction Lambda, je suis revenu à nouveau sur cet écran et
--Spécifier la fonction Lambda: spécifiez la fonction Lambda créée précédemment dans "Sélectionner parmi les fonctions Lambda"
Il est nécessaire de définir.
Lambda
Lambda détecte l'événement PUT, et si SSI (Server Side Include) est décrit dans le fichier HTML téléchargé, Lambda l'inclura et créera une fonction pour le stocker dans un autre compartiment. Pour S3, modifiez la stratégie de base de ressources pour public pour temporaire et accordez des autorisations. Je pense que ce qui suit sera utile. Politique basée sur les ressources de Lambda lorsqu'elle est déclenchée par S3
import json
import os
import logging
import boto3
from botocore.errorfactory import ClientError
import re
import urllib.parse
logger = logging.getLogger()
logger.setLevel(logging.INFO)
s3 = boto3.client('s3')
def lambda_handler(event, context):
logger.info('## ENVIRONMENT VARIABLES')
logger.info(os.environ)
logger.info('## EVENT')
logger.info(event)
input_bucket = event['Records'][0]['s3']['bucket']['name']
output_bucket = os.environ['S3_BUCKET_TARGET']
logger.info('## INPUT BUKET')
logger.info(input_bucket)
input_key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
logger.info('## INPUT KEY')
logger.info(input_key)
try:
#Obtenir le fichier d'entrée
response = s3.get_object(Bucket=input_bucket, Key=input_key)
if not input_key.endswith('.html'):
s3.copy_object(Bucket=output_bucket, Key=input_key, CopySource={'Bucket': input_bucket, 'Key': input_key})
else:
input_html = response[u'Body'].read().decode('utf-8')
output_html = input_html
#Obtenir la description SSI
include_path_base = re.findall(r'<!--#include virtual="/(.*?)" -->.*?\n', input_html, flags=re.DOTALL)
logger.info('## PATH BASE')
logger.info(include_path_base)
if len(include_path_base) > 0:
for path in include_path_base:
include_path = path
logger.info('## PATH')
logger.info(include_path)
#Obtenir le fichier SSI
try:
include = s3.get_object(Bucket=input_bucket, Key=include_path)
include_html = include[u'Body'].read().decode('utf-8')
#Exécutez SSI
output_html = output_html.replace('<!--#include virtual="/' + include_path + '" -->', include_html)
except ClientError:
pass
#Sortie de fichier
logger.info('## OUTPUT BUKET')
logger.info(output_bucket)
output_key = input_key
logger.info('## OUTPUT KEY')
logger.info(output_key)
out_s3 = boto3.resource('s3')
s3_obj = out_s3.Object(output_bucket, output_key)
response = s3_obj.put(Body = bytes(output_html, 'UTF-8'))
except Exception as e:
logger.info(e)
raise e
Définissez le nom du compartiment public (cette fois s3-ssi-include
) dans la variable d'environnement S3_BUCKET_TARGET
sur l'écran de gestion.
En outre, enregistrez-le une fois jusqu'à présent et spécifiez la fonction __Lambda du côté S3: Spécifiez la fonction Lambda créée précédemment dans "Sélectionner parmi les fonctions Lambda" __.
Cela termine la fonction que Lambda incorpore le fichier d'inclusion au moment du téléchargement du fichier dans le compartiment S3 à des fins temporaires et le transfère vers le compartiment S3 public d'origine.
Je pense qu'il peut être stocké dans S3 comme s'il était téléchargé sur un serveur Web normal, donc si vous devez migrer un site qui utilise SSI vers S3 + CloudFront pour la migration de site, etc., il est courant que ce soit décrit dans SSI. Vous pouvez migrer des fichiers sans avoir à tous les remplacer en même temps. Si vous remplacez les fichiers communs gérés à l'origine par SSI par chaque fichier, les fichiers communs suivants seront codés en dur, ce qui augmentera la main-d'œuvre et les risques opérationnels. Pour être honnête, je ne veux pas en faire trop car il y a un risque d'erreur humaine dans le remplacement du lot lui-même. Compte tenu de cela, je me demande si cette fonction est assez pratique. Cependant, l'inconvénient est que cela coûte cher car il utilise deux seaux, et c'est un peu difficile à comprendre, il est donc nécessaire de le faire connaître correctement.
Maintenant, avec l'évolution de CI / CD et Docker, je pense qu'il y a moins de situations où vous vous inquiétez de ce qui précède. Il n'y a pas que de tels sites dans le monde, alors je me demande si la demande est si faible.
Tout cela vient du terrain.