Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CodeBuild PipelineProject LinuxBuildImage.STANDARD_6_0 somehow got mixed up with aws-cdk-lib.aws_codebuild.LinuxBuildImage.AMAZON_LINUX_2_ARM #29528

Open
icelava opened this issue Mar 18, 2024 · 9 comments
Labels
@aws-cdk/aws-codebuild Related to AWS CodeBuild bug This issue is a bug. effort/medium Medium work item – several days of effort language/dotnet Related to .NET bindings p3

Comments

@icelava
Copy link

icelava commented Mar 18, 2024

Describe the bug

We have a .NET CDK project that handles deployment of CodePipleline/CodeBuild and has been working based on Amazon.CDK.Lib 2.94.0.

For our React application pipelines, the CodeBuild setup is like

this.Build = new PipelineProject(this, codeBuildName, new PipelineProjectProps
{
    Environment = new BuildEnvironment
    {
        BuildImage = LinuxBuildImage.STANDARD_6_0,
        ComputeType = ComputeType.MEDIUM
    },
    Description = $"{_props.ProductName} React CI CD {_props.Environment}",
    ProjectName = codeBuildName,
    Timeout = Duration.Minutes(10),
    EnvironmentVariables = envVars,
    Badge = false,
    Cache = Cache.Local(LocalCacheMode.CUSTOM),
    Role = this._props.CodebuildRole
});

Upon updating to CDK 2.130.0, attempting cdk list would result in strange error.

PS C:\projects\dev-tools-cdk> cdk list
Warning NETSDK1174: The abbreviation of -p for --project is deprecated. Please use --project.

Unhandled exception. System.TypeInitializationException: The type initializer for 'Amazon.CDK.AWS.CodeBuild.LinuxBuildImage' threw an exception.
---> System.Exception: Of static property aws-cdk-lib.aws_codebuild.LinuxBuildImage.AMAZON_LINUX_2_ARM: Unable to serialize value as aws-cdk-lib.aws_codebuild.IBuildImage
├── ?? Failing value is undefined
?── ?? Failure reason(s):
?─ A value is required (type is non-optional)
at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
at Amazon.JSII.Runtime.Services.Client.ReceiveResponseTResponse
at Amazon.JSII.Runtime.Services.Client.Send[TRequest,TResponse](TRequest requestObject)
at Amazon.JSII.Runtime.Services.Client.StaticGet(StaticGetRequest request)
at Amazon.JSII.Runtime.Services.Client.StaticGet(String fullyQualifiedName, String property)
at Amazon.JSII.Runtime.Deputy.DeputyBase.<>c__DisplayClass8_01.<GetStaticProperty>b__0(IClient client) at Amazon.JSII.Runtime.Deputy.DeputyBase.GetPropertyCore[T](JsiiPropertyAttribute propertyAttribute, Func2 getFunc)
at Amazon.JSII.Runtime.Deputy.DeputyBase.GetStaticProperty[T](Type type, String propertyName)
at Amazon.CDK.AWS.CodeBuild.LinuxBuildImage..cctor()
--- End of inner exception stack trace ---
at Amazon.CDK.AWS.CodeBuild.LinuxBuildImage.get_STANDARD_6_0()
at DevToolsCdk.Constructs.ReactPipeline.Initialize() in C:\projects\dev-tools-cdk\src\DevToolsCdk\Constructs\ReactPipeline.cs:line 85
at DevToolsCdk.Constructs.ReactPipeline..ctor(Construct scope, String id, ArtifactStore artifactStore, ReactPipelineProps props) in C:\projects\dev-tools-cdk\src\DevToolsCdk\Constructs\ReactPipeline.cs:line 48
at DevToolsCdk.Stacks.EvoBuildStack.EstablishReactFrontEnd(ReactFrontEndConfig frontEndConfig) in C:\projects\dev-tools-cdk\src\DevToolsCdk\Stacks\EvoBuildStack.cs:line 229
at DevToolsCdk.Stacks.EvoBuildStack..ctor(Construct scope, String id, EvoBuildConfig config, DevToolsStack sharedStack, DevToolsConfig sharedConfig, IStackProps props) in C:\projects\dev-tools-cdk\src\DevToolsCdk\Stacks\EvoBuildStack.cs:line 72
at DevToolsCdk.Program.Main(String[] args) in C:\projects\dev-tools-cdk\src\DevToolsCdk\Program.cs:line 56

Why is there involvement with LinuxBuildImage.AMAZON_LINUX_2_ARM? Our definition is for STANDARD_6_0 (Ubuntu).

