{ "Parameters": { "EEAssetsBucket": { "Type": "String", "Default": "BucketNameNotSet" }, "EEAssetsKeyPrefix": { "Type": "String", "Default": "KeyPrefixNotSet" }, "EETeamRoleArn": { "Type": "String", "Default": "RoleArnNotSet" }, "SourceZipFile": { "Type": "String", "Default": "workshop-stack-app.zip" }, "SourceZipFileChecksum": { "Type": "String", "Default": "" } }, "Resources": { "VPCB9E5F0B4": { "Type": "AWS::EC2::VPC", "Properties": { "CidrBlock": "10.0.0.0/16", "EnableDnsHostnames": true, "EnableDnsSupport": true, "InstanceTenancy": "default", "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/Resource" } }, "VPCPublicSubnet1SubnetB4246D30": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.0.0/18", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": { "Fn::Select": [ 0, { "Fn::GetAZs": "" } ] }, "MapPublicIpOnLaunch": true, "Tags": [ { "Key": "aws-cdk:subnet-name", "Value": "Public" }, { "Key": "aws-cdk:subnet-type", "Value": "Public" }, { "Key": "Name", "Value": "FoundationStack/VPC/PublicSubnet1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet1/Subnet" } }, "VPCPublicSubnet1RouteTableFEE4B781": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCB9E5F0B4" }, "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC/PublicSubnet1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet1/RouteTable" } }, "VPCPublicSubnet1RouteTableAssociation0B0896DC": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" }, "SubnetId": { "Ref": "VPCPublicSubnet1SubnetB4246D30" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet1/RouteTableAssociation" } }, "VPCPublicSubnet1DefaultRoute91CEF279": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet1RouteTableFEE4B781" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "VPCIGWB7E252D3" } }, "DependsOn": ["VPCVPCGW99B986DC"], "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet1/DefaultRoute" } }, "VPCPublicSubnet1EIP6AD938E8": { "Type": "AWS::EC2::EIP", "Properties": { "Domain": "vpc", "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC/PublicSubnet1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet1/EIP" } }, "VPCPublicSubnet1NATGatewayE0556630": { "Type": "AWS::EC2::NatGateway", "Properties": { "SubnetId": { "Ref": "VPCPublicSubnet1SubnetB4246D30" }, "AllocationId": { "Fn::GetAtt": ["VPCPublicSubnet1EIP6AD938E8", "AllocationId"] }, "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC/PublicSubnet1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet1/NATGateway" } }, "VPCPublicSubnet2Subnet74179F39": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.64.0/18", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": { "Fn::Select": [ 1, { "Fn::GetAZs": "" } ] }, "MapPublicIpOnLaunch": true, "Tags": [ { "Key": "aws-cdk:subnet-name", "Value": "Public" }, { "Key": "aws-cdk:subnet-type", "Value": "Public" }, { "Key": "Name", "Value": "FoundationStack/VPC/PublicSubnet2" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet2/Subnet" } }, "VPCPublicSubnet2RouteTable6F1A15F1": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCB9E5F0B4" }, "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC/PublicSubnet2" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet2/RouteTable" } }, "VPCPublicSubnet2RouteTableAssociation5A808732": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" }, "SubnetId": { "Ref": "VPCPublicSubnet2Subnet74179F39" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet2/RouteTableAssociation" } }, "VPCPublicSubnet2DefaultRouteB7481BBA": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" }, "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": { "Ref": "VPCIGWB7E252D3" } }, "DependsOn": ["VPCVPCGW99B986DC"], "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PublicSubnet2/DefaultRoute" } }, "VPCPrivateSubnet1Subnet8BCA10E0": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.128.0/18", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": { "Fn::Select": [ 0, { "Fn::GetAZs": "" } ] }, "MapPublicIpOnLaunch": false, "Tags": [ { "Key": "aws-cdk:subnet-name", "Value": "Private" }, { "Key": "aws-cdk:subnet-type", "Value": "Private" }, { "Key": "Name", "Value": "FoundationStack/VPC/PrivateSubnet1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet1/Subnet" } }, "VPCPrivateSubnet1RouteTableBE8A6027": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCB9E5F0B4" }, "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC/PrivateSubnet1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet1/RouteTable" } }, "VPCPrivateSubnet1RouteTableAssociation347902D1": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" }, "SubnetId": { "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet1/RouteTableAssociation" } }, "VPCPrivateSubnet1DefaultRouteAE1D6490": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "VPCPublicSubnet1NATGatewayE0556630" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet1/DefaultRoute" } }, "VPCPrivateSubnet2SubnetCFCDAA7A": { "Type": "AWS::EC2::Subnet", "Properties": { "CidrBlock": "10.0.192.0/18", "VpcId": { "Ref": "VPCB9E5F0B4" }, "AvailabilityZone": { "Fn::Select": [ 1, { "Fn::GetAZs": "" } ] }, "MapPublicIpOnLaunch": false, "Tags": [ { "Key": "aws-cdk:subnet-name", "Value": "Private" }, { "Key": "aws-cdk:subnet-type", "Value": "Private" }, { "Key": "Name", "Value": "FoundationStack/VPC/PrivateSubnet2" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet2/Subnet" } }, "VPCPrivateSubnet2RouteTable0A19E10E": { "Type": "AWS::EC2::RouteTable", "Properties": { "VpcId": { "Ref": "VPCB9E5F0B4" }, "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC/PrivateSubnet2" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet2/RouteTable" } }, "VPCPrivateSubnet2RouteTableAssociation0C73D413": { "Type": "AWS::EC2::SubnetRouteTableAssociation", "Properties": { "RouteTableId": { "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" }, "SubnetId": { "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet2/RouteTableAssociation" } }, "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { "Type": "AWS::EC2::Route", "Properties": { "RouteTableId": { "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" }, "DestinationCidrBlock": "0.0.0.0/0", "NatGatewayId": { "Ref": "VPCPublicSubnet1NATGatewayE0556630" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/PrivateSubnet2/DefaultRoute" } }, "VPCIGWB7E252D3": { "Type": "AWS::EC2::InternetGateway", "Properties": { "Tags": [ { "Key": "Name", "Value": "FoundationStack/VPC" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/IGW" } }, "VPCVPCGW99B986DC": { "Type": "AWS::EC2::VPCGatewayAttachment", "Properties": { "VpcId": { "Ref": "VPCB9E5F0B4" }, "InternetGatewayId": { "Ref": "VPCIGWB7E252D3" } }, "Metadata": { "aws:cdk:path": "FoundationStack/VPC/VPCGW" } }, "Workspace2F8C78CC": { "Type": "AWS::Cloud9::EnvironmentEC2", "Properties": { "InstanceType": "t3.medium", "Description": "AWS Event Workshop", "Name": "aws-workshop", "SubnetId": { "Ref": "VPCPublicSubnet1SubnetB4246D30" } }, "Metadata": { "aws:cdk:path": "FoundationStack/Workspace/Resource" } }, "UpdateWorkspaceMembershipFunctionServiceRole9784B9F9": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" }, "ManagedPolicyArns": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] ] } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/UpdateWorkspaceMembershipFunction/ServiceRole/Resource" } }, "UpdateWorkspaceMembershipFunctionServiceRoleDefaultPolicy3615A70C": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "cloud9:createEnvironmentMembership", "Effect": "Allow", "Resource": "*" } ], "Version": "2012-10-17" }, "PolicyName": "UpdateWorkspaceMembershipFunctionServiceRoleDefaultPolicy3615A70C", "Roles": [ { "Ref": "UpdateWorkspaceMembershipFunctionServiceRole9784B9F9" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/UpdateWorkspaceMembershipFunction/ServiceRole/DefaultPolicy/Resource" } }, "UpdateWorkspaceMembershipFunctionFAB27C9D": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "ZipFile": "\nconst respond = async function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {\n return new Promise((resolve, reject) => {\n var responseBody = JSON.stringify({\n Status: responseStatus,\n Reason: \"See the details in CloudWatch Log Stream: \" + context.logGroupName + \" \" + context.logStreamName,\n PhysicalResourceId: physicalResourceId || context.logStreamName,\n StackId: event.StackId,\n RequestId: event.RequestId,\n LogicalResourceId: event.LogicalResourceId,\n NoEcho: noEcho || false,\n Data: responseData\n });\n\n console.log(\"Response body:\\n\", responseBody);\n\n var https = require(\"https\");\n var url = require(\"url\");\n\n var parsedUrl = url.parse(event.ResponseURL);\n var options = {\n hostname: parsedUrl.hostname,\n port: 443,\n path: parsedUrl.path,\n method: \"PUT\",\n headers: {\n \"content-type\": \"\",\n \"content-length\": responseBody.length\n }\n };\n\n var request = https.request(options, function(response) {\n console.log(\"Status code: \" + response.statusCode);\n console.log(\"Status message: \" + response.statusMessage);\n resolve();\n });\n\n request.on(\"error\", function(error) {\n console.log(\"respond(..) failed executing https.request(..): \" + error);\n resolve();\n });\n\n request.write(responseBody);\n request.end();\n });\n};\n\nexports.handler = async function (event, context) {\n console.log(JSON.stringify(event, null, 4));\n const AWS = require('aws-sdk');\n\n try {\n const environmentId = event.ResourceProperties.EnvironmentId;\n\n if (event.RequestType === \"Create\" || event.RequestType === \"Update\") {\n const eeTeamRoleArn = event.ResourceProperties.EETeamRoleArn;\n\n if (!!eeTeamRoleArn && eeTeamRoleArn !== 'RoleArnNotSet') {\n const arnSplit = eeTeamRoleArn.split(':');\n const accountNumber = arnSplit[4];\n const resourceName = arnSplit[5].split('/')[1];\n const eeTeamAssumedRoleArn = `arn:aws:sts::${accountNumber}:assumed-role/${resourceName}/MasterKey`;\n\n console.log('Resolved EE Team Assumed Role ARN: ' + eeTeamAssumedRoleArn);\n\n const cloud9 = new AWS.Cloud9();\n\n const { membership } = await cloud9.createEnvironmentMembership({\n environmentId,\n permissions: 'read-write',\n userArn: eeTeamAssumedRoleArn,\n }).promise();\n console.log(JSON.stringify(membership, null, 4));\n }\n }\n console.log('Sending SUCCESS response');\n await respond(event, context, 'SUCCESS', {}, environmentId);\n } catch (error) {\n console.error(error);\n await respond(event, context, 'FAILED', { Error: error });\n }\n};\n " }, "Role": { "Fn::GetAtt": [ "UpdateWorkspaceMembershipFunctionServiceRole9784B9F9", "Arn" ] }, "Handler": "update_instance_profile.lambda_handler", "Runtime": "python3.9", "Timeout": 60 }, "DependsOn": [ "UpdateWorkspaceMembershipFunctionServiceRoleDefaultPolicy3615A70C", "UpdateWorkspaceMembershipFunctionServiceRole9784B9F9" ], "Metadata": { "aws:cdk:path": "FoundationStack/UpdateWorkspaceMembershipFunction/Resource" } }, "UpdateWorkspaceMembership": { "Type": "AWS::CloudFormation::CustomResource", "Properties": { "ServiceToken": { "Fn::GetAtt": ["UpdateWorkspaceMembershipFunctionFAB27C9D", "Arn"] }, "EnvironmentId": { "Ref": "Workspace2F8C78CC" }, "EETeamRoleArn": { "Ref": "EETeamRoleArn" } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete", "Metadata": { "aws:cdk:path": "FoundationStack/UpdateWorkspaceMembership/Default" } }, "BuildProjectRole0E170066": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "codebuild.amazonaws.com" } } ], "Version": "2012-10-17" } }, "Metadata": { "aws:cdk:path": "FoundationStack/BuildProjectRole/Resource" } }, "BuildProjectRoleDefaultPolicyE4352B8B": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": ["s3:GetObject*", "s3:GetBucket*", "s3:List*"], "Effect": "Allow", "Resource": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":s3:::", { "Ref": "EEAssetsBucket" } ] ] }, { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":s3:::", { "Ref": "EEAssetsBucket" }, "/", { "Ref": "EEAssetsKeyPrefix" }, "/", { "Ref": "SourceZipFile" } ] ] } ] }, { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":logs:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":log-group:/aws/codebuild/", { "Ref": "BuildProject097C5DB7" } ] ] }, { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":logs:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":log-group:/aws/codebuild/", { "Ref": "BuildProject097C5DB7" }, ":*" ] ] } ] }, { "Action": [ "codebuild:CreateReportGroup", "codebuild:CreateReport", "codebuild:UpdateReport", "codebuild:BatchPutTestCases", "codebuild:BatchPutCodeCoverages" ], "Effect": "Allow", "Resource": { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":codebuild:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":report-group/", { "Ref": "BuildProject097C5DB7" }, "-*" ] ] } } ], "Version": "2012-10-17" }, "PolicyName": "BuildProjectRoleDefaultPolicyE4352B8B", "Roles": [ { "Ref": "BuildProjectRole0E170066" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/BuildProjectRole/DefaultPolicy/Resource" } }, "BuildProjectPolicyF8FA4BD5": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "*", "Effect": "Allow", "Resource": "*" } ], "Version": "2012-10-17" }, "PolicyName": "BuildProjectPolicyF8FA4BD5", "Roles": [ { "Ref": "BuildProjectRole0E170066" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/BuildProjectPolicy/Resource" } }, "BuildProject097C5DB7": { "Type": "AWS::CodeBuild::Project", "Properties": { "Artifacts": { "Type": "NO_ARTIFACTS" }, "Environment": { "ComputeType": "BUILD_GENERAL1_SMALL", "Image": "aws/codebuild/standard:5.0", "ImagePullCredentialsType": "CODEBUILD", "PrivilegedMode": false, "Type": "LINUX_CONTAINER" }, "ServiceRole": { "Fn::GetAtt": ["BuildProjectRole0E170066", "Arn"] }, "Source": { "Location": { "Fn::Join": [ "", [ { "Ref": "EEAssetsBucket" }, "/", { "Ref": "EEAssetsKeyPrefix" }, "/", { "Ref": "SourceZipFile" } ] ] }, "Type": "S3" }, "EncryptionKey": "alias/aws/s3", "TimeoutInMinutes": 90 }, "Metadata": { "aws:cdk:path": "FoundationStack/BuildProject/Resource" } }, "StartBuildFunctionServiceRole25C56391": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" }, "ManagedPolicyArns": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] ] } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/StartBuildFunction/ServiceRole/Resource" } }, "StartBuildFunctionServiceRoleDefaultPolicy53DA047E": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": "codebuild:StartBuild", "Effect": "Allow", "Resource": { "Fn::GetAtt": ["BuildProject097C5DB7", "Arn"] } } ], "Version": "2012-10-17" }, "PolicyName": "StartBuildFunctionServiceRoleDefaultPolicy53DA047E", "Roles": [ { "Ref": "StartBuildFunctionServiceRole25C56391" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/StartBuildFunction/ServiceRole/DefaultPolicy/Resource" } }, "StartBuildFunction21B23CDA": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "ZipFile": "\nconst respond = async function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {\n return new Promise((resolve, reject) => {\n var responseBody = JSON.stringify({\n Status: responseStatus,\n Reason: \"See the details in CloudWatch Log Stream: \" + context.logGroupName + \" \" + context.logStreamName,\n PhysicalResourceId: physicalResourceId || context.logStreamName,\n StackId: event.StackId,\n RequestId: event.RequestId,\n LogicalResourceId: event.LogicalResourceId,\n NoEcho: noEcho || false,\n Data: responseData\n });\n\n console.log(\"Response body:\\n\", responseBody);\n\n var https = require(\"https\");\n var url = require(\"url\");\n\n var parsedUrl = url.parse(event.ResponseURL);\n var options = {\n hostname: parsedUrl.hostname,\n port: 443,\n path: parsedUrl.path,\n method: \"PUT\",\n headers: {\n \"content-type\": \"\",\n \"content-length\": responseBody.length\n }\n };\n\n var request = https.request(options, function(response) {\n console.log(\"Status code: \" + response.statusCode);\n console.log(\"Status message: \" + response.statusMessage);\n resolve();\n });\n\n request.on(\"error\", function(error) {\n console.log(\"respond(..) failed executing https.request(..): \" + error);\n resolve();\n });\n\n request.write(responseBody);\n request.end();\n });\n};\n\nconst AWS = require('aws-sdk');\n\nexports.handler = async function (event, context) {\n console.log(JSON.stringify(event, null, 4));\n try {\n const projectName = event.ResourceProperties.ProjectName;\n const codebuild = new AWS.CodeBuild();\n\n console.log(`Starting new build of project ${projectName}`);\n\n const { build } = await codebuild.startBuild({\n projectName,\n // Pass CFN related parameters through the build for extraction by the\n // completion handler.\n buildspecOverride: event.RequestType === 'Delete' ? 'cdk/ide/buildspec-destroy.yml' : 'cdk/ide/buildspec.yml',\n environmentVariablesOverride: [\n {\n name: 'CFN_RESPONSE_URL',\n value: event.ResponseURL\n },\n {\n name: 'CFN_STACK_ID',\n value: event.StackId\n },\n {\n name: 'CFN_REQUEST_ID',\n value: event.RequestId\n },\n {\n name: 'CFN_LOGICAL_RESOURCE_ID',\n value: event.LogicalResourceId\n },\n {\n name: 'VPC_ID',\n value: event.ResourceProperties.VpcId\n },\n {\n name: 'CLOUD9_ENVIRONMENT_ID',\n value: event.ResourceProperties.Cloud9EnvironmentId\n },\n {\n name: 'BUILD_ROLE_ARN',\n value: event.ResourceProperties.BuildRoleArn\n }\n ]\n }).promise();\n console.log(`Build id ${build.id} started - resource completion handled by EventBridge`);\n } catch(error) {\n console.error(error);\n await respond(event, context, 'FAILED', { Error: error });\n }\n};\n " }, "Role": { "Fn::GetAtt": ["StartBuildFunctionServiceRole25C56391", "Arn"] }, "Handler": "index.handler", "Runtime": "nodejs14.x", "Timeout": 60 }, "DependsOn": [ "StartBuildFunctionServiceRoleDefaultPolicy53DA047E", "StartBuildFunctionServiceRole25C56391" ], "Metadata": { "aws:cdk:path": "FoundationStack/StartBuildFunction/Resource" } }, "ReportBuildFunctionServiceRole3573BFF1": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" } } ], "Version": "2012-10-17" }, "ManagedPolicyArns": [ { "Fn::Join": [ "", [ "arn:", { "Ref": "AWS::Partition" }, ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" ] ] } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/ReportBuildFunction/ServiceRole/Resource" } }, "ReportBuildFunctionServiceRoleDefaultPolicy4D7DF48B": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { "Statement": [ { "Action": [ "codebuild:BatchGetBuilds", "codebuild:ListBuildsForProject" ], "Effect": "Allow", "Resource": { "Fn::GetAtt": ["BuildProject097C5DB7", "Arn"] } } ], "Version": "2012-10-17" }, "PolicyName": "ReportBuildFunctionServiceRoleDefaultPolicy4D7DF48B", "Roles": [ { "Ref": "ReportBuildFunctionServiceRole3573BFF1" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/ReportBuildFunction/ServiceRole/DefaultPolicy/Resource" } }, "ReportBuildFunction724A99F2": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "ZipFile": "\nconst respond = async function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {\n return new Promise((resolve, reject) => {\n var responseBody = JSON.stringify({\n Status: responseStatus,\n Reason: \"See the details in CloudWatch Log Stream: \" + context.logGroupName + \" \" + context.logStreamName,\n PhysicalResourceId: physicalResourceId || context.logStreamName,\n StackId: event.StackId,\n RequestId: event.RequestId,\n LogicalResourceId: event.LogicalResourceId,\n NoEcho: noEcho || false,\n Data: responseData\n });\n\n console.log(\"Response body:\\n\", responseBody);\n\n var https = require(\"https\");\n var url = require(\"url\");\n\n var parsedUrl = url.parse(event.ResponseURL);\n var options = {\n hostname: parsedUrl.hostname,\n port: 443,\n path: parsedUrl.path,\n method: \"PUT\",\n headers: {\n \"content-type\": \"\",\n \"content-length\": responseBody.length\n }\n };\n\n var request = https.request(options, function(response) {\n console.log(\"Status code: \" + response.statusCode);\n console.log(\"Status message: \" + response.statusMessage);\n resolve();\n });\n\n request.on(\"error\", function(error) {\n console.log(\"respond(..) failed executing https.request(..): \" + error);\n resolve();\n });\n\n request.write(responseBody);\n request.end();\n });\n};\n\nconst AWS = require('aws-sdk');\n\nexports.handler = async function (event, context) {\n console.log(JSON.stringify(event, null, 4));\n\n const projectName = event['detail']['project-name'];\n\n const codebuild = new AWS.CodeBuild();\n\n const buildId = event['detail']['build-id'];\n const { builds } = await codebuild.batchGetBuilds({\n ids: [ buildId ]\n }).promise();\n\n console.log(JSON.stringify(builds, null, 4));\n\n const build = builds[0];\n // Fetch the CFN resource and response parameters from the build environment.\n const environment = {};\n build.environment.environmentVariables.forEach(e => environment[e.name] = e.value);\n\n const response = {\n ResponseURL: environment.CFN_RESPONSE_URL,\n StackId: environment.CFN_STACK_ID,\n LogicalResourceId: environment.CFN_LOGICAL_RESOURCE_ID,\n RequestId: environment.CFN_REQUEST_ID,\n // Must be constant, otherwise CloudFormation will attempt to delete the\n // resource after completing an update\n PhysicalResourceId: 'build'\n };\n\n if (event['detail']['build-status'] === 'SUCCEEDED') {\n await respond(response, context, 'SUCCESS', {});\n } else {\n await respond(response, context, 'FAILED', { Error: 'Build failed' });\n }\n};\n " }, "Role": { "Fn::GetAtt": ["ReportBuildFunctionServiceRole3573BFF1", "Arn"] }, "Handler": "index.handler", "Runtime": "nodejs14.x", "Timeout": 60 }, "DependsOn": [ "ReportBuildFunctionServiceRoleDefaultPolicy4D7DF48B", "ReportBuildFunctionServiceRole3573BFF1" ], "Metadata": { "aws:cdk:path": "FoundationStack/ReportBuildFunction/Resource" } }, "BuildCompleteRule660B1845": { "Type": "AWS::Events::Rule", "Properties": { "Description": "Build complete", "EventPattern": { "source": ["aws.codebuild"], "detail-type": ["CodeBuild Build State Change"], "detail": { "build-status": ["SUCCEEDED", "FAILED", "STOPPED"], "project-name": [ { "Ref": "BuildProject097C5DB7" } ] } }, "State": "ENABLED", "Targets": [ { "Arn": { "Fn::GetAtt": ["ReportBuildFunction724A99F2", "Arn"] }, "Id": "Target0" } ] }, "Metadata": { "aws:cdk:path": "FoundationStack/BuildCompleteRule/Resource" } }, "BuildCompleteRuleAllowEventRuleFoundationStackReportBuildFunction021C098BFF39C076": { "Type": "AWS::Lambda::Permission", "Properties": { "Action": "lambda:InvokeFunction", "FunctionName": { "Fn::GetAtt": ["ReportBuildFunction724A99F2", "Arn"] }, "Principal": "events.amazonaws.com", "SourceArn": { "Fn::GetAtt": ["BuildCompleteRule660B1845", "Arn"] } }, "Metadata": { "aws:cdk:path": "FoundationStack/BuildCompleteRule/AllowEventRuleFoundationStackReportBuildFunction021C098B" } }, "ClusterStack": { "Type": "AWS::CloudFormation::CustomResource", "Properties": { "ServiceToken": { "Fn::GetAtt": ["StartBuildFunction21B23CDA", "Arn"] }, "ProjectName": { "Ref": "BuildProject097C5DB7" }, "VpcId": { "Ref": "VPCB9E5F0B4" }, "Cloud9EnvironmentId": { "Ref": "Workspace2F8C78CC" }, "BuildRoleArn": { "Fn::GetAtt": ["BuildProjectRole0E170066", "Arn"] }, "ZipFileChecksum": { "Ref": "SourceZipFileChecksum" } }, "DependsOn": [ "BuildCompleteRuleAllowEventRuleFoundationStackReportBuildFunction021C098BFF39C076", "BuildCompleteRule660B1845", "BuildProjectPolicyF8FA4BD5", "VPCIGWB7E252D3", "VPCPrivateSubnet1DefaultRouteAE1D6490", "VPCPrivateSubnet1RouteTableBE8A6027", "VPCPrivateSubnet1RouteTableAssociation347902D1", "VPCPrivateSubnet1Subnet8BCA10E0", "VPCPrivateSubnet2DefaultRouteF4F5CFD2", "VPCPrivateSubnet2RouteTable0A19E10E", "VPCPrivateSubnet2RouteTableAssociation0C73D413", "VPCPrivateSubnet2SubnetCFCDAA7A", "VPCPublicSubnet1DefaultRoute91CEF279", "VPCPublicSubnet1EIP6AD938E8", "VPCPublicSubnet1NATGatewayE0556630", "VPCPublicSubnet1RouteTableFEE4B781", "VPCPublicSubnet1RouteTableAssociation0B0896DC", "VPCPublicSubnet1SubnetB4246D30", "VPCPublicSubnet2DefaultRouteB7481BBA", "VPCPublicSubnet2RouteTable6F1A15F1", "VPCPublicSubnet2RouteTableAssociation5A808732", "VPCPublicSubnet2Subnet74179F39", "VPCB9E5F0B4", "VPCVPCGW99B986DC" ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete", "Metadata": { "aws:cdk:path": "FoundationStack/ClusterStack/Default" } }, "CDKMetadata": { "Type": "AWS::CDK::Metadata", "Properties": { "Analytics": "v2:deflate64:H4sIAAAAAAAA/01Ry07DMBD8lt6dbRuKEDdoVFAvYKWoV7RxFtVtYld+pEJW/h3nUZLTzM6ud2fkFFawSoIRkD4t8GYTUV6SShYQDg7FhWU/iqPBmhwZFvvfwT7A1osLuS1aYiRSCMer6AaPPGPcF5UUB18ocp02sVx7R19YVDTpk/ZqrRYSndTqf7gjuz3v4APdOzq64S/jRjaRTov3KnqL/D4wOBmrVxdjnGpSrmWi0r58hm6raqTRqpN3WcoqrIsSIbx5Je4O5pyTqaW1sWqZxBpCrocUPXIdE/dnBxYP6ZIKL6sSAjf6TKL3OdKWURPv2rjFj1siti3LyWpvRC99enf18ZW3TtfzxpxnWpXS9a6wup4QNouX8QuXPfZ5k6G3E+ksdctU9Ahnu2zWG1g/wnpxtlImxisna4J8wD/4kPaUHgIAAA==" }, "Metadata": { "aws:cdk:path": "FoundationStack/CDKMetadata/Default" }, "Condition": "CDKMetadataAvailable" } }, "Outputs": { "URL": { "Value": { "Fn::Join": [ "", [ "https://", { "Ref": "AWS::Region" }, ".console.aws.amazon.com/cloud9/ide/", { "Ref": "Workspace2F8C78CC" } ] ] } } }, "Conditions": { "CDKMetadataAvailable": { "Fn::Or": [ { "Fn::Or": [ { "Fn::Equals": [ { "Ref": "AWS::Region" }, "af-south-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ap-east-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ap-northeast-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ap-northeast-2" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ap-south-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ap-southeast-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ap-southeast-2" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "ca-central-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "cn-north-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "cn-northwest-1" ] } ] }, { "Fn::Or": [ { "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-central-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-north-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-south-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-west-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-west-2" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "eu-west-3" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "me-south-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "sa-east-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "us-east-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "us-east-2" ] } ] }, { "Fn::Or": [ { "Fn::Equals": [ { "Ref": "AWS::Region" }, "us-west-1" ] }, { "Fn::Equals": [ { "Ref": "AWS::Region" }, "us-west-2" ] } ] } ] } } }