pulumi-aws icon indicating copy to clipboard operation
pulumi-aws copied to clipboard

Issue with AWS CodeBuild with projectVisibility is empty

Open rizaldim opened this issue 1 year ago • 6 comments

What happened?

I import a AWS CodeBuild project using pulumi import, it shows a warning:

Diagnostics:
  aws:codebuild:Project (codebuild_bca_trx_ner_v2):
    warning: One or more imported inputs failed to validate. This is almost certainly a bug in the `aws` provider. The import will still proceed, but you will need to edit the generated code after copying it into your program.
    warning: aws:codebuild/project:Project resource 'codebuild_bca_trx_ner_v2' has a problem: expected project_visibility to be one of ["PUBLIC_READ" "PRIVATE"], got . Examine values at 'codebuild_bca_trx_ner_v2.projectVisibility'.

and then I run pulumi up but I get an error:

Diagnostics:
  aws:codebuild:Project (codebuild_finscore_v4):
    error: aws:codebuild/project:Project resource 'codebuild_finscore_v4' has a problem: expected project_visibility to be one of ["PUBLIC_READ" "PRIVATE"], got . Examine values at 'codebuild_finscore_v4.projectVisibility'.

Since I set ignore_changes=["projectVisibility"] as my resource options (see code below), I expect that Pulumi will ignore the projectVisibility attribute but it doesn't.

Currently I work around it by running pulumi stack export after importing the CodeBuild project and then manually editing the export result json file, and then I run pulumi stack import with the edited file. It works fine but if I run pulumi refresh I am back to square one.

Example

My code:

import pulumi
import pulumi_aws as aws

buildspec_yml = None
with open('./buildspec.yml') as f:
    buildspec_yml = f.read()

env = 'stg'
projects = [
        {
            'name': 'bca_trx_ner_v2',
            'service': f'service-bca-trx-ner-{env}',
            'container_name': 'bca-trx-ner',
            'path_in_repo': 'bca-transaction-ner/v2'
        },
        {
            'name': 'finscore_v4',
            'service': f'service-finscore-v4-{env}',
            'container_name': 'finscore-v4',
            'path_in_repo': 'finscore/v4'
        }
    ]

for project in projects:
    project_name = f"codebuild_{project['name']}"

    artifacts = aws.codebuild.ProjectArtifactsArgs(
            location="shared-bucket-artifacts-ap-southeast-3-xxxxx",
            name=project['service'],
            namespace_type="BUILD_ID",
            packaging="NONE",
            path=f"/aws/codebuild/artifact-{project['service']}",
            type="S3",
        )

    environment_args = aws.codebuild.ProjectEnvironmentArgs(
            compute_type="BUILD_GENERAL1_LARGE",
            environment_variables=[
                aws.codebuild.ProjectEnvironmentEnvironmentVariableArgs(
                    name="APP_CONTAINER_NAME",
                    value=project['container_name'],
                ),
            ],
            image="aws/codebuild/amazonlinux2-x86_64-standard:5.0",
            privileged_mode=True,
            type="LINUX_CONTAINER",
        )

    source_args = aws.codebuild.ProjectSourceArgs(
            buildspec=f"""{buildspec_yml}""",
            git_clone_depth=1,
            git_submodules_config=aws.codebuild.ProjectSourceGitSubmodulesConfigArgs(
                fetch_submodules=False,
            ),
            location="https://github.com/myorg/myrepo.git",
            report_build_status=True,
            type="GITHUB",
        )

    codebuild_project = aws.codebuild.Project(project_name,
        artifacts=artifacts,
        badge_enabled=True,
        cache=aws.codebuild.ProjectCacheArgs(
            location=f"shared-bucket-artifacts-ap-southeast-3-xxxxx/aws/codebuild/cache-{project['service']}",
            type="S3",
        ),
        concurrent_build_limit=1,
        description=f"CodeBuild Project for {project['service']}",
        encryption_key="arn:aws:kms:ap-southeast-3:xxxxx:alias/aws/s3",
        environment=environment_args,
        logs_config=aws.codebuild.ProjectLogsConfigArgs(
            cloudwatch_logs=aws.codebuild.ProjectLogsConfigCloudwatchLogsArgs(
                group_name=f"/aws/codebuild/{project['service']}",
            ),
        ),
        name=project['service'],
        queued_timeout=60,
        service_role=f"arn:aws:iam::xxxxx:role/aws-codebuild-{project['service']}",
        source=source_args,
        source_version="staging",
        tags={
            "Environment": "stg",
            "ManagedBy": "Terraform",
            "Name": project['service'],
            "Service": project['service'],
            "Stack": "stack-pipeline",
        },
        opts=pulumi.ResourceOptions(
            ignore_changes=["projectVisibility"], 
            protect=False))

Output of pulumi about

CLI
Version 3.97.0 Go Version go1.21.5 Go Compiler gc

Plugins NAME VERSION aws 6.14.0 python unknown

Host
OS darwin Version 14.2 Arch arm64

This project is written in python: executable='/opt/homebrew/bin/python3' version='3.11.6'

Current Stack: organization/infra/staging

