{"id":820,"date":"2019-07-26T10:21:42","date_gmt":"2019-07-26T08:21:42","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=820"},"modified":"2021-03-17T12:51:21","modified_gmt":"2021-03-17T11:51:21","slug":"pipelines-di-cd-ci-cross-account-con-aws-codepipeline","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/pipelines-di-cd-ci-cross-account-con-aws-codepipeline\/","title":{"rendered":"Pipelines di CD\/CI cross-account con AWS CodePipeline"},"content":{"rendered":"
La suddivisione dei progetti software Cloud su pi\u00f9 account AWS \u00e8 una best practice Amazon consolidata ed estremamente importante per assicurare la segmentazione delle competenze delle varie entit\u00e0 (internal stakeholder, subcontractors etc.) che stanno partecipando al progetto. In questo contesto risulta spesso consigliabile isolare in un account dedicato i vari repository contenenti il codice del progetto (e.g. frontend, backend diviso in microservizi, app mobile) e hostati su AWS CodeCommit. Questo permette di dare permessi granulari ai vari sviluppatori, per lavorare solo sulla parte del codice di loro effettiva competenza.\u00a0<\/span><\/p>\n Tuttavia, per velocizzare le operazioni di deploy del codice nei vari ambienti (e.g sviluppo, staging, produzione) e renderle resilienti a possibili errori umani, risulta essenziale creare delle pipeline di CD\/CI che si occupino di effettuare il deploy del codice sui relativi ambienti in account AWS differenti.\u00a0<\/span><\/p>\n Per fare questo \u00e8 possibile utilizzare CodePipeline, il servizio managed di pipelines offerto da AWS. Tramite CodePipeline \u00e8 infatti possibile effettuare il source del codice da un repository Git da CodeCommit, eseguire i test automatici tramite un container Docker creato per questo scopo (utilizzando il servizio CodeBuild) ed infine procedere al deploy del codice. CodePipeline supporta il deploy \u201cclassico\u201d di applicativi su macchine EC2 tramite AWS CodeDeploy, il deploy di servizi serverless (Lambda Functions) tramite AWS CloudFormation e il deploy di container su Amazon ECS, sia in modalit\u00e0 serverless con Fargate (container as-a-service) che nella modalit\u00e0 tradizionale con i container hostati su istanze EC2.<\/span><\/p>\n La creazione di una Pipeline cross-account, tuttavia, pu\u00f2 essere effettuata esclusivamente utilizzando la AWS CLI, in quanto\u00a0 – ad oggi – non \u00e8 possibile eseguire questa operazione dalla web console. Inoltre, la creazione di questo tipo di pipeline richiede una serie di passaggi preparatori aggiuntivi, che a breve andremo a descrivere, rispetto alla creazione di una pipeline su singolo account.\u00a0<\/span><\/p>\n Nella configurazione qui proposta, le pipeline vengono create direttamente nell\u2019account su cui verr\u00e0 eseguito il deploy: per esempio, la pipeline che si occupa di eseguire la build e il deploy del ramo development si trova sull\u2019account dove \u00e8 presente l\u2019infrastruttura AWS relativa all\u2019ambiente di development. Gli sviluppatori vengono informati dell\u2019esito dei vari step della pipeline tramite un sistema di notifiche automatico tramite Cloudwatch events ed SNS. Tuttavia \u00e8 anche possibile, se necessario, creare le pipeline nell\u2019account dove \u00e8 presente il repository ed eseguire solo lo step di deploy nell\u2019account contenente l\u2019infrastruttura. Alternativamente, \u00e8 possibile utilizzare un account dedicato alle sole pipelines, che eseguono il source dall\u2019account dei repositories e, una volta completata la build, procedono al deploy del codice negli account dei vari ambienti.<\/span><\/p>\n Prima di procedere con la descrizione dei vari step necessari per la creazione di una Pipeline cross-account \u00e8 necessario definire un po\u2019 di nomenclatura:<\/span><\/p>\n I componenti sopra descritti e le loro relazioni reciproche sono rappresentati schematicamente in figura.<\/span><\/p>\n <\/p>\n Procediamo ora con la descrizione passo a passo della procedura utilizzata: per prima cosa \u00e8 necessario procedere alla creazione della CodePipeline KMS Key. Nella schermata riguardante i permessi \u00e8 necessario inserire l\u2019opzione per concedere l\u2019utilizzo della chiave anche all\u2019account Master.<\/span><\/p>\n A questo punto bisogna creare il CodePipeline Bucket con una bucket policy di questo tipo:<\/span><\/p>\n Questo tipo di policy consente l\u2019accesso al bucket al ruolo Cross Account Source Role e impedisce l\u2019upload di file non criptati nel bucket S3. Al posto di <\/span><Cross Account Source Role> <\/span>nella policy va inserito il nome che si desidera usare per il Cross Account Source Role.<\/span><\/p>\n Dopo aver creato la chiave ed il bucket \u00e8 il momento di creare i due ruoli CodePipeline Role e Cross Account Source Role rispettivamente nell\u2019 Account Target e nell\u2019Account Master. Ognuno dei 2 ruoli avr\u00e0 tre policy: <\/span><\/p>\n <\/p>\n <\/p>\n <\/p>\n <\/p>\n\n
{<\/span>\r\n \u00a0\u00a0\u00a0\"Version\": \"2012-10-17\",<\/span>\r\n \u00a0\u00a0\u00a0\"Statement\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Sid\": \"DenyUnEncryptedObjectUploads\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Deny\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Principal\": \"*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": \"s3:PutObject\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"<CodePipeline Bucket ARN>\/*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Condition\": {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"StringNotEquals\": {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:x-amz-server-side-encryption\": \"aws:kms\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Sid\": \"DenyInsecureConnections\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Deny\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Principal\": \"*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": \"s3:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"<CodePipeline Bucket ARN>\/*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Condition\": {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Bool\": {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"aws:SecureTransport\": \"false\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Sid\": \"crossaccount\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Principal\": {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"AWS\": \"arn:aws:iam::<Account Master ID>:role\/<Cross Account Source Role>\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": \"s3:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"<CodePipeline Bucket ARN>\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"<CodePipeline Bucket ARN>\/*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"<CodePipeline Bucket ARN>\/**\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0]<\/span>\r\n}<\/span><\/pre>\n
\n
\n
\n
{<\/span>\r\n \u00a0\u00a0\u00a0\"Version\": \"2012-10-17\",<\/span>\r\n \u00a0\u00a0\u00a0\"Statement\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:BatchGet*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:Get*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:List*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:Describe*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:Post*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:Merge*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:Test*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:Update*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:UploadArchive\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:GitPull\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"arn:aws:codecommit:eu-west-1:<Account Master ID>:*\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": \"codecommit:ListRepositories\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"*\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0]<\/span>\r\n}<\/span><\/pre>\n
\n
\n
{<\/span>\r\n \u00a0\u00a0\u00a0\"Version\": \"2012-10-17\",<\/span>\r\n \u00a0\u00a0\u00a0\"Statement\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"kms:DescribeKey\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"kms:GenerateDataKey*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"kms:Encrypt\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"kms:ReEncrypt*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"kms:Decrypt\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"<CodePipeline KMS Key ARN>\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0]<\/span>\r\n}\r\n<\/span><\/pre>\n
\n
\n
{<\/span>\r\n \u00a0\u00a0\u00a0\"Version\": \"2012-10-17\",<\/span>\r\n \u00a0\u00a0\u00a0\"Statement\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Sid\": \"Example\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:*\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"<CodePipeline Bucket ARN>\/*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"<CodePipeline Bucket ARN>\/**\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span>\r\n \u00a0\u00a0\u00a0]<\/span>\r\n}<\/span><\/pre>\n
\n
\n
\n
{<\/span>\r\n \u00a0\u00a0\u00a0\"Version\": \"2012-10-17\",<\/span>\r\n \u00a0\u00a0\u00a0\"Statement\": {<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": \"sts:AssumeRole\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"<Cross Account Source Role ARN>\"<\/span>\r\n \u00a0\u00a0\u00a0}<\/span>\r\n}\r\n<\/span><\/pre>\n
\n
\n
{<\/span>\r\n \u00a0\u00a0\u00a0\"Statement\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:GetObject\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:GetObjectVersion\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:GetBucketVersioning\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:PutObject\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"arn:aws:s3:::codepipeline*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"arn:aws:s3:::elasticbeanstalk*\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:CancelUploadArchive\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:GetBranch\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:GetCommit\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:GetUploadArchiveStatus\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codecommit:UploadArchive\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codedeploy:CreateDeployment\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codedeploy:GetApplicationRevision\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codedeploy:GetDeployment\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codedeploy:GetDeploymentConfig\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"codedeploy:RegisterApplicationRevision\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0],<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Resource\": \"*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Effect\": \"Allow\"<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0},<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"Action\": [<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"elasticbeanstalk:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"ec2:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"elasticloadbalancing:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"autoscaling:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"cloudwatch:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"s3:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"sns:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"cloudformation:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"rds:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"sqs:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"ecs:*\",<\/span>\r\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"iam:PassRole\"<\/span>\r\n