diff --git a/aoe-infra/infra/bin/infra.ts b/aoe-infra/infra/bin/infra.ts index a4bf5346..04931878 100644 --- a/aoe-infra/infra/bin/infra.ts +++ b/aoe-infra/infra/bin/infra.ts @@ -17,7 +17,6 @@ import { EcsServiceStack } from '../lib/ecs-service'; import { FrontendBucketStack } from '../lib/front-end-bucket-stack'; import { FrontendStaticContentDeploymentStack } from '../lib/front-end-content-deployment-stack'; import { EcrStack } from '../lib/ecr-stack'; -import { UtilityStack } from '../lib/utility-stack'; import { ElasticacheServerlessStack } from '../lib/redis-stack'; import { CpuArchitecture } from 'aws-cdk-lib/aws-ecs'; import { BastionStack } from '../lib/bastion-stack'; @@ -31,6 +30,8 @@ import { NamespaceStack } from "../lib/NamespaceStack" import { EfsStack } from "../lib/efs-stack"; import { DocumentdbStack } from "../lib/documentdb-stack"; import { MskStack } from "../lib/msk-stack"; +import { GithubActionsStack } from "../lib/githubActionsStack"; +import { UtilityStack } from "../lib/utility-stack"; const app = new cdk.App(); @@ -55,10 +56,13 @@ else { process.exit(1); } - // dev, qa & prod account resources.. if (environmentName == 'dev' || environmentName == 'qa' || environmentName == 'prod') { + const githubActionsStack = new GithubActionsStack(app, 'GithubActionsStack', { + environment: environmentName + }) + // Remember to update KMS key removal policy const Kms = new KmsStack(app, 'KmsStack', { env: { region: "eu-west-1" }, @@ -176,6 +180,7 @@ if (environmentName == 'dev' || environmentName == 'qa' || environmentName == 'p stackName: `${environmentName}-frontend-bucket`, environment: environmentName, cloudFrontDistribution: Cloudfront.distribution, + githubActionsRole: githubActionsStack.githubActionsRole }) const s3BucketStack = new S3Stack(app, 'S3BucketStack', { @@ -519,6 +524,7 @@ else if (environmentName == 'utility') { env: { region: "eu-west-1" }, stackName: `${environmentName}-utility`, }) + const FrontendEcr = new EcrStack(app, 'FrontendEcrStack', { env: { region: "eu-west-1" }, stackName: 'aoe-web-frontend-ecr', diff --git a/aoe-infra/infra/lib/front-end-bucket-stack.ts b/aoe-infra/infra/lib/front-end-bucket-stack.ts index 2a1f4b20..b840d97f 100644 --- a/aoe-infra/infra/lib/front-end-bucket-stack.ts +++ b/aoe-infra/infra/lib/front-end-bucket-stack.ts @@ -3,12 +3,14 @@ import { Construct } from 'constructs'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as cloudfront from 'aws-cdk-lib/aws-cloudfront'; import * as origins from 'aws-cdk-lib/aws-cloudfront-origins'; +import { Role } from "aws-cdk-lib/aws-iam"; interface FrontendBucketStackProps extends StackProps { // domain: string environment: string, cloudFrontDistribution: cloudfront.Distribution, + githubActionsRole :Role } export class FrontendBucketStack extends Stack { @@ -24,6 +26,8 @@ export class FrontendBucketStack extends Stack { // encryptionKey: props.s3KmsKey, }); + this.bucket.grantWrite(props.githubActionsRole) + // CloudFront OAI, Origin & behaviour const s3oai = new cloudfront.OriginAccessIdentity(this, 'OAI'); const s3origin = new origins.S3Origin(this.bucket, { originAccessIdentity: s3oai }); diff --git a/aoe-infra/infra/lib/githubActionsStack.ts b/aoe-infra/infra/lib/githubActionsStack.ts new file mode 100644 index 00000000..26db2692 --- /dev/null +++ b/aoe-infra/infra/lib/githubActionsStack.ts @@ -0,0 +1,51 @@ +import * as cdk from 'aws-cdk-lib' +import { Construct } from 'constructs' +import * as iam from 'aws-cdk-lib/aws-iam' +import { StackProps } from "aws-cdk-lib"; + +interface CommonStackProps extends StackProps { + environment: string +} + +export class GithubActionsStack extends cdk.Stack { + public githubActionsRole: iam.Role + + constructor(scope: Construct, id: string, props: CommonStackProps) { + super(scope, id, props) + + const githubOidcProvider = new iam.OpenIdConnectProvider(this, `GithubOidcProvider`, { + url: 'https://token.actions.githubusercontent.com', + thumbprints: [ + '6938fd4d98bab03faadb97b34396831e3780aea1', + '1c58a3a8518e8759bf075b76b750d4f2df264fcd' + ], + clientIds: ['sts.amazonaws.com'], + }); + + this.githubActionsRole = new iam.Role(this, `AoeGithubActionsUser`, { + assumedBy: new iam.WebIdentityPrincipal( + githubOidcProvider.openIdConnectProviderArn, + { + StringLike: { + 'token.actions.githubusercontent.com:sub': 'repo:Opetushallitus/aoe:*', + 'token.actions.githubusercontent.com:aud': 'sts.amazonaws.com', + }, + }, + ), + roleName: `aoe-github-actions-deployment-role-${props.environment}`, + }); + + const cdkPolicyStatement = new iam.PolicyStatement({ + actions: [ 'sts:AssumeRole', 'iam:PassRole'], + resources: [ + "arn:aws:iam::*:role/cdk-hnb659fds-deploy-role-*", + "arn:aws:iam::*:role/cdk-hnb659fds-file-publishing-*", + "arn:aws:iam::*:role/cdk-hnb659fds-image-publishing-*", + "arn:aws:iam::*:role/cdk-hnb659fds-lookup-*", + "arn:aws:iam::*:role/cdk-hnb659fds-cfn-exec-*" + ] + }) + this.githubActionsRole.addToPolicy(cdkPolicyStatement) + + } +}