TYPE URN pulumi:pulumi:Stack urn:pulumi:staging::infra::pulumi:pulumi:Stack::infra-staging pulumi:providers:aws urn:pulumi:staging::infra::pulumi:providers:aws::default_6_14_0 aws:ecr/repository:Repository urn:pulumi:staging::infra::aws:ecr/repository:Repository::ecr_repo_apicron ... aws:codebuild/project:Project urn:pulumi:staging::infra::aws:codebuild/project:Project::codebuild_bca_trx_ner_v2 aws:codebuild/project:Project urn:pulumi:staging::infra::aws:codebuild/project:Project::codebuild_finscore_v4

Found no pending operations associated with staging

Backend
Name cangkeh-m2-1.local URL s3://pulumi-state-staging-xxxxxxxxxxx?awssdk=v2&profile=myprofile User rizaldim Organizations
Token type personal

Dependencies: NAME VERSION pip 23.3.2 pulumi-aws 6.14.0 setuptools 69.0.2 wheel 0.42.0

Pulumi locates its logs in /var/folders/z8/60m0nm0919d33zg8kppj0t600000gs/T/ by default

Additional context

  • My AWS region is ap-southeast-3
  • I run aws codebuild batch-get-projects --names <project_name> to check the value of projectVisibility of the project but that attribute doesn't show up in the output
  • I run aws codebuild update-project-visibility --project-arn <proj_arn> --project-visibility PRIVATE --debug to update its visibility but I got this error:
An error occurred (InvalidInputException) when calling the UpdateProjectVisibility operation: Unknown Operation UpdateProjectVisibility

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

rizaldim avatar Dec 19 '23 14:12 rizaldim

Potentially related issue from the upstream TF provider: https://github.com/hashicorp/terraform-provider-aws/issues/22473

antdking avatar Dec 19 '23 14:12 antdking

Additional info, might be useful:

  • These CodeBuild projects were created using Terraform with Terraform AWS Provider version 4.27.0
  • I tried to set the project visiblity to public using AWS Console, just so that the project visibility is not empty, but it failed. The error was Unknown Operation UpdateProjectVisibility. So probably the operation is not supported in my region. I can't find anything mentioning this in the AWS docs.

rizaldim avatar Dec 19 '23 14:12 rizaldim

Thank you for reporting this! My team will pick this up as time permits.

Additional context. In SDKv2 upstream this is defined as:

			"project_visibility": {
				Type:         schema.TypeString,
				Optional:     true,
				Default:      codebuild.ProjectVisibilityTypePrivate,
				ValidateFunc: validation.StringInSlice(codebuild.ProjectVisibilityType_Values(), false),
			},

But the default value is not propagated into the Pulumi schema for some reason.

» $schema rs aws:codebuild/project:Project schema inputProperties projectVisibility
description: |
    Specifies the visibility of the project's builds. Possible values are: `PUBLIC_READ` and `PRIVATE`. Default value is `PRIVATE`.
type: string

Theoretically not specifying projectVisibility should assume PRIVATE here, so pulumi up should work fine without having the projectVisibility specified.

t0yv0 avatar Dec 20 '23 16:12 t0yv0

Thanks @t0yv0 . Might I ask, what is that schema rs that you run? Is that part of pulumi schema command?

rizaldim avatar Dec 20 '23 16:12 rizaldim

Ah sorry that's just some personal tool I've been working on (https://github.com/t0yv0/pus) to assist this kind of lookup; it's not yet really ready for public use. You can get roughly the same result out with jq over schema.json in the repo, drilling down into the Pulumi Package Schema files.

t0yv0 avatar Dec 20 '23 20:12 t0yv0

There are a couple of issues going on here, but the issues will only occur if you are working in a region that does not yet support the projectVisibility API. You would not be able to reproduce the issue in us-east-2 for example. This means that the issue will eventually be resolved when AWS finishes rolling this out to all regions.

When you create a project, the default projectVisibility is PRIVATE. When you are creating a project in a region that doesn't support projectVisibility the create will work fine because projectVisibility is not set. On subsequent updates it will show a diff on projectVisibility and the update will fail because the UpdateProjectVisiblity API is not available. This is also the case in Terraform.

Where this issue diverges from upstream is that if you try this in Terraform, Terraform will let you import the Project, but will then fail on subsequent actions. Pulumi will not let you proceed with the import because it shows a diff

warning: inputs to import do not match the existing resource; importing this resource will fail
    = aws:codebuild/project:Project: (import)
        [id=chall-project-e287179]
        [urn=urn:pulumi:dev::pulumi-typescript-app::aws:codebuild/project:Project::chall-project]
        [provider=urn:pulumi:dev::pulumi-typescript-app::pulumi:providers:aws::default_6_41_0::f13b0394-998a-465b-ba4a-867fe8f91cfa]
      + projectVisibility: "PRIVATE"
Resources:
    = 1 to import
    3 unchanged

...

error: inputs to import do not match the existing resource
error: update failed

I don't think this is something we should fix on the Pulumi side. Ideally this is something that should be fixed upstream, maybe as a DiffSuppressFunc. I've testing this out and the below DiffSuppressFunc would allow the import to succeed. e.g.

			"project_visibility": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  types.ProjectVisibilityTypePrivate,
				DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool {
					return oldValue == "" && newValue == "PRIVATE"
				},
				ValidateDiagFunc: enum.Validate[types.ProjectVisibilityType](),
			},

corymhall avatar Jul 03 '24 16:07 corymhall