Expected Behavior

CodeBuild continue to use LinuxBuildImage.STANDARD_6_0 like previously.

Current Behavior

LinuxBuildImage.STANDARD_6_0 somehow ends up as LinuxBuildImage.AMAZON_LINUX_2_ARM and not properly defined under the covers?

Reproduction Steps

  1. Update from Amazon.CDK.Lib 2.94.0 to 2.130.0.
  2. Build existing CDK project as per above code expectations.
  3. run cdk list

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.130.0

Framework Version

.NET 6.0

Node.js Version

18.9.0

OS

Windows 11

Language

.NET

Language Version

C# 10

Other information

No response

@icelava icelava added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Mar 18, 2024
@github-actions github-actions bot added the @aws-cdk/aws-codebuild Related to AWS CodeBuild label Mar 18, 2024
@icelava
Copy link
Author

icelava commented Mar 19, 2024

Even if other build images are used, STANDARD_7_0 or AMAZON_LINUX_2_5 the same error still appears.

@icelava
Copy link
Author

icelava commented Mar 19, 2024

We have a separate library project that does something similar but this one works correctly.

var buildProject = new PipelineProject(this, this.codeBuildName, new PipelineProjectProps
{
	Environment = new BuildEnvironment
	{
		BuildImage = LinuxBuildImage.STANDARD_7_0,
		ComputeType = ComputeType.MEDIUM
	},
	Description = $"{this._props.ProductName} {this._props.PackageName} publisher {this._props.Environment}",
	ProjectName = this.codeBuildName,
	Timeout = Duration.Minutes(10),
	Badge = false
});

Can't tell what is the difference that causes proper behaviour.

@icelava
Copy link
Author

icelava commented Mar 19, 2024

Update to CDK 2.133.0 did not solve the problem. Probably because the same underlying Amazon.JSII.Runtime 1.94.0 is used.

UPDATE

Force Amazon.JSII.Runtime update to 1.95.0 at top propject level still yields same result.

@icelava
Copy link
Author

icelava commented Mar 19, 2024

Following the inner libraries' stack the lowest I can get to is Amazon.JSII.Runtime.Services.ServiceContainer

namespace Amazon.JSII.Runtime.Services;

public static class ServiceContainer
{
	private static readonly Lazy<IServiceProvider> _serviceProvider = new Lazy<IServiceProvider>(() => BuildServiceProvider(), LazyThreadSafetyMode.ExecutionAndPublication);

	public static IServiceProvider? ServiceProviderOverride { get; set; }

	internal static IServiceProvider ServiceProvider => ServiceProviderOverride ?? _serviceProvider.Value;

