From cad1a04defb7219183752895b8031538fc08b112 Mon Sep 17 00:00:00 2001 From: Chris Pates Date: Thu, 16 Jun 2022 20:17:38 +0100 Subject: [PATCH] Add Deploy to Staging --- cicd/{buildapp.yml => buildapp/buildspec.yml} | 17 +- .../buildspec.yml} | 0 cicd/{ => buildimages}/golang/Dockerfile | 0 cicd/{ => buildimages}/sam/Dockerfile | 0 ...roduction.yaml => production-account.yaml} | 63 +- cicd/cloudformation/staging-account.yaml | 143 ++++ cicd/cloudformation/staging.yaml | 683 ------------------ cicd/deploy/stack.yml | 37 + cicd/{package.yml => package/buildspec.yml} | 10 +- cicd/publish/buildspec.yml | 36 + cicd/{publish.yml => release/buildspec.yml} | 15 +- template.yaml | 7 + 12 files changed, 290 insertions(+), 721 deletions(-) rename cicd/{buildapp.yml => buildapp/buildspec.yml} (89%) rename cicd/{buildimage.yml => buildimages/buildspec.yml} (100%) rename cicd/{ => buildimages}/golang/Dockerfile (100%) rename cicd/{ => buildimages}/sam/Dockerfile (100%) rename cicd/cloudformation/{production.yaml => production-account.yaml} (92%) create mode 100644 cicd/cloudformation/staging-account.yaml delete mode 100644 cicd/cloudformation/staging.yaml create mode 100644 cicd/deploy/stack.yml rename cicd/{package.yml => package/buildspec.yml} (71%) create mode 100644 cicd/publish/buildspec.yml rename cicd/{publish.yml => release/buildspec.yml} (70%) diff --git a/cicd/buildapp.yml b/cicd/buildapp/buildspec.yml similarity index 89% rename from cicd/buildapp.yml rename to cicd/buildapp/buildspec.yml index 3260b5ef..c25ba2db 100644 --- a/cicd/buildapp.yml +++ b/cicd/buildapp/buildspec.yml @@ -5,9 +5,11 @@ phases: commands: # Install go.lang - wget -q https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz + - rm -rf /go - tar -C / -xzf go${GO_VERSION}.linux-amd64.tar.gz - export PATH="/go/bin:$PATH" && export GOPATH="/go" && export PATH="$GOPATH/bin:$PATH" - rm go${GO_VERSION}.linux-amd64.tar.gz + - go version # Install golint - go install golang.org/x/lint/golint@latest @@ -45,20 +47,25 @@ phases: build: commands: # Make clean - - rm -f ${OUTPUT} ${PACKAGED_TEMPLATE} + - rm -f main packaged.yaml # Make go-build - go build -o ${APP_NAME} main.go - - # Make main - - goreleaser build --snapshot --rm-dist + + # Does it exist? + - ls ${APP_NAME} + + # Does it run? + - ./${APP_NAME} --version post_build: commands: + # Make main + - goreleaser build --snapshot --rm-dist + - ls -la artifacts: files: - ${APP_NAME} - dist/**/* - - cmd/**/* diff --git a/cicd/buildimage.yml b/cicd/buildimages/buildspec.yml similarity index 100% rename from cicd/buildimage.yml rename to cicd/buildimages/buildspec.yml diff --git a/cicd/golang/Dockerfile b/cicd/buildimages/golang/Dockerfile similarity index 100% rename from cicd/golang/Dockerfile rename to cicd/buildimages/golang/Dockerfile diff --git a/cicd/sam/Dockerfile b/cicd/buildimages/sam/Dockerfile similarity index 100% rename from cicd/sam/Dockerfile rename to cicd/buildimages/sam/Dockerfile diff --git a/cicd/cloudformation/production.yaml b/cicd/cloudformation/production-account.yaml similarity index 92% rename from cicd/cloudformation/production.yaml rename to cicd/cloudformation/production-account.yaml index 7619ccc3..4206801f 100644 --- a/cicd/cloudformation/production.yaml +++ b/cicd/cloudformation/production-account.yaml @@ -47,6 +47,9 @@ Metadata: CodeStarConnection: default: "arn:aws:codestar-connections:::connection/abcd1234-ab12-ab12--ab12-abcdef123456" +Conditions: + AddCodeBuildResource: !Equals [ !Ref StagingAccount, true ] + Resources: CodePipelineLogGroup: @@ -238,18 +241,16 @@ Resources: Provider: CodeBuild OutputArtifacts: - Name: Built - RunOrder: '2' + RunOrder: '1' Configuration: ProjectName: !Ref CodeBuildApp - - Name: Staging - Actions: - Name: PackageApp ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild - RunOrder: 1 + RunOrder: 2 Configuration: ProjectName: !Ref CodeBuildPackage PrimarySource: Source @@ -258,13 +259,15 @@ Resources: InputArtifacts: - Name: Built - Name: Source - - Name: PublishStaging + - Name: Staging + Actions: + - Name: ReleaseCandidate ActionTypeId: Category: Build Owner: AWS Version: 1 Provider: CodeBuild - RunOrder: '2' + RunOrder: '1' Configuration: ProjectName: !Ref CodeBuildStaging PrimarySource: Source @@ -273,6 +276,30 @@ Resources: InputArtifacts: - Name: Source - Name: Packaged + - Name: Deploy + ActionTypeId: + Category: Deploy + Owner: AWS + Version: '1' + Provider: CloudFormation + RunOrder: '2' + Configuration: + ActionMode: CREATE_UPDATE + Capabilities: CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND + ChangeSetName: pipeline-changeset + ParameterOverrides: !Sub '{"ApplicationArn": "arn:aws:serverlessrepo:${AWS::Region}:${AWS::AccountId}:applications/${ApplicationName}-Staging"}' + RoleArn: + Fn::If: + - AddCodeBuildResource + - !Sub arn:aws:iam::${StagingAccount}:role/ProductionAcctCodePipelineCloudFormationRole + - !Ref AWS::NoValue + StackName: !Sub Deploy-${ApplicationName} + TemplatePath: 'Source::cicd/deploy/stack.yml' + OutputFileName: 'stack-outputs.json' + OutputArtifacts: + - Name: Deployed + InputArtifacts: + - Name: Source - Name: Approvals Actions: - Name: PassedStaging @@ -305,7 +332,7 @@ Resources: ServiceRole: !Ref CodeBuildImagesRole Source: Type: CODEPIPELINE - BuildSpec: "cicd/buildimage.yml" + BuildSpec: "cicd/buildimages/buildspec.yml" Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:5.0 @@ -315,13 +342,13 @@ Resources: - Name: ImageRepo Value: golang - Name: ImageVersion - Value: "1.18.1" + Value: "1.18.2" - Name: AccountId Value: !Ref AWS::AccountId - Name: Region Value: !Ref AWS::Region - Name: DockerPath - Value: 'cicd/golang/' + Value: 'cicd/buildimages/golang/' Artifacts: Name: !Ref ApplicationName Type: CODEPIPELINE @@ -360,7 +387,7 @@ Resources: - Name: Region Value: !Ref AWS::Region - Name: DockerPath - Value: 'cicd/sam/' + Value: 'cicd/buildimages/sam/' Artifacts: Name: !Ref ApplicationName Type: CODEPIPELINE @@ -384,7 +411,7 @@ Resources: ServiceRole: !Ref CodeBuildAppRole Source: Type: CODEPIPELINE - BuildSpec: "cicd/buildapp.yml" + BuildSpec: "cicd/buildapp/buildspec.yml" Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:5.0 @@ -393,7 +420,7 @@ Resources: - Name: ARTIFACT_S3_BUCKET Value: !Sub ${ArtifactBucket} - Name: GO_VERSION - Value: "1.18.1" + Value: "1.18.2" - Name: OUTPUT Value: main - Name: APP_NAME @@ -421,7 +448,7 @@ Resources: ServiceRole: !Ref CodeBuildPackageRole Source: Type: CODEPIPELINE - BuildSpec: "cicd/package.yml" + BuildSpec: "cicd/package/buildspec.yml" Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:5.0 @@ -456,7 +483,7 @@ Resources: ServiceRole: !Ref CodeBuildPublishRole Source: Type: CODEPIPELINE - BuildSpec: "cicd/publish.yml" + BuildSpec: "cicd/publish/buildspec.yml" Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:5.0 @@ -464,10 +491,10 @@ Resources: EnvironmentVariables: - Name: ARTIFACT_S3_BUCKET Value: !Sub ${ArtifactBucket} - - Name: SDLC - Value: 'staging' - Name: ShareWith Value: !Ref StagingAccount + - Name: AppARN + Value: !Sub "arn:aws:serverlessrepo:${AWS::Region}:${AWS::AccountId}:applications/${ApplicationName}-Staging" Artifacts: Name: !Ref ApplicationName Type: CODEPIPELINE @@ -492,7 +519,7 @@ Resources: ServiceRole: !Ref CodeBuildPublishRole Source: Type: CODEPIPELINE - BuildSpec: "cicd/publish.yml" + BuildSpec: "cicd/release/buildspec.yml" Environment: ComputeType: BUILD_GENERAL1_SMALL Image: aws/codebuild/standard:5.0 @@ -500,8 +527,6 @@ Resources: EnvironmentVariables: - Name: ARTIFACT_S3_BUCKET Value: !Sub ${ArtifactBucket} - - Name: SDLC - Value: release Artifacts: Name: !Ref ApplicationName Type: CODEPIPELINE diff --git a/cicd/cloudformation/staging-account.yaml b/cicd/cloudformation/staging-account.yaml new file mode 100644 index 00000000..b100823e --- /dev/null +++ b/cicd/cloudformation/staging-account.yaml @@ -0,0 +1,143 @@ +AWSTemplateFormatVersion: '2010-09-09' + +Description: + This CloudFormation template will deploy a an IAM role and some Secrets to + allow the CI/CD pipeline in the production account to deploy candidate releases + (via privately shared app in the AWS Serverless Application Repository (SAR). + +Parameters: + ProductionAccount: + Description: AWS Account permited to depoy into this account + Type: String + AllowedPattern: '[0-9]+' + GoogleCredentials: + Description: Credentials to log into Google (content of credentials.json) + Type: String + NoEcho: true + GoogleAdminEmail: + Description: Google Admin email + Type: String + NoEcho: true + SCIMEndpointUrl: + Description: AWS SSO SCIM Endpoint Url + Type: String + NoEcho: true + SCIMEndpointAccessToken: + Description: AWS SSO SCIM AccessToken + Type: String + NoEcho: true + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Pipeline + Parameters: + - ProductionAccount + - Label: + default: Google Workspace + Parameters: + - GoogleAdminEmail + - GoogleCredentials + - Label: + default: AWS SSO + Parameters: + - SCIMEndpointUrl + - SCIMEndpointAccessToken + + ParameterLabels: + ProductionAccount: + default: "123456789012" + GoogleCredentials: + default: "contents of credentials.json" + GoogleAdminEmail: + default: "admin@WorkspaceDomain" + SCIMEndpointUrl: + default: "https://scim..amazonaws.com//scim/v2/" + SCIMEndpointAccessToken: + default: "AWS SSO SCIM Access Token" + +Resources: + + GoogleCredentialSecret: + Type: "AWS::SecretsManager::Secret" + DeletionPolicy: Retain + UpdateReplacePolicy: Delete + Properties: + Name: E2ETestGoogleCredentials + SecretString: !Ref GoogleCredentials + + GoogleAdminEmailSecret: + Type: "AWS::SecretsManager::Secret" + DeletionPolicy: Retain + UpdateReplacePolicy: Delete + Properties: + Name: E2ETestGoogleAdminEmail + SecretString: !Ref GoogleAdminEmail + + SSoSCIMUrlSecret: # This can be moved to custom provider + Type: "AWS::SecretsManager::Secret" + DeletionPolicy: Retain + UpdateReplacePolicy: Delete + Properties: + Name: E2ETestSCIMEndpointUrl + SecretString: !Ref SCIMEndpointUrl + + SSoSSCIMAccessTokenSecret: # This can be moved to custom provider + Type: "AWS::SecretsManager::Secret" + DeletionPolicy: Retain + UpdateReplacePolicy: Delete + Properties: + Name: E2ETestSCIMAccessToken + SecretString: !Ref SCIMEndpointAccessToken + + ProductionAccountCloudformationRole: + Type: AWS::IAM::Role + Properties: + RoleName: ProductionAcctCodePipelineCloudFormationRole + AssumeRolePolicyDocument: + Statement: + - Action: ['sts:AssumeRole'] + Effect: Allow + Principal: + AWS: !Ref ProductionAccount + Version: '2012-10-17' + Path: / + Policies: + - PolicyName: ProductionAcctCodePipelineCloudFormation-Policy + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: + - 'iam:PassRole' + - 'cloudformation:*' + Effect: Allow + Resource: '*' + + CFDeployerRole: + Type: AWS::IAM::Role + Properties: + RoleName: CloudFormationDeployerRole + AssumeRolePolicyDocument: + Statement: + - Action: ['sts:AssumeRole'] + Effect: Allow + Principal: + Service: 'cloudformation.amazonaws.com' + Version: '2012-10-17' + Path: / + Policies: + - PolicyName: CloudFormation-Deployer-Policy + PolicyDocument: + Version: '2012-10-17' + Statement: + - Action: '*' + Effect: Allow + Resource: '*' + +Outputs: + + ProductionAccountCloudformationRoleArn: + Description: The Role available to the Production account for deployment + Value: !GetAtt ProductionAccountCloudformationRole.Arn + diff --git a/cicd/cloudformation/staging.yaml b/cicd/cloudformation/staging.yaml deleted file mode 100644 index b59a961f..00000000 --- a/cicd/cloudformation/staging.yaml +++ /dev/null @@ -1,683 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Transform: 'AWS::Serverless-2016-10-31' - -Description: - This CloudFormation template will deploy a full CI/CD pipeline for SSO - Sync. It includes building with AWS CodeBuild, publishing to a - staging (private) AWS Serverless Application Repository (SAR), deployment - of the beta into a staging environment via AWS CloudFormation. If the commit - is also a release, then the app will also be published to the public SAR entry. - -Parameters: - ApplicationName: - Description: This will be used to name the pipeline and build resources - Default: SSOSync - Type: String - AllowedPattern: '[A-Za-z0-9-]+' - StagingBuildAllowedAccounts: - Description: The AWS Account Id(s) with which to share the staging build (comma delimited) - Type: String - AllowedPattern: '[0-9,]+' - IntegrationTestAccount: - Description: AWS Account where staging build is automatically deployed and tested - Type: String - AllowedPattern: '[0-9]+' - GoogleCredentials: - Description: Credentials to log into Google (content of credentials.json) - Type: String - NoEcho: true - GoogleAdminEmail: - Description: Google Admin email - Type: String - NoEcho: true - SCIMEndpointUrl: - Description: AWS SSO SCIM Endpoint Url - Type: String - NoEcho: true - SCIMEndpointAccessToken: - Description: AWS SSO SCIM AccessToken - Type: String - NoEcho: true - -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Application Configuration - Parameters: - - ApplicationName - - Label: - default: Details of Staging and Test environments - Parameters: - - StagingBuildAllowedAccounts - - Label: - default: End 2 End Test environment - Parameters: - - IntegrationTestAccount - - GoogleCredentials - - GoogleAdminEmail - - SCIMEndpointUrl - - SCIMEndpointAccessToken - - ParameterLabels: - ApplicationName: - default: "SSOSync" - StagingBuildAllowedAccounts: - default: "111111111111,2222222222222,33333333333" - IntegrationTestAccount: - default: "123456789012" - GoogleCredentials: - default: "contents of credentials.json" - GoogleAdminEmail: - default: "admin@WorkspaceDomain" - SCIMEndpointUrl: - default: "https://scim..amazonaws.com//scim/v2/" - SCIMEndpointAccessToken: - default: "AWS SSO SCIM Access Token" - -Resources: - - GoogleCredentialSecret: - Type: "AWS::SecretsManager::Secret" - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - Properties: - Name: E2ETestGoogleCredentials - SecretString: !Ref GoogleCredentials - Tags: - - Key: Application - Value: !Ref ApplicationName - - GoogleAdminEmailSecret: - Type: "AWS::SecretsManager::Secret" - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - Properties: - Name: E2ETestGoogleAdminEmail - SecretString: !Ref GoogleAdminEmail - Tags: - - Key: Application - Value: !Ref ApplicationName - - SSoSCIMUrlSecret: # This can be moved to custom provider - Type: "AWS::SecretsManager::Secret" - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - Properties: - Name: E2ETestSCIMEndpointUrl - SecretString: !Ref SCIMEndpointUrl - Tags: - - Key: Application - Value: !Ref ApplicationName - - SSoSSCIMAccessTokenSecret: # This can be moved to custom provider - Type: "AWS::SecretsManager::Secret" - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - Properties: - Name: E2ETestSCIMAccessToken - SecretString: !Ref SCIMEndpointAccessToken - Tags: - - Key: Application - Value: !Ref ApplicationName - - SARPublishApp: - Type: AWS::Serverless::Application - UpdateReplacePolicy: Delete - Properties: - Location: - ApplicationId: 'arn:aws:serverlessrepo:us-east-1:077246666028:applications/aws-serverless-codepipeline-serverlessrepo-publish' - SemanticVersion: 1.0.0 - - CodePipelineArtifactS3Bucket: - Type: AWS::S3::Bucket - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - - CodePipelineArtifactS3BucketPolicy: - Type: AWS::S3::BucketPolicy - Properties: - Bucket: !Ref CodePipelineArtifactS3Bucket - PolicyDocument: - Version: '2012-10-17' - Statement: - - Action: ['s3:GetObject'] - Effect: Allow - Principal: - Service: 'serverlessrepo.amazonaws.com' - Resource: - - !Sub ${CodePipelineArtifactS3Bucket.Arn}/* - Condition: - StringEquals: - aws:SourceAccount: !Ref AWS::AccountId - - Sid: DenyUnEncryptedObjectUploads - Effect: Deny - Principal: "*" - Action: s3:PutObject - Resource: !Sub ${CodePipelineArtifactS3Bucket.Arn}/* - Condition: - StringNotEquals: - s3:x-amz-server-side-encryption: aws:kms - - Sid: DenyInsecureConnections - Effect: Deny - Principal: "*" - Action: "s3:*" - Resource: !Sub ${CodePipelineArtifactS3Bucket.Arn}/* - Condition: - Bool: - aws:SecureTransport: false - - StagingS3Bucket: - Type: AWS::S3::Bucket - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - - StagingS3BucketPolicy: - Type: AWS::S3::BucketPolicy - Properties: - Bucket: !Ref StagingS3Bucket - PolicyDocument: - Version: '2012-10-17' - Statement: - - Action: ['s3:GetObject'] - Effect: Allow - Principal: - Service: 'serverlessrepo.amazonaws.com' - Resource: !Sub ${StagingS3Bucket.Arn}/* - Condition: - StringEquals: - aws:SourceAccount: !Ref AWS::AccountId - - ReleaseS3Bucket: - Type: AWS::S3::Bucket - DeletionPolicy: Retain - UpdateReplacePolicy: Delete - - ReleaseS3BucketPolicy: - Type: AWS::S3::BucketPolicy - Properties: - Bucket: !Ref ReleaseS3Bucket - PolicyDocument: - Version: '2012-10-17' - Statement: - - Action: ['s3:GetObject'] - Effect: Allow - Principal: - Service: 'serverlessrepo.amazonaws.com' - Resource: - - !Sub ${ReleaseS3Bucket.Arn}/* - Condition: - StringEquals: - aws:SourceAccount: !Ref AWS::AccountId - - CodePipeline: - Type: AWS::CodePipeline::Pipeline - Properties: - Name: !Ref ApplicationName - RoleArn: !Sub ${CodePipelineRole.Arn} - ArtifactStore: - Type: S3 - Location: !Ref CodePipelineArtifactS3Bucket - Stages: - - Name: Source - Actions: - - Name: GitHub - ActionTypeId: - Category: Source - Owner: AWS - Version: 1 - Provider: CodeStarSourceConnection - OutputArtifacts: - - Name: 1-Source - Configuration: - ConnectionArn: arn:aws:codestar-connections:us-east-2:004480582608:connection/0a1c90d5-1395-4a3b-8734-2b53cda9fad2 - FullRepositoryId: awslabs/ssosync - BranchName: CodePipeline - DetectChanges: true - - Name: Build - Actions: - - Name: BuildGo - InputArtifacts: - - Name: 1-Source - ActionTypeId: - Category: Build - Owner: AWS - Version: 1 - Provider: CodeBuild - OutputArtifacts: - - Name: 2-Build - Configuration: - ProjectName: !Ref CodeBuildGo - - Name: PackageStaging - Actions: - - Name: PackageStaging - InputArtifacts: - - Name: 2-Build - ActionTypeId: - Category: Build - Owner: AWS - Version: 1 - Provider: CodeBuild - OutputArtifacts: - - Name: 3-Staging - Configuration: - ProjectName: !Ref CodeBuildStaging - - Name: PublishStaging - Actions: - - Name: PublishStagingToSAR - InputArtifacts: - - Name: 3-Staging - ActionTypeId: - Category: Invoke - Owner: AWS - Version: 1 - Provider: Lambda - Configuration: - FunctionName: !GetAtt SARPublishApp.Outputs.ServerlessRepoPublishFunctionName - - Name: Approvals - Actions: - - Name: ProductionGate - ActionTypeId: - Category: Approval - Owner: AWS - Version: 1 - Provider: Manual - - Name: PackageRelease - Actions: - - Name: PackageRelease - InputArtifacts: - - Name: 2-Build - ActionTypeId: - Category: Build - Owner: AWS - Version: 1 - Provider: CodeBuild - OutputArtifacts: - - Name: 4-Release - Configuration: - ProjectName: !Ref CodeBuildRelease - - Name: PublishRelease - Actions: - - Name: PublishReleaseToSAR - InputArtifacts: - - Name: 4-Release - ActionTypeId: - Category: Invoke - Owner: AWS - Version: 1 - Provider: Lambda - Configuration: - FunctionName: !GetAtt SARPublishApp.Outputs.ServerlessRepoPublishFunctionName - - CodeBuildGo: - Type: AWS::CodeBuild::Project - Properties: - Name: !Sub "${ApplicationName}-Build-go" - Description: !Sub Build project for ${ApplicationName} - ServiceRole: !Ref CodeBuildGoRole - Source: - Type: CODEPIPELINE - BuildSpec: "cicd/build/buildgo.yml" - Environment: - ComputeType: BUILD_GENERAL1_SMALL - Image: aws/codebuild/standard:5.0 - Type: LINUX_CONTAINER - EnvironmentVariables: - - Name: ARTIFACT_S3_BUCKET - Value: !Sub ${CodePipelineArtifactS3Bucket} - - Name: GO_VERSION - Value: "1.18.1" - - Name: OUTPUT - Value: main - - Name: APP_NAME - Value: ssosync - Artifacts: - Name: !Ref ApplicationName - Type: CODEPIPELINE - - CodeBuildStaging: - Type: AWS::CodeBuild::Project - Properties: - Name: !Sub "${ApplicationName}-Package-Staging" - Description: !Sub SAM package for ${ApplicationName} - ServiceRole: !Ref CodeBuildStagingRole - Source: - Type: CODEPIPELINE - BuildSpec: "cicd/package/staging.yml" - Environment: - ComputeType: BUILD_GENERAL1_SMALL - Image: aws/codebuild/standard:5.0 - Type: LINUX_CONTAINER - EnvironmentVariables: - - Name: ARTIFACT_S3_BUCKET - Value: !Sub ${CodePipelineArtifactS3Bucket} - - Name: S3Bucket - Value: !Ref StagingS3Bucket - - Name: Template - Value: template.yaml - - Name: Packaged - Value: packaged.yaml - Artifacts: - Name: !Ref ApplicationName - Type: CODEPIPELINE - - CodeBuildRelease: - Type: AWS::CodeBuild::Project - Properties: - Name: !Sub "${ApplicationName}-Package-Release" - Description: !Sub SAM package for ${ApplicationName} - ServiceRole: !Ref CodeBuildReleaseRole - Source: - Type: CODEPIPELINE - BuildSpec: "cicd/package/release.yml" - Environment: - ComputeType: BUILD_GENERAL1_SMALL - Image: aws/codebuild/standard:5.0 - Type: LINUX_CONTAINER - EnvironmentVariables: - - Name: ARTIFACT_S3_BUCKET - Value: !Sub ${CodePipelineArtifactS3Bucket} - - Name: S3Bucket - Value: !Ref ReleaseS3Bucket - - Name: Template - Value: template.yaml - - Name: Packaged - Value: packaged.yaml - - Name: APP_NAME - Value: !Sub "${ApplicationName}" - Artifacts: - Name: !Ref ApplicationName - Type: CODEPIPELINE - - CodePipelineRole: - Type: AWS::IAM::Role - Properties: - RoleName: !Sub ${ApplicationName}-CodePipeline-${AWS::Region} - AssumeRolePolicyDocument: - Statement: - - Action: ['sts:AssumeRole'] - Effect: Allow - Principal: - Service: [codepipeline.amazonaws.com] - Version: '2012-10-17' - Path: / - Policies: - - PolicyName: !Sub ${ApplicationName}-CodePipeline-${AWS::Region} - PolicyDocument: - Version: '2012-10-17' - Statement: - - Action: - - 'iam:PassRole' - Effect: Allow - Resource: '*' - - Action: - - 'codestar-connections:UseConnection' - - 'codestar-connections:GetConnection' - - 'codestar-connections:ListConnections' - - 'codestar-connections:ListTagsForResource' - Resource: !Sub arn:aws:codestar-connections:${AWS::Region}:${AWS::AccountId}:connection/* - Effect: Allow - - Action: - - 'codebuild:BatchGetBuilds' - - 'codebuild:StartBuild' - Resource: - - !Sub ${CodeBuildGo.Arn} - - !Sub ${CodeBuildStaging.Arn} - - !Sub ${CodeBuildRelease.Arn} - Effect: Allow - - Action: - - 's3:GetBucketVersioning' - - 's3:ListBucket' - Resource: - - !Sub ${CodePipelineArtifactS3Bucket.Arn} - - !Sub ${StagingS3Bucket.Arn} - - !Sub ${ReleaseS3Bucket.Arn} - Effect: Allow - - Action: - - 's3:PutObject' - - 's3:GetObject' - - 's3:GetObjectVersion' - Resource: - - !Sub ${CodePipelineArtifactS3Bucket.Arn}/* - - !Sub ${StagingS3Bucket.Arn}/* - - !Sub ${ReleaseS3Bucket.Arn}/* - Effect: Allow - - Action: - - 'codedeploy:CreateDeployment' - - 'codedeploy:GetApplicationRevision' - - 'codedeploy:GetDeployment' - - 'codedeploy:GetDeploymentConfig' - - 'codedeploy:RegisterApplicationRevision' - Resource: '*' - Effect: Allow - - Action: 'lambda:InvokeFunction' - Resource: !GetAtt SARPublishApp.Outputs.ServerlessRepoPublishFunctionArn - Effect: Allow - - Action: - - 'cloudformation:CreateStack' - - 'cloudformation:DeleteStack' - - 'cloudformation:DescribeStacks' - - 'cloudformation:UpdateStack' - - 'cloudformation:CreateChangeSet' - - 'cloudformation:DeleteChangeSet' - - 'cloudformation:DescribeChangeSet' - - 'cloudformation:ExecuteChangeSet' - - 'cloudformation:SetStackPolicy' - - 'cloudformation:ValidateTemplate' - Resource: '*' - Effect: Allow - - CodePipelineCloudFormationRole: - Type: AWS::IAM::Role - Properties: - Path: / - RoleName: !Sub ${ApplicationName}-CloudFormation-${AWS::Region} - AssumeRolePolicyDocument: | - { - "Statement": [{ - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "cloudformation.amazonaws.com" - } - }] - } - Policies: - - PolicyName: !Sub ${ApplicationName}-CloudFormation-${AWS::Region} - PolicyDocument: | - { - "Statement": [{ - "Effect": "Allow", - "Action": [ "*" ], - "Resource": "*" - }] - } - - CodeDeployApplication: - Type: AWS::CodeDeploy::Application - Properties: - ApplicationName: !Sub ${ApplicationName} - - CodeDeployServiceRole: - Type: AWS::IAM::Role - Properties: - Path: / - RoleName: !Sub ${ApplicationName}-CodeDeploy-${AWS::Region} - AssumeRolePolicyDocument: | - { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "codedeploy.amazonaws.com" - } - } - ] - } - Policies: - - PolicyName: !Sub ${AWS::StackName}-${AWS::Region} - PolicyDocument: !Sub | - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "autoscaling:CompleteLifecycleAction", - "autoscaling:DeleteLifecycleHook", - "autoscaling:DescribeAutoScalingGroups", - "autoscaling:DescribeLifecycleHooks", - "autoscaling:PutLifecycleHook", - "autoscaling:RecordLifecycleActionHeartbeat", - "ec2:DescribeInstances", - "ec2:DescribeInstanceStatus", - "tag:GetTags", - "tag:GetResources", - "sns:Publish", - "cloudwatch:DescribeAlarms" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": "secretsmanager:GetSecretValue", - "Resource": "*" - } - ] - } - - CodeBuildGoRole: - Type: AWS::IAM::Role - Properties: - Path: / - RoleName: !Sub ${ApplicationName}-CodeBuild-Go-${AWS::Region} - AssumeRolePolicyDocument: | - { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "codebuild.amazonaws.com" - } - } - ] - } - Policies: - - PolicyName: !Sub ${ApplicationName}-CodeBuild-Go-${AWS::Region} - PolicyDocument: !Sub | - { - "Statement": [ - { - "Effect": "Allow", - "Resource": "*", - "Action": [ - "logs:CreateLogGroup", - "logs:CreateLogStream", - "logs:PutLogEvents" - ] - }, - { - "Effect": "Allow", - "Resource": "${CodePipelineArtifactS3Bucket.Arn}/*", - "Action": "s3:*" - } - ] - } - - CodeBuildStagingRole: - Type: AWS::IAM::Role - Properties: - RoleName: !Sub ${ApplicationName}-CodePipeline-${AWS::Region} - AssumeRolePolicyDocument: - Statement: - - Action: ['sts:AssumeRole'] - Effect: Allow - Principal: - Service: [codepipeline.amazonaws.com] - Version: '2012-10-17' - Path: / - Policies: - - PolicyName: !Sub ${ApplicationName}-CodeBuild-Staging-${AWS::Region} - PolicyDocument: - Version: '2012-10-17' - Statement: - - Action: - - 'logs:CreateLogGroup' - - 'logs:CreateLogStream' - - 'logs:PutLogEvents' - Effect: Allow - Resource: '*' - - Action: 's3:*' - Effect: Allow - Resource: - - !Sub ${CodePipelineArtifactS3Bucket.Arn}/* - - !Sub ${StagingS3Bucket.Arn}/* - - Action: 'serverlessrepo:*' - Effect: Allow - Resource: !Sub arn:aws:serverlessrepo:us-east-2:004480582608:applications/* - - CodeBuildReleaseRole: - Type: AWS::IAM::Role - Properties: - Path: / - RoleName: !Sub ${ApplicationName}-CodeBuild-Release-${AWS::Region} - AssumeRolePolicyDocument: | - { - "Statement": [{ - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "codebuild.amazonaws.com" - } - }] - } - Policies: - - PolicyName: !Sub ${ApplicationName}-CodeBuild-Release-${AWS::Region} - PolicyDocument: !Sub | - { - "Statement": [ - { - "Effect": "Allow", - "Resource": [ "*" ], - "Action": [ - "logs:CreateLogGroup", - "logs:CreateLogStream", - "logs:PutLogEvents" - ] - }, - { - "Effect": "Allow", - "Resource": [ - "arn:aws:s3:::${CodePipelineArtifactS3Bucket}/*", - "arn:aws:s3:::${ReleaseS3Bucket}/*" - ], - "Action": "s3:*" - } - ] - } - -Outputs: - - CodePipelineURL: - Description: The URL for the created pipeline - Value: !Sub https://${AWS::Region}.console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${ApplicationName} - - CodeDeployApplication: - Description: The CodeDeploy application used across all environments - Value: !Ref CodeDeployApplication - Export: - Name: !Sub CodeDeployApplication-${ApplicationName} - - CodeDeployServiceRoleArn: - Description: The CodeDeploy service role used across all environments - Value: !GetAtt CodeDeployServiceRole.Arn - Export: - Name: !Sub CodeDeployServiceRoleArn-${ApplicationName} - - CodePipelineArtifactS3BucketARN: - Description: "S3 bucket ARN Codepipeline is using" - Value: !GetAtt CodePipelineArtifactS3Bucket.Arn - Export: - Name: CodePipelineArtifactS3BucketARN diff --git a/cicd/deploy/stack.yml b/cicd/deploy/stack.yml new file mode 100644 index 00000000..e30a30e4 --- /dev/null +++ b/cicd/deploy/stack.yml @@ -0,0 +1,37 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: 'AWS::Serverless-2016-10-31' + +Description: + This CloudFormation template will deploy an instance of the SSOSync-Staging + candidate releases (via privately shared app in the AWS Serverless Application + Repository (SAR) within the Staging Account. + +Parameters: + ApplicationArn: + Description: The candidate release in the SAR + Default: 'arn:aws:serverlessrepo:::applications/' + Type: String + +Resources: + SARApp: + Type: AWS::Serverless::Application + Properties: + Location: + ApplicationId: 'arn:aws:serverlessrepo:us-east-2:004480582608:applications/SSOSync-Staging' + SemanticVersion: "1.0.0-staging" + Parameters: + GoogleAdminEmail: '{{resolve:secretsmanager:E2ETestGoogleAdminEmail}}' + GoogleCredentials: '{{resolve:secretsmanager:E2ETestGoogleCredentials}}' + SCIMEndpointUrl: '{{resolve:secretsmanager:E2ETestSCIMEndpointUrl}}' + SCIMEndpointAccessToken: '{{resolve:secretsmanager:E2ETestSCIMAccessToken}}' + SyncMethod: groups + GoogleUserMatch: 'name:*' + GoogleGroupMatch: 'name:AWS*' + LogLevel: warn + LogFormat: json + IgnoreUsers: None + IgnoreGroups: None + IncludeGroups: None + ScheduleExpression: 'rate(1 day)' + + diff --git a/cicd/package.yml b/cicd/package/buildspec.yml similarity index 71% rename from cicd/package.yml rename to cicd/package/buildspec.yml index ba6b970c..01e1a302 100644 --- a/cicd/package.yml +++ b/cicd/package/buildspec.yml @@ -13,16 +13,22 @@ phases: - rm -rf ./sam-installation aws-sam-cli-linux-x86_64.zip pre_build: + commands: + - cp -r ${CODEBUILD_SRC_DIR_Built}/* ./ + - ls -la + # Check that the files need to package exist - ls README.md - ls SAR.md - - cp -r ${CODEBUILD_SRC_DIR_Built}/dist ./ - ls dist/ssosync_linux_amd64_v1/ssosync + # Check that the executable works + - ./dist/ssosync_linux_amd64_v1/ssosync --version + build: commands: # Package our application with AWS SAM - - sam package --no-progressbar --template-file ${Template} --s3-bucket ${S3Bucket} --output-template-file packaged.yaml + - sam package --no-progressbar --template-file template.yaml --s3-bucket ${S3Bucket} --output-template-file packaged.yaml post_build: commands: diff --git a/cicd/publish/buildspec.yml b/cicd/publish/buildspec.yml new file mode 100644 index 00000000..79c0a31b --- /dev/null +++ b/cicd/publish/buildspec.yml @@ -0,0 +1,36 @@ +version: 0.2 + +phases: + install: + commands: + # Print all environment variables (handy for AWS CodeBuild logs) + - env + - ls -la + + # Update sam to latest version + - wget -q https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip + - unzip -q aws-sam-cli-linux-x86_64.zip -d sam-installation + - sudo ./sam-installation/install --update + - rm -rf ./sam-installation aws-sam-cli-linux-x86_64.zip + + pre_build: + commands: + # Copy in the package file + - cp ${CODEBUILD_SRC_DIR_Packaged}/packaged.yaml ./ + + # Check we have the required file + - ls packaged.yaml + + build: + commands: + # Replace App Name in template + - sed -i 's/ ssosync/ SSOSync-Staging/g' packaged.yaml --semantic-version "1.0.0-staging" + + # Remove the previous build + - aws serverlessrepo delete-application --application-id ${AppARN} + + # Package our application with AWS SAM + - sam publish --template packaged.yaml + + # Share with the StagingAccount + - aws serverlessrepo put-application-policy --application-id ${AppARN} --statements Principals=${ShareWith},Actions=Deploy diff --git a/cicd/publish.yml b/cicd/release/buildspec.yml similarity index 70% rename from cicd/publish.yml rename to cicd/release/buildspec.yml index f9bdcfe0..a10f0ced 100644 --- a/cicd/publish.yml +++ b/cicd/release/buildspec.yml @@ -21,19 +21,10 @@ phases: # Check we have the required file - ls packaged.yaml - # Replace App Name in template - - echo ${SDLC} - - | - if expr "${SDLC}" : "staging" >/dev/null; then - echo "SSOSync-Staging" - sed -i 's/ ssosync/ SSOSync-Staging/g' packaged.yaml - elif expr "${SDLC}" : "release" >/dev/null; then - echo "SSOSync" - sed -i 's/ ssosync/ SSOSync/g' packaged.yaml - fi - build: commands: + # Replace App Name in template + - sed -i 's/ ssosync/ SSOSync/g' packaged.yaml + # Package our application with AWS SAM - sam publish --template packaged.yaml - diff --git a/template.yaml b/template.yaml index 84ca8ea5..ec1cc095 100644 --- a/template.yaml +++ b/template.yaml @@ -173,3 +173,10 @@ Resources: Properties: Name: SSOSyncSCIMAccessToken SecretString: !Ref SCIMEndpointAccessToken + +Outputs: + FunctionArn: + Description: "The Arn of the deployed lambda function" + Value: !GetAtt SSOSyncFunction.Arn + Export: + Name: CSSOSyncFunctionARN