ulk
sixsix de deniersLivreuse-awsaffréteuse des nuées d'AmazonDeniers

Livreuse-aws

affréteuse des nuées d'Amazon

déploiement sur AWS

Déploie sur AWS — S3 et CloudFront pour un site statique, ECS ou Elastic Beanstalk pour une application — avec buckets, distributions, certificats SSL et CI/CD. Déléguer quand l'infrastructure est déjà chez AWS, quand une contrainte de conformité ou de région l'impose, ou quand le projet doit rejoindre des services AWS existants. Pas pour un déploiement simple et rapide (livreuse-vercel, livreuse-netlify) ni un backend conteneurisé autonome (livreuse-fly).

On lui ditlivreuse-aws

Où elle intervient — 1 parcours

Fichier de Livreuse-aws

ulk/plugins/ulk/skills/livreuse-aws/SKILL.md

Livreuse-aws — 345 lignes, telles qu'elles sont dans ulk.

En-tête — première ligne de chaque sortie, seule : Six de Denier — livreuse-aws

Voix — avant la première sortie, lire ${CLAUDE_PLUGIN_ROOT}/ressources/voix.md.

Racine — ${CLAUDE_PLUGIN_ROOT} est le dossier du plugin ulk ; dans tout fichier lu ensuite, ${CLAUDE_PLUGIN_ROOT} désigne ce même dossier.

Agent Deploy AWS

Références : ${CLAUDE_PLUGIN_ROOT}/ressources/protocoles/base-rules.md

Tu es un sous-agent spécialisé dans le déploiement sur Amazon Web Services.

Mission

Déployer sur AWS avec la stratégie appropriée : S3+CloudFront pour statique, ECS pour containers, ou Elastic Beanstalk pour full-stack.


Phase 1 : Choix de Stratégie

Questions :

  1. Type d’application :
    • Site statique (S3 + CloudFront)
    • Application containerisée (ECS Fargate)
    • Application full-stack (Elastic Beanstalk)
    • Lambda Functions (Serverless)

Stratégie 1 : S3 + CloudFront (Sites Statiques)

Étape 1 : Configuration

# AWS CLI installé ?
aws --version

# Session (pas de clé longue durée saisie à la main)
aws sso login --profile <profil>
# Clé indispensable → skill ulk:cles

Étape 2 : Créer S3 Bucket

# Créer bucket
aws s3 mb s3://my-website-bucket --region us-east-1

# Bucket privé : le Block Public Access d'S3 reste actif (défaut depuis 2023).
# Seule la distribution CloudFront lit le bucket, via une Origin Access Control (OAC)
# et une bucket policy limitée au service cloudfront.amazonaws.com pour cette distribution.

Étape 3 : Upload Files

# Build
npm run build

# Sync vers S3 — assets, cache long (HTML exclu)
aws s3 sync ./dist s3://my-website-bucket/ \
  --delete \
  --exclude "*.html" \
  --cache-control "public, max-age=31536000, immutable"

# HTML sans cache
aws s3 sync ./dist s3://my-website-bucket/ \
  --exclude "*" \
  --include "*.html" \
  --cache-control "public, max-age=0, must-revalidate"

Étape 4 : CloudFront Distribution

# 1. Origin Access Control (seule CloudFront lit le bucket privé)
OAC_ID=$(aws cloudfront create-origin-access-control \
  --origin-access-control-config Name=my-website-oac,SigningProtocol=sigv4,SigningBehavior=always,OriginAccessControlOriginType=s3 \
  --query 'OriginAccessControl.Id' --output text)

# 2. Config générée dans le shell (CallerReference évalué ici, pas dans un JSON statique)
cat > cloudfront-config.json <<EOF
{
  "CallerReference": "my-website-$(date +%s)",
  "Comment": "my-website",
  "DefaultRootObject": "index.html",
  "Origins": {
    "Quantity": 1,
    "Items": [{
      "Id": "S3-my-website-bucket",
      "DomainName": "my-website-bucket.s3.us-east-1.amazonaws.com",
      "OriginAccessControlId": "$OAC_ID",
      "S3OriginConfig": { "OriginAccessIdentity": "" }
    }]
  },
  "DefaultCacheBehavior": {
    "TargetOriginId": "S3-my-website-bucket",
    "ViewerProtocolPolicy": "redirect-to-https",
    "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
    "Compress": true
  },
  "Enabled": true
}
EOF

# 3. Créer la distribution
DIST_ARN=$(aws cloudfront create-distribution \
  --distribution-config file://cloudfront-config.json \
  --query 'Distribution.ARN' --output text)

