Contenu
Deployer un site statique avec CDK
AWS propose de nombreux services, et plusieurs manières de déployer de manière automatisée son infrastructure. Dans cet article, nous découvrirons l’un de ces outils de déploiement automatique, AWS CDK, au travers de l’exemple d’un site statique déployé avec un bucket S3.
Pour aider au suivi, un repository github suivant les mêmes instructions est disponible, un lien pour l’état du projet à chaque étape sera en fin de chaque section.
Le site statique
Le site statique en tant que tel n’a pas d’importance, ainsi nous nous baserons sur le helloworld de react:
npx create-react-app cdk-example
Cette commande crée un nouveau dossier et initialise un projet react, qui sera compilé dans le dossier build
. Si vous préférez utiliser un de vos propre projet, changez simplement les références au dossier build
par son équivalent dans votre projet.
Pour référence, cet article a été écris avec create-react-app
v5.0.1, le projet de référence à ce stade ressemble donc à:
.
├── node_modules
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── README.md
└── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
├── reportWebVitals.js
└── setupTests.js
CDK
Le Cloud Development Kit de AWS est une librairie permettant de décrire son infrastructure AWS en JavaScript, et de déployer et synchroniser son infrastructure à partir ce cette description. Si vous connaissez Terraform, vous pouvez vous figurer une version de Terraform en syntaxe javascript, typescript, python, C#, java ou go et centrée autour de AWS. Pour cet article, nous utiliserons javascript.
L’avantage principal est qu’un développeur avec peu d’expérience devops peux comprendre et travailler avec le CDK dans une syntaxe connue, plutôt que d’apprendre un language nouveau dans son intégralité.
Configurer CDK
Avant de pouvoir utiliser le CDK, nous allons devoir le configurer et installer la CLI AWS v2, la CLI de CDK, et configurer l’accès au compte AWS sur lequel vous déploierez.
AWS propose un guide complet pour l’installation de la CLI que je vous laisse suivre.
Les sections suivantes sont une version résumée et traduite du guide AWS sur l’installation et configuration de AWS CDK, vous pouvez si vous le préférez consulter l’article original.
Installer l’AWS CDK CLI
La CLI est disponible simplement sur npm, il vous suffit donc de lancer la commande
npm i -g aws-cdk
Credentials
AWS recommande fortement l’utilisation de IAM Security Center pour la connexion à AWS via la CLI. La configuration de celui ci est cependant trop longue pour cet article. Si vous souhaitez vous simplifier la tache, vous pouvez utiliser les Access Tokens:
- Connectez vous à la console AWS
- Allez dans le service IAM
- Dans la section
Users
, sélectionnez votre utilisateur (ou créez un nouvel utilisateur pour cet usage) - Dans l’onglet
Security Credentials
, cherchez la sectionAccess Keys
et cliquez surCreate access key
- Sélectionnez
Command Line Interface (CLI)
, cochez la case sur l’avertissement de sécurité, puis sur Next. - Ajoutez une description si vous le souhaitez, cliquez sur
Next
, et vous aurez votre access key. - Utilisez la commande
aws configure
pour configurer l’accès en ajoutant les clefs créées précédemment.
Bootstrap
Le CDK a besoin de certaines ressources créés en amont pour pouvoir faire son travail, fort heureusement, AWS permet de créer automatiquement ces données:
cdk bootstrap
Vous n’aurez besoin d’exécuter ceci qu’une seule fois pour tout le compte AWS, les autres utilisateurs du compte AWS n’auront pas besoin de configurer quoique ce soit de plus. Si vous voulez tout de même utiliser cette commande avec un compte aux droits restreints, les droits minimums que le compte doit avoir pour faire le bootstrap est:
Pour le compte 123456789012
dans la region eu-west-3
.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "IAM",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:CreateRole",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DetachRolePolicy",
"iam:AttachRolePolicy",
"iam:PutRolePolicy"
],
"Resource": [
"arn:aws:iam::123456789012:role/cdk-*"
]
},
{
"Sid": "CloudFormation",
"Effect": "Allow",
"Action": [
"cloudformation:DescribeStackEvents",
"cloudformation:CreateStack",
"cloudformation:GetTemplate",
"cloudformation:DeleteStack",
"cloudformation:CreateChangeSet",
"cloudformation:DescribeChangeSet",
"cloudformation:ExecuteChangeSet",
"cloudformation:DeleteChangeSet",
"cloudformation:DescribeStacks"
],
"Resource": "arn:aws:cloudformation:eu-west-3:123456789012:stack/CDKToolkit/*"
},
{
"Sid": "S3",
"Effect": "Allow",
"Action": [
"s3:CreateBucket",
"s3:SetBucketEncryption"
],
"Resource": "*"
},
{
"Sid": "SSM",
"Effect": "Allow",
"Action": [
"ssm:PutParameter",
"ssm:DeleteParameter"
],
"Resource": "arn:aws:ssm:eu-west-3:123456789012:parameter/cdk-bootstrap/*/version"
},
{
"Sid": "ECR",
"Effect": "Allow",
"Action": [
"ecr:CreateRepository",
"ecr:SetRepositoryPolicy",
"ecr:DeleteRepository"
],
"Resource": "arn:aws:ecr:eu-west-3:123456789012:repository/cdk-*"
}
]
}
Il est cependant bien plus important de vérifier les permissions du role d’execution qui est créé lors de cette opération. Ce role sera utilisé pour tout les déploiement via le CDK, et est par défaut créé avec les droits administrateur, il convient donc de retourner dans IAM, rechercher le role cdk-abc123cde-cfn-exec-role-123456789012-eu-west-3
qui sera apparut, et le limiter aux actions qui doivent être autorisées pour le déploiement.
Pour référence, vous pouvez aussi consulter la documentation AWS officielle.
Ajouter CDK au projet
cdk init
AWS CDK propose une commande cdk init
pour initialiser un nouveau projet utilisant CDK. Cependant, nous avons déjà notre projet existant.
Pour ajouter cdk au projet, nous allons créer un nouveau dossier, et initialiser un projet CDK dedans, et récupérer ce dont nous avons besoins:
mkdir cdk
cd cdk
cdk init --language=javascript
Note: Vous pouvez remplacer --language=javascript
par --language=typescript
pour avoir votre CDK en typescript et générer les fichiers avec.
L’initialisation de CDK nous donne un projet de cette forme:
.
├── bin
│ └── cdk.js
├── cdk.json
├── jest.config.js
├── lib
│ └── cdk-stack.js
├── package.json
├── package-lock.json
├── README.md
├── test
│ └── cdk.test.js
Nous pouvons récupérer presque tout les fichiers tel quel, il nous faudra seulement être plus prudent sur package.json
, et ignorer le package-lock.json
.
package.json
Nous devrons recopier les propriétés bin
et scripts.cdk
.
Nous devront aussi récupérer les dépendances:
npm i aws-cdk jest aws-cdk-lib constructs
Les fichiers de CDK
À ce stade, votre projet devrait ressembler à:
.
├── bin
│ └── cdk.js
├── cdk.json
├── jest.config.js
├── lib
│ └── cdk-stack.js
├── package.json
├── package-lock.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── README.md
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
└── test
└── cdk.test.js
Les différentes choses que nous avons récupéré sont donc:
- Un script
cdk
dans le package.json, pour faciliter l’utilisation de cdk. - Un lien vers le binaire
bin/cdk.js
dans le package.json, pour faciliter l’utilisation de cdk. bin/cdk.js
, qui est le point d’entrée de CDK, et sera utilisé pour configurer CDK (environment, compte AWS…).lib/cdk-stack.js
, qui est utilisé parbin/cdk.js
et permet de configurer ce qui sera déployé.cdk.json
, qui similaire àeslintrc.json
, permet de configurer CDK.
CDK Stack
Nous avons maintenant tout ce qu’il nous faut pour commencer à déployer notre projet avec CDK.
Déployer un bucket S3
Dans lib/cdk-stack.js
, nous pouvons ajouter:
const { Stack, RemovalPolicy, CfnOutput } = require('aws-cdk-lib')
const { Bucket } = require('aws-cdk-lib/aws-s3');
class CdkStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);
const websiteBucket = new Bucket(this, 'website', {
versioned: false,
removalPolicy: RemovalPolicy.DESTROY,
autoDeleteObjects: true
});
new CfnOutput(this, 'bucketName', {
value: websiteBucket.bucketName,
description: 'The name of the s3 bucket',
exportName: 'websiteBucketName',
});
}
}
module.exports = { CdkStack }
Nous déclarons donc un bucket S3 nommé website
appartenant à une stack nommée CdkStack
, qui ne versionne pas les fichiers, et qui détruira ses fichiers au moment d’être détruit.
Nous déclarons aussi une sortie bucketName
qui nous affichera le nom du buscket S3 créé.
Note: Le nom fournit sera utilisé comme une partie du nom, mais son véritable nom sera de la forme cdkstack-website12345678-90abcdefghij
, d’où l’importance de l’afficher. En cas de besoins, vous pouvez aussi retrouver la stack par son nom dans CloudFormation et regarder ses ressources.
Nous pouvons déployer:
cdk deploy
Si nous allons voir dans la console, nous trouverons bien notre bucket créé, mais il sera vide et non accessible.
Faire du bucket un site statique
Il ne nous reste maintenant qu’à envoyer nos fichiers, et rendre le bucket accessible:
const { BucketDeployment, Source } = require('aws-cdk-lib/aws-s3-deployment');
// ...
new BucketDeployment(this, 'deployment', {
destinationBucket: websiteBucket,
sources: [Source.asset('./build')],
retainOnDelete: false
});
Nous créons ainsi un déploiement de fichiers nommé deployment
, basé sur le contenu de build
, qui cible websiteBucket
(le bucket créé précédemment) et qui ne garde pas les fichiers lors de la suppression.
Note: Si ce n’est pas déjà fait, pensez à lancer npm run build
pour générer le dossier build
et le site web à partir de react.
Si nous déployons, nous verrons que notre bucket est redéployé, et contiens bien notre site, mais il n’est toujours pas accessible.
Pour cela, dans la configuration de websiteBucket
, nous devons ajouter:
websiteIndexDocument: 'index.html',
publicReadAccess: true,
Cela définira que notre page d’accueil est index.html
, et ouvrira les droits de lecture publique sur le bucket, permettant d’accéder à la page.
Et pour avoir l’URL, nous ajouterons une nouvelle sortie:
new CfnOutput(this, 'bucketWebsiteUrl', {
value: websiteBucket.bucketWebsiteUrl,
description: 'The website URL',
exportName: 'websiteBucketWebsiteUrl',
});
Déployez, et vous verrez dans la sortie de CDK l’url de votre site, qui sera accessible.
Conclusion
Nous avons vu comment initialiser, installer et configurer CDK pour le déploiement et comment déployer un site web statique. Il convient de remarquer que le site statique n’est accessible que en HTTP (pas de HTTPS) et indique dès le nom qu’il s’agit de quelque chose de déployé via S3.
Pour aller plus loin, nous pourrons ajouter CloudFront pour gérer le HTTPS et le DNS pour avoir un nom de domaine à nous.
Pour rechercher les modules accessibles par CDK et comment les configurer, consultez l’API de AWS CDK.