Estrarre dati da SAP in modo semplice con Amazon AppFlow
04 Dicembre 2024 - 2 min. read
Mehmed Dourmouch
DevOps Engineer
Bentornati nella nostra mini-serie dedicata al Platform-as-a-Services su AWS.
Nella prima parte, abbiamo percorso i punti chiave di una implementazione ottimale introducendo i principali aspetti da considerare nello sviluppo di un prodotto PaaS. In questo articolo, esamineremo invece la questione dal punto di vista dello stack infrastrutturale analizzando i servizi condivisi alla base del funzionamento di una Web Server vending machine, il nostro obiettivo finale.
Partiamo dai repository.
Nel repository che analizzeremo, come accennato nel precedente articolo, troviamo i vari stack per la creazione di:
La VPC è composta da 9 subnet, 3 per ogni Avaliability Zone, in maniera tale da rendere l’infrastruttura altamente disponibile. Le subnet sono suddivise in:
Il costrutto VPC che ci mette a disposizione AWS CDK ha una gestione dei CIDR assegnati alle subnet che rende impossibile effettuare supernetting, privandoci quindi della possibilità di raggruppare le subnet con netmask piu piccole. Abbiamo quindi deciso di utilizzare questo costrutto, assicurandoci però di sovrascrivere i vari CIDR prima del deploy tramite questa porzione di codice:
myVpc.privateSubnets.forEach((subnet, index) => {
let cidr = `${startSubnetsCidr}.${firstPrivateCidr + index}.${endSubnetsCidr}`
const cfnSubnet = subnet.node.defaultChild as aws_ec2.CfnSubnet;
cfnSubnet.addPropertyOverride('CidrBlock', `${cidr}`);
let name = `${configFile.projectName}-${process.env.ENVIRONMENT}-natted-${subnet.availabilityZone.replace(/^\w+\-\w+\-\d/,'')}`;
let subName = `Subnet-Natted-${subnet.availabilityZone.replace(/^\w+\-\w+\-\d/,'').toUpperCase()}-${process.env.ENVIRONMENT}-Name`;
let subId = `Subnet-Natted-${subnet.availabilityZone.replace(/^\w+\-\w+\-\d/,'').toUpperCase()}-${process.env.ENVIRONMENT}-ID`;
let subCidr = `Subnet-Natted-${subnet.availabilityZone.replace(/^\w+\-\w+\-\d/,'').toUpperCase()}-${process.env.ENVIRONMENT}-CIDR`;
cdk.Aspects.of(subnet).add(
new cdk.Tag(
'Name',
Name
)
)
})
Rilasciata la VPC possiamo deployare al suo interno tutte le risorse necessarie per far funzionare la vending machine come ad esempio gli Application Load Balancer nelle subnet pubbliche, i Web Server nelle subnet nattate, e i database dedicati ai Web Server nelle subnet private.
Affronteremo, nel prossimo articolo, la creazione di queste risorse.
Il bucket S3 creato da questo stack viene utilizzato per stoccare i log, gli artifact e il risultato dei git push su GitLab; vengono inoltre assegnati relativi permessi per i ruoli IAM garantendo full access al bucket, e vengono create le removal policy per i log stoccati:
const myLifeCycleLogsRule: aws_s3.LifecycleRule = {
id: `logs-cleared`,
enabled: true,
prefix: `*-${process.env.ENVIRONMENT}-log`,
expiration: cdk.Duration.days(1)
}
Per poter utilizzare il bucket S3 come sorgente della pipeline occorre attivare il servizio CloudTrail per garantire la possibilità di intercettare gli eventi:
const myTrail = new aws_cloudtrail.Trail(this, `CloudTrail-${process.env.ENVIRONMENT}`, {
trailName: `trail-${process.env.ENVIRONMENT}`,
sendToCloudWatchLogs: true,
bucket: myGlobalBucketS3,
encryptionKey: myKms,
cloudWatchLogGroup: new aws_logs.LogGroup(this, `Logs-${upperEnvironment}`, {
logGroupName: `logs-${process.env.ENVIRONMENT}`,
retention: aws_logs.RetentionDays.THREE_DAYS,
removalPolicy: RemovalPolicy.DESTROY
}),
cloudWatchLogsRetention: aws_logs.RetentionDays.THREE_DAYS,
s3KeyPrefix: `logs-${process.env.ENVIRONMENT}`,
isMultiRegionTrail: false
});
Ma questo non basta. Per far sì che la pipeline venga invocata all'inserimento di un nuovo file all’interno del bucket S3 è necessario configurare un evento di notifica su CloudTrail che stia in ascolto di operazioni di scrittura all’interno bucket S3:
myTrail.addS3EventSelector([{
bucket: myGlobalBucketS3,
objectPrefix: `software/`,
}], {
readWriteType: aws_cloudtrail.ReadWriteType.WRITE_ONLY,
})
myTrail.addS3EventSelector([{
bucket: myGlobalBucketS3,
objectPrefix: `infrastructure/`,
}], {
readWriteType: aws_cloudtrail.ReadWriteType.WRITE_ONLY,
})
Per garantire la cifratura dei dati su S3, su CloudTrail, e nel database, abbiamo creato una chiave KMS customer managed. A questa chiave abbiamo successivamente assegnato una policy che permette alle entità che devono operare sui servizi cifrati di poterla utilizzare:
myKms.addToResourcePolicy( new iam.PolicyStatement({
sid: "Allow principals in the account to decrypt log files",
actions: [
"kms:Decrypt",
"kms:ReEncryptFrom"
],
principals: [ new iam.AccountPrincipal(`${process.env.CDK_DEFAULT_ACCOUNT}`) ],
resources: [
`arn:aws:kms:${process.env.CDK_DEFAULT_REGION}:${process.env.CDK_DEFAULT_ACCOUNT}:key/*`,
],
conditions: {
"StringLike": {
"kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:*:trail/*"
},
"StringEquals": {
"kms:CallerAccount": `${process.env.CDK_DEFAULT_ACCOUNT}`
}
}
}));
Questo ALB gestirà gli accessi ai nostri servizi indirizzandoli in automatico dalla porta 80 in HTTP alla porta 443 in HTTPS:
myAppLoadBalancer.addListener(`App-80-Listener`, {
port: 80,
defaultAction: elbv2.ListenerAction.redirect({
permanent: true,
port: '443',
protocol: 'HTTPS',
})
})
myAppLoadBalancer.addListener(`App-443-Listener`, {
port: 443,
defaultAction: elbv2.ListenerAction.fixedResponse(503, {
contentType: `text/plain`,
messageBody: 'host not found',
})
})
Per porter gestire le richieste effettuate in https sulla porta 443 è necessario che sia associato al relativo listener un certificato facilmente configurabile tramite il servizio AWS Certificate Manager, che oltre alla creazione dei certificati permette anche l’aggiornamento automatico degli stessi.
Le risorse configurate all’interno di questo repository costituiscono le fondamenta per l’intera soluzione.
Nella prossima puntata analizzeremo lo stack applicativo dedicato a ciascun cliente che utilizza i servizi che abbiamo visto oggi.
Per avere una soluzione solida dal punto di vista di sicurezza e scalabilità è necessario che ciò che la mantiene in piedi sia altrettanto affidabile: per questo motivo ci siamo appoggiati unicamente a servizi gestiti da AWS, riducendo quindi l’effort di amministrazione e monitoring.
Ci vediamo tra 14 giorni per l'ultimo capitolo!
Proud2beCloud è il blog di beSharp, APN Premier Consulting Partner italiano esperto nella progettazione, implementazione e gestione di infrastrutture Cloud complesse e servizi AWS avanzati. Prima di essere scrittori, siamo Solutions Architect che, dal 2007, lavorano quotidianamente con i servizi AWS. Siamo innovatori alla costante ricerca della soluzione più all'avanguardia per noi e per i nostri clienti. Su Proud2beCloud condividiamo regolarmente i nostri migliori spunti con chi come noi, per lavoro o per passione, lavora con il Cloud di AWS. Partecipa alla discussione!