Introduzione
Nell’ultimo post abbiamo messo in piedi i nostri account, tra cui l’account Development dove andremo a fare i primi sviluppi.
Oggi invece vedremo come impostare un ipotetico progetto dove oltre all’applicativo andremo a definire anche l’infrastruttura, pratica comunemente chiamata IaC, Infrastructure as Code.
Download e setup AWS CLI
Per prima cosa scarichiamo e installiamo il programma AWS CLI versione 2 per il proprio sistema operativo. Una guida e’ fornita da AWS qui.
Setup credenziali
Installata la CLI di AWS impostiamo il nostro profilo Development.
Questo ci permettera’ di usare il nostro account Development direttamente da CLI senza andare ogni volta a fare copia e incolla delle credenziali.
aws configure sso
SSO session name (Recommended): Development
SSO start URL [None]: https://roberttimistest.awsapps.com/start#/
SSO region [None]: eu-central-1
SSO registration scopes [sso:account:access]: # Premere invio
Fatto cio’ vi verra’ aperta una schermata su browser dove andremo a confermare di avere lo stesso codice:
Tornando sul terminale ora avremo due scelte:
There are 2 AWS accounts available to you.
> Administration, [email protected] (100530710461)
> Development, [email protected] (056415619219)
Scegliamo Development:
Using the account ID 056415619219
The only role available to you is: AdministratorAccess
Using the role name AdministratorAccess
CLI default client Region [None]: eu-central-1
CLI default output format [None]: json
CLI profile name [AdministratorAccess-056415619219]: Development
Fatto cio’ ora siamo pronti ad usare il nostro account direttamente da CLI specificando con il flag —profile
Se la sessione scade, dove secondo le impostazioni che abbiamo lasciato dovrebbe durare 1 ora, bastera’ fare aws sso login —profile
Creazione e setup progetto
Iniziamo quindi a impostare il nostro progetto. In questo tutorial andremo ad utilizzare SST, un framework scritto in Typescript che semplifica notevolmente gli sviluppi su AWS tramite CDK, il Cloud Development Kit, ovvero la libreria che viene usata tipicamente per definire l’infrastruttura tramite codice.
Questo framework ci permette di usufruire di alcuni costrutti comodi, ma anche di utilizzare direttamente la CDK.
Io lo uso sempre anche se non ho bisogno dei costrutti proposti, perche’ organizza il codice in una maniera che personalmente apprezzo.
Un’altra cosa bella di SST e’ che ci permettera’ di fare debug direttamente nella console di lambda, container, tabelle dynamo DB e altro.
Per la gestione dei pacchetti node io utilizzero’ PNPM, ma comandi equivalenti esistono anche per Yarn, NPN e simili.
Mettiamoci quindi in una cartella a piacere e lanciamo i seguenti comandi:
pnpm create sst app
cd app
pnpm i
git init
Una volta terminata l’installazione ci troveremo diverse cartelle e file:
tree . -I 'node_modules'
.
├── package.json
├── packages
│ ├── core
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── event.ts
│ │ │ └── todo.ts
│ │ ├── sst-env.d.ts
│ │ └── tsconfig.json
│ └── functions
│ ├── package.json
│ ├── src
│ │ ├── events
│ │ │ └── todo-created.ts
│ │ ├── lambda.ts
│ │ └── todo.ts
│ ├── sst-env.d.ts
│ └── tsconfig.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── sst.config.ts
├── stacks
│ └── MyStack.ts
└── tsconfig.json
All’interno di packages troviamo core e functions.
L’idea e’ quella di organizzare separando il nucleo della nostra logica in core, in modo da poterla riutilizzare su piu’ fronti: Lambda, Container Fargate, Jobs, ecc…
Dentro functions invece definiamo direttamente gli handler delle nostre lambda e SST tramite esbuild impacchettera’ il codice e le dipendenze e fara’ il deploy su AWS. All’interno di stacks invece andremo a definire i nostri stack CDK, ovvero unita’ di risorse e servizi da andare a creare su AWS.
Per prima cosa modifichiamo sst.config.ts per utilizzare il nostro profilo e la nostra regione:
import { SSTConfig } from "sst";
import { API } from "./stacks/MyStack";
export default {
config(input) {
const profiles: Record<string, string> = {
dev: "Development",
};
return {
name: "app",
region: "eu-central-1", // modificare qui la regione
// aggiungiamo il profilo
profile: profiles[input.stage || "dev"] || profiles.dev,
};
},
stacks(app) {
// impostazioni di default per le lambda
app.setDefaultFunctionProps({
runtime: "nodejs18.x",
architecture: "arm_64",
});
// facciamo in modo che alcune risorse tipo S3 e tabelle Dynamo
// vengano rimosse in automatico su Development
if (app.stage !== "prod") {
app.setDefaultRemovalPolicy("destroy");
}
app.stack(API);
},
} satisfies SSTConfig;
A questo punto possiamo provare a lanciare questo progetto di prova usando il comando pnpm sst dev
pnpm sst dev
Please enter a name you’d like to use for your personal stage. Or hit enter to use rob: # Premere invio
✔ Deploying bootstrap stack, this only needs to happen once
SST v2.25.1 ready!
➜ App: app
Stage: rob
Console: https://console.sst.dev
| API PUBLISH_ASSETS_COMPLETE
...
✔ Deployed:
API
ApiEndpoint: https://tjqwcalfc4.execute-api.eu-central-1.amazonaws.com
Connessione console
Andando su https://console.sst.dev avremo la nostra console dalla quale possiamo interagire con lo stack.
Una volta fatto l’accesso inserendo l’email, creiamo un workspace e andiamo a cliccare su Connect an AWS Account nella schermata seguente:
Spuntiamo I acknowledge that AWS CloudFormation might create IAM resources with custom names. e clicchiamo su Create stack.
Una volta terminato sulla nostra console avremo questa vista, con tutte le risorse:
Sulla console clicchiamo sull’endpoint:
E invochiamo la nostra lambda:
curl https://tjqwcalfc4.execute-api.eu-central-1.amazonaws.com
Hello world. The time is 2023-09-15T14:56:30.434Z%
Possiamo gia’ notare da terminale che avremo queste nuovi log:
| Invoked packages/functions/src/lambda.handler
| Built packages/functions/src/lambda.handler
| Done in 177ms
E che nella console avremo il dettaglio dell’invocazione e della risposta:
Modificando il codice della lambda, questo verra’ automaticamente caricato e sara’ pronto per la prossima invocazione:
// packages/functions/src/lambda.ts
import { ApiHandler } from "sst/node/api";
export const handler = ApiHandler(async (_evt) => {
return {
statusCode: 200,
body: `Ciao Mondo. L'ora e' ${new Date().toISOString()}`,
};
});
Invocando:
curl https://tjqwcalfc4.execute-api.eu-central-1.amazonaws.com
Ciao Mondo. L'ora e' 2023-09-15T15:06:03.208Z%
Conclusione
Una volta che avete finito potete distruggere lo stack con pnpm sst remove.
Se avete richieste particolari scrivetemi su [email protected]