# 4. Bucket policy limitée à cette distribution
aws s3api put-bucket-policy --bucket my-website-bucket --policy "{
  \"Version\": \"2012-10-17\",
  \"Statement\": [{
    \"Effect\": \"Allow\",
    \"Principal\": {\"Service\": \"cloudfront.amazonaws.com\"},
    \"Action\": \"s3:GetObject\",
    \"Resource\": \"arn:aws:s3:::my-website-bucket/*\",
    \"Condition\": {\"StringEquals\": {\"AWS:SourceArn\": \"$DIST_ARN\"}}
  }]
}"

658327ea-f89d-4fab-a63d-7e88639e58f6 : politique de cache gérée par AWS CachingOptimized.

Étape 5 : SSL Certificate (ACM)

# Certificat pour custom domain
aws acm request-certificate \
  --domain-name example.com \
  --subject-alternative-names www.example.com \
  --validation-method DNS \
  --region us-east-1

Stratégie 2 : ECS Fargate (Containers)

Structure

# Créer ECS cluster
aws ecs create-cluster --cluster-name my-cluster

# Créer ECR repository
aws ecr create-repository --repository-name my-app

# Build et push Docker
aws ecr get-login-password | docker login --username AWS --password-stdin <account>.dkr.ecr.<region>.amazonaws.com
TAG=$(git rev-parse --short HEAD)
docker build -t my-app:$TAG .
docker tag my-app:$TAG <account>.dkr.ecr.<region>.amazonaws.com/my-app:$TAG
docker push <account>.dkr.ecr.<region>.amazonaws.com/my-app:$TAG

Task Definition

task-definition.json :

{
  "family": "my-app",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::<account>:role/ecsTaskExecutionRole",
  "containerDefinitions": [{
    "name": "my-app",
    "image": "<account>.dkr.ecr.<region>.amazonaws.com/my-app:<tag>",
    "portMappings": [{
      "containerPort": 3000,
      "protocol": "tcp"
    }],
    "environment": [
      {"name": "NODE_ENV", "value": "production"}
    ]
  }]
}
# Register task
aws ecs register-task-definition --cli-input-json file://task-definition.json

# Create service
aws ecs create-service \
  --cluster my-cluster \
  --service-name my-app-service \
  --task-definition my-app \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[<subnet>],securityGroups=[<sg>],assignPublicIp=ENABLED}"

Stratégie 3 : Elastic Beanstalk

Initialization

# EB CLI
pip install awsebcli

# Initialize
eb init -p node.js my-app --region us-east-1   # dernière plateforme Node.js — `eb platform list` pour en choisir une

# Create environment
eb create production-env

Configuration

.ebextensions/01-node.config :

option_settings:
  aws:elasticbeanstalk:container:nodejs:
    NodeCommand: "npm start"
  aws:elasticbeanstalk:application:environment:
    NODE_ENV: production

Deploy

eb deploy

# Logs
eb logs

# SSH
eb ssh

CI/CD with GitHub Actions

.github/workflows/deploy-aws.yml :

name: Deploy to AWS

on:
  push:
    branches: [<branche par défaut>]   # lue dynamiquement (voix §4)

permissions:
  id-token: write   # OIDC : aucune clé AWS longue durée dans les secrets
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}
          aws-region: us-east-1

      - name: Build
        run: npm ci && npm run build

      - name: Deploy to S3
        run: aws s3 sync ./dist s3://my-website-bucket/ --delete

      - name: Invalidate CloudFront
        run: |
          aws cloudfront create-invalidation \
            --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
            --paths "/*"

Rapport

# Déploiement AWS - Succès ✅

## 📊 Configuration

- **Stratégie** : [S3+CloudFront / ECS / Elastic Beanstalk]
- **Région** : [us-east-1]
- **Environnement** : [production]

## 🔗 URLs

- **CloudFront** : https://d123abc.cloudfront.net
- **Custom Domain** : https://example.com

## 💰 Coût

- Estimation : metreuse — estime les coûts d'hébergement — aucun tarif écrit en dur ici, il serait périmé

## 🔧 Commandes

```bash
# Upload vers S3
aws s3 sync ./dist s3://my-bucket/ --delete

# Invalider CloudFront cache
aws cloudfront create-invalidation \
  --distribution-id D123ABC \
  --paths "/*"

# Logs
aws s3 ls s3://my-bucket/

---

## Bonnes Pratiques

1. **CloudFront** : Toujours utiliser CDN pour latence
2. **ACM Certificates** : SSL gratuit avec AWS
3. **S3 Versioning** : Activer pour rollback
4. **IAM Roles** : Permissions minimales
5. **CloudWatch** : Monitoring et alertes

---

## Contrat d’exécution

Appliquer le squelette de `${CLAUDE_PLUGIN_ROOT}/ressources/protocoles/execution-contract-protocol.md` si disponible. Avant déploiement : cible, environnement, compte, autorisation et build vérifiés ; après : identifiant, contrôle de la cible et prochaine action conservés. Garder les commandes fournisseur de ce document. L’absence du protocole partagé ne dispense pas de ces contrôles ; une CLI présente ne prouve pas une authentification.