diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 0000000..9e50181 --- /dev/null +++ b/ci/README.md @@ -0,0 +1,14 @@ +## AWS CodeBuild Stack Setup + +create or update the stack +``` +aws cloudformation deploy --capabilities CAPABILITY_IAM --stack-name aws-lambda-cpp-ci --template-file codebuild.yml +``` + +(optional) trigger docker build and docker push of the build environment images. +A project to do this is pre-configured in the deployed stack. +``` +aws cloudformation describe-stacks --stack-name aws-lambda-cpp-ci --query "Stacks[].Outputs[].OutputValue" +# run command output from above, will look like: +# aws codebuild start-build --project-name +``` diff --git a/ci/codebuild.yml b/ci/codebuild.yml new file mode 100644 index 0000000..1205407 --- /dev/null +++ b/ci/codebuild.yml @@ -0,0 +1,412 @@ + +Parameters: + GitHub: + Type: String + Default: https://github.com/awslabs/aws-lambda-cpp.git + +Resources: + + ECR: + Type: AWS::ECR::Repository + + LambdaTestRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: can-log + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: + - !Join [':', [ arn:aws:logs, !Ref AWS::Region, !Ref AWS::AccountId, log-group:/aws/lambda/lambda-cpp-* ] ] + - !Join [':', [ arn:aws:logs, !Ref AWS::Region, !Ref AWS::AccountId, log-group:/aws/lambda/lambda-cpp-*:* ] ] + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + + LogsAccessRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: codebuild.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: readthelogs + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: + - !Join [':', [ arn:aws:logs, !Ref AWS::Region, !Ref AWS::AccountId, log-group:/aws/codebuild/aws-lambda-cpp-ci:* ] ] + Action: + - logs:GetLogEvents + + CodeBuildRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: codebuild.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: thepolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Resource: + - !Join [':', [ arn:aws:logs, !Ref AWS::Region, !Ref AWS::AccountId, log-group:/aws/codebuild/aws-lambda-cpp-ci ] ] + - !Join [':', [ arn:aws:logs, !Ref AWS::Region, !Ref AWS::AccountId, log-group:/aws/codebuild/aws-lambda-cpp-ci:* ] ] + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + - Effect: Allow + Resource: + - !Join [ '', [ arn:aws:s3:::codepipeline-, !Ref AWS::Region, -* ] ] + Action: + - s3:PutObject + - s3:GetObject + - s3:GetObjectVersion + - s3:GetBucketAcl + - s3:GetBucketLocation + - Effect: Allow + Resource: + - !Join [ ':', [ arn:aws:codebuild, !Ref AWS::Region, !Ref AWS::AccountId, report-group/test-* ] ] + Action: + - codebuild:CreateReportGroup + - codebuild:CreateReport + - codebuild:UpdateReport + - codebuild:BatchPutTestCases + - codebuild:BatchPutCodeCoverages + - Effect: Allow + Resource: + - '*' + Action: + - ecr:GetAuthorizationToken + - Effect: Allow + Resource: + - !GetAtt ECR.Arn + Action: + # pulling + - ecr:BatchCheckLayerAvailability + - ecr:GetDownloadUrlForLayer + - ecr:BatchGetImage + # pushing + - ecr:CompleteLayerUpload + - ecr:GetAuthorizationToken + - ecr:UploadLayerPart + - ecr:InitiateLayerUpload + - ecr:BatchCheckLayerAvailability + - ecr:PutImage + - Effect: Allow + Resource: + - !GetAtt LambdaTestRole.Arn + Action: + - iam:GetRole + - iam:PassRole + - Effect: Allow + Resource: + - !Join [':', [ arn:aws:lambda, !Ref AWS::Region, !Ref AWS::AccountId, function:lambda-cpp-* ] ] + Action: + - lambda:CreateFunction + - lambda:DeleteFunction + - lambda:InvokeFunction + + UpdateArmBuildEnvironments: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Environment: + ImagePullCredentialsType: CODEBUILD + ComputeType: BUILD_GENERAL1_SMALL + Image: aws/codebuild/amazonlinux2-aarch64-standard:2.0 + Type: ARM_CONTAINER + PrivilegedMode: True + EnvironmentVariables: + - Name: ECR_NAME + Type: PLAINTEXT + Value: !Ref ECR + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: | + version: 0.2 + phases: + build: + commands: + - ./ci/update-images.sh + + UpdateX86BuildEnvironments: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Environment: + ImagePullCredentialsType: CODEBUILD + ComputeType: BUILD_GENERAL1_MEDIUM + Image: aws/codebuild/amazonlinux2-x86_64-standard:4.0 + Type: LINUX_CONTAINER + PrivilegedMode: True + EnvironmentVariables: + - Name: ECR_NAME + Type: PLAINTEXT + Value: !Ref ECR + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: | + version: 0.2 + phases: + build: + commands: + - ./ci/update-images.sh + + + Amazon2Arm: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Triggers: + BuildType: BUILD + Webhook: True + FilterGroups: + - - Type: EVENT + Pattern: PUSH,PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED + Environment: + ImagePullCredentialsType: SERVICE_ROLE + ComputeType: BUILD_GENERAL1_SMALL + Type: ARM_CONTAINER + Image: !Join [ ':', [ !GetAtt ECR.RepositoryUri, amazon-linux-2-linux-arm64 ]] + EnvironmentVariables: + - Name: LAMBDA_TEST_ROLE + Type: PLAINTEXT + Value: !Ref LambdaTestRole + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: ci/codebuild/amazonlinux-2.yml + + Amazon2: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Triggers: + BuildType: BUILD + Webhook: True + FilterGroups: + - - Type: EVENT + Pattern: PUSH,PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED + Environment: + ImagePullCredentialsType: SERVICE_ROLE + ComputeType: BUILD_GENERAL1_SMALL + Type: LINUX_CONTAINER + Image: !Join [ ':', [ !GetAtt ECR.RepositoryUri, amazon-linux-2-linux-amd64 ]] + EnvironmentVariables: + - Name: LAMBDA_TEST_ROLE + Type: PLAINTEXT + Value: !Ref LambdaTestRole + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: ci/codebuild/amazonlinux-2.yml + + Amazon201803: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Triggers: + BuildType: BUILD + Webhook: True + FilterGroups: + - - Type: EVENT + Pattern: PUSH,PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED + Environment: + ImagePullCredentialsType: SERVICE_ROLE + ComputeType: BUILD_GENERAL1_SMALL + Type: LINUX_CONTAINER + Image: !Join [ ':', [ !GetAtt ECR.RepositoryUri, amazon-linux-2018.03-linux-amd64 ]] + EnvironmentVariables: + - Name: LAMBDA_TEST_ROLE + Type: PLAINTEXT + Value: !Ref LambdaTestRole + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: ci/codebuild/amazonlinux-2018.03.yml + + Ubuntu1804: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Triggers: + BuildType: BUILD + Webhook: True + FilterGroups: + - - Type: EVENT + Pattern: PUSH,PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED + Environment: + ImagePullCredentialsType: SERVICE_ROLE + ComputeType: BUILD_GENERAL1_SMALL + Type: LINUX_CONTAINER + Image: !Join [ ':', [ !GetAtt ECR.RepositoryUri, ubuntu-linux-18.04-linux-amd64 ]] + EnvironmentVariables: + - Name: LAMBDA_TEST_ROLE + Type: PLAINTEXT + Value: !Ref LambdaTestRole + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: ci/codebuild/ubuntu-18.04.yml + + Alpine315: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Triggers: + BuildType: BUILD + Webhook: True + FilterGroups: + - - Type: EVENT + Pattern: PUSH,PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED + Environment: + ImagePullCredentialsType: SERVICE_ROLE + ComputeType: BUILD_GENERAL1_SMALL + Type: LINUX_CONTAINER + Image: !Join [ ':', [ !GetAtt ECR.RepositoryUri, alpine-linux-3.15-linux-amd64 ]] + EnvironmentVariables: + - Name: LAMBDA_TEST_ROLE + Type: PLAINTEXT + Value: !Ref LambdaTestRole + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: ci/codebuild/alpine-3.15.yml + + Arch: + Type: AWS::CodeBuild::Project + Properties: + Artifacts: + Type: NO_ARTIFACTS + BadgeEnabled: True + Visibility: PUBLIC_READ + ConcurrentBuildLimit: 1 + ServiceRole: !GetAtt CodeBuildRole.Arn + ResourceAccessRole: !GetAtt LogsAccessRole.Arn + LogsConfig: + CloudWatchLogs: + Status: ENABLED + GroupName: /aws/codebuild/aws-lambda-cpp-ci + Triggers: + BuildType: BUILD + Webhook: True + FilterGroups: + - - Type: EVENT + Pattern: PUSH,PULL_REQUEST_CREATED,PULL_REQUEST_UPDATED + Environment: + ImagePullCredentialsType: SERVICE_ROLE + ComputeType: BUILD_GENERAL1_SMALL + Type: LINUX_CONTAINER + Image: !Join [ ':', [ !GetAtt ECR.RepositoryUri, arch-linux-linux-amd64 ]] + EnvironmentVariables: + - Name: LAMBDA_TEST_ROLE + Type: PLAINTEXT + Value: !Ref LambdaTestRole + Source: + Type: GITHUB + Location: !Ref GitHub + BuildSpec: ci/codebuild/arch-linux.yml + +Outputs: + BootstrapArmImages: + Description: to bootstrap or update the arm images, run the command! + Value: !Join [' ', [ aws codebuild start-build --project-name, !Ref UpdateArmBuildEnvironments ] ] + BootstrapX86Images: + Description: to bootstrap or update the arm images, run the command! + Value: !Join [' ', [ aws codebuild start-build --project-name, !Ref UpdateX86BuildEnvironments ] ] diff --git a/ci/update-images.sh b/ci/update-images.sh new file mode 100755 index 0000000..b711ebb --- /dev/null +++ b/ci/update-images.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -euo pipefail + +PRJ_ROOT=$(git rev-parse --show-toplevel) +ECR_NAME=${ECR_NAME:-aws-lambda-cpp-ci} +REGION=${AWS_DEFAULT_REGION:-us-west-2} +ACCOUNT_ID=$(aws sts get-caller-identity --output text --query "Account") + +aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com + +# on Linux, if buildx is giving trouble - run: +# docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + +build-and-push () { + TAG=$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$ECR_NAME:$1-$(echo $2 | sed 's|/|-|g') + docker build --platform $2 -t $TAG -f "$PRJ_ROOT/ci/docker/$1" . + docker push $TAG +} + +if [[ $(arch) == "aarch64" ]]; then + build-and-push amazon-linux-2 linux/arm64 +else + build-and-push ubuntu-linux-18.04 linux/amd64 + build-and-push alpine-linux-3.15 linux/amd64 + build-and-push amazon-linux-2017.03 linux/amd64 + build-and-push amazon-linux-2 linux/amd64 + build-and-push arch-linux linux/amd64 +fi diff --git a/tests/runtime_tests.cpp b/tests/runtime_tests.cpp index a65a267..f118dab 100644 --- a/tests/runtime_tests.cpp +++ b/tests/runtime_tests.cpp @@ -89,7 +89,11 @@ struct LambdaRuntimeTest : public ::testing::Test { create_function_request.SetHandler(handler_name); create_function_request.SetFunctionName(function_name); // I ran into eventual-consistency issues when creating the role dynamically as part of the test. - create_function_request.SetRole(get_role_arn("integration-tests")); + auto exec_role = Aws::Environment::GetEnv("LAMBDA_TEST_ROLE"); + if (exec_role.empty()) { + exec_role = "integration-tests"; + } + create_function_request.SetRole(get_role_arn(exec_role)); struct stat s; auto rc = stat(ZIP_FILE_PATH, &s);