	public static ServiceProvider BuildServiceProvider(ILoggerFactory? loggerFactoryOverride = null)
	{
		IServiceCollection services = new ServiceCollection();
		if (loggerFactoryOverride == null)
		{
			services.AddLogging(delegate (ILoggingBuilder builder)
			{
				builder.AddConsole();
			});
		}
		else
		{
			services.AddSingleton(loggerFactoryOverride);
		}

		services.AddSingleton<IFileSystem, FileSystem>();
		services.AddSingleton<IJsiiRuntimeProvider, JsiiRuntimeProvider>();
		services.AddSingleton<ILoadedPackageSet, LoadedPackageSet>();
		services.AddSingleton<ITypeCache, TypeCache>();
		services.AddSingleton<IJsiiToFrameworkConverter, JsiiToFrameworkConverter>();
		services.AddSingleton<IFrameworkToJsiiConverter, FrameworkToJsiiConverter>();
		services.AddSingleton<IReferenceMap, ReferenceMap>();
		services.AddSingleton<INodeProcess, NodeProcess>();
		services.AddSingleton<IRuntime, Runtime>();
		services.AddSingleton<IResourceExtractor, ResourceExtractor>();
		services.AddTransient<IClient, Client>();
		ServiceProvider serviceProvider = services.BuildServiceProvider();
		serviceProvider.GetRequiredService<IClient>().Hello();
		return serviceProvider;
	}

Client relies on Runtime to perform requests and responses for the enum property values but Runtime cannot be decompiled/navigated to thus cannot see how its performing these value references.

@icelava
Copy link
Author

icelava commented Mar 19, 2024

Value caching in play?

More details about our stack, and where the "culprit" is.

Our system consists for five separate applications and the constructor of the stack defines a CodePipeline for each individual app.

this.EstablishContainerPipeline1();
this.EstablishContainerPipeline2();
this.EstablishContainerPipeline3();
this.EstablishReactPipeline1();
this.EstablishReactPipeline2();

The first three use a different pipeline construct to build and push container images to ECR. CDK has no problem synthesizing those. It's only on the fourth (React) pipeline where the error happens, wihch made us wonder what's wrong with the React pipeline construct.

However on later testing by commenting out the container pipelines did CDK finally synthesize the React pipelines as expected. Reversing the order of pipelines (React before container) also works.

The former pipeline construct's CodeBuild makes use of LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0

this.buildProject = new PipelineProject(this, codeBuildName, new PipelineProjectProps
{
	Environment = new BuildEnvironment
	{
		BuildImage = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0,
		ComputeType = ComputeType.LARGE,
		Privileged = true
	},
	Description = $"{this._props.ProductName} {this._props.AppShorthand} CI CD {_props.Environment}",
	ProjectName = codeBuildName,
	BuildSpec = BuildSpec.FromSourceFilename(this._props.Buildspec),
	Timeout = Duration.Minutes(20),
	EnvironmentVariables = envVars,
	Badge = false,
	Cache = Cache.Local(LocalCacheMode.CUSTOM, LocalCacheMode.DOCKER_LAYER),
	Role = this._props.CodebuildRole
});

Those somehow have a lingering effect on the latter fourth (React) pipeline to reference LinuxBuildImage.AMAZON_LINUX_2_ARM instead?

I can't track any relation between LinuxArmBuildImage and LinuxBuildImage.

@pahud
Copy link
Contributor

pahud commented Mar 20, 2024

Hi

I am not .NET expert but this works for me in cdk v2.126.0

using Amazon.CDK;
using Amazon.CDK.AWS.CodeBuild;
using Constructs;

namespace Dotnet
{
    public class DotnetStack : Stack
    {
        internal DotnetStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your stack goes here
            new PipelineProject(this, "foo", new PipelineProjectProps
            {
                Environment = new BuildEnvironment
                {
                    BuildImage = LinuxBuildImage.STANDARD_6_0,
                    ComputeType = ComputeType.MEDIUM
                },
                ProjectName = "foo",
                Timeout = Duration.Minutes(10),
                Badge = false,
                Cache = Cache.Local(LocalCacheMode.CUSTOM),
            });
        }
    }
}

and cdk diff shows

Resources
[+] AWS::IAM::Role foo/Role fooRole65AC3ADB 
[+] AWS::IAM::Policy foo/Role/DefaultPolicy fooRoleDefaultPolicy357EC2C3 
[+] AWS::CodeBuild::Project foo foo6445C170 

LinuxArmBuildImage is for ARM-based images

/** @deprecated Use LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0 instead. */
public static readonly AMAZON_LINUX_2_ARM = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0;
/**
* Image "aws/codebuild/amazonlinux2-aarch64-standard:2.0".
* @deprecated Use LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0 instead.
* */
public static readonly AMAZON_LINUX_2_ARM_2 = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0;
/** @deprecated Use LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0 instead. */
public static readonly AMAZON_LINUX_2_ARM_3 = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0;

LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0 is defined here.

LinuxBuildImage.STANDARD_7_0 is defined here for AMD64 standard images.

Update from Amazon.CDK.Lib 2.94.0 to 2.130.0.

How did you upgrade from 2.94.0 to 2.130.0 ?

@pahud pahud added p2 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. effort/medium Medium work item – several days of effort language/dotnet Related to .NET bindings and removed needs-triage This issue or PR still needs to be triaged. labels Mar 20, 2024
@icelava
Copy link
Author

icelava commented Mar 21, 2024

We have our own L3 library assembly which depended on 2.130.0, now 2.133.0.

The pipeline constructs in play however are not part of that library but with the top-level CDK project. Synth works when the CodePipeline/Codebuild depending on LinuxBuildImage.STANDARD_6_0 are instantiated first before those depending LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_3_0.

WIth the original reverse order, that's when the strange mis-reference happens. Something that I cannot see with the Runtime class in use (from Client.StaticGet()).

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Mar 21, 2024
@icelava
Copy link
Author

icelava commented Apr 12, 2024

So who exactly is in charge of the .NET packages? (Amazon.JSII.Runtime)

@pahud pahud added p3 and removed p2 labels Jun 11, 2024
@AleksandrsJakovlevsVisma

I am having the same issue. It's annoying that I had to refactor code because of this silly little bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-codebuild Related to AWS CodeBuild bug This issue is a bug. effort/medium Medium work item – several days of effort language/dotnet Related to .NET bindings p3
Projects
None yet
Development

No branches or pull requests

3 participants