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

(pipelines): publish_assets_in_parallel + docker_credentials results in jsii error #16164

Closed
amirfireeye opened this issue Aug 22, 2021 · 4 comments
Labels
@aws-cdk/pipelines CDK Pipelines library bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. effort/medium Medium work item – several days of effort p1

Comments

@amirfireeye
Copy link
Contributor

I am trying to use the new publish_assets_in_parallel option of CDK Pipelines to reduce the number of CodeBuild projects we have. As the number of pipelines grows, we are seeing more and more throttling of CodeBuild. A lower number of projects would help with that.

However, when used with docker_credentials and specifically pipelines.DockerCredential.ecr, I get a weird jsii error:

jsii.errors.JSIIError: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object

pipelines.DockerCredential.docker_hub works fine. It's only the ECR credentials that seem to trip it.

Reproduction Steps

Synth the following minimal example.

from aws_cdk import core, pipelines, aws_lambda, aws_ecr_assets, aws_secretsmanager, aws_ecr
import os

os.makedirs("f1", exist_ok=True)
open("f1/hello", "w")
os.makedirs("f2", exist_ok=True)
open("f2/world", "w")
os.makedirs("d1", exist_ok=True)
open("d1/Dockerfile", "w").write("FROM nginx")
os.makedirs("d2", exist_ok=True)
open("d2/Dockerfile", "w").write("FROM bash")

app = core.App()

stage = core.Stage(app, "stage")
stack = core.Stack(stage, "stack")
aws_lambda.Function(stack, "f1", code=aws_lambda.Code.from_asset("f1"), handler="asd", runtime=aws_lambda.Runtime.PYTHON_3_7)
aws_lambda.Function(stack, "f2", code=aws_lambda.Code.from_asset("f2"), handler="asd", runtime=aws_lambda.Runtime.PYTHON_3_8)
aws_ecr_assets.DockerImageAsset(stack, "d1", directory="d1")
aws_ecr_assets.DockerImageAsset(stack, "d2", directory="d2")
pipeline_stack = core.Stack(app, "pipeline-stack")
pipeline = pipelines.CodePipeline(
    pipeline_stack,
    "pipeline",
    synth=pipelines.ShellStep("synth", input=pipelines.CodePipelineSource.git_hub("foo/bar", "main"), commands=["cdk synth"]),
    publish_assets_in_parallel=False,
    docker_credentials=[
        pipelines.DockerCredential.ecr(
            [
                aws_ecr.Repository.from_repository_attributes(
                    pipeline_stack,
                    "EcrAllRepos",
                    repository_name="*",
                    repository_arn=pipeline_stack.format_arn(
                        service="ecr",
                        resource="*",
                    ),
                )
            ]
        ),
    ]
)

app.synth()

What did you expect to happen?

I would expect this code to synth without errors.

What actually happened?

jsii.errors.JavaScriptError: 
  TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
      at Object.writeFileSync (node:fs:2146:5)
      at CodeBuildFactory.produceAction (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/jsii-kernel-uMjfip/node_modules/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.js:120:16)
      at Object.produceAction (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/jsii-kernel-uMjfip/node_modules/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.js:58:40)
      at CodePipeline.pipelineStagesAndActionsFromGraph (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/jsii-kernel-uMjfip/node_modules/@aws-cdk/pipelines/lib/codepipeline/codepipeline.js:154:48)
      at CodePipeline.doBuildPipeline (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/jsii-kernel-uMjfip/node_modules/@aws-cdk/pipelines/lib/codepipeline/codepipeline.js:116:14)
      at CodePipeline.buildPipeline (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/jsii-kernel-uMjfip/node_modules/@aws-cdk/pipelines/lib/main/pipeline-base.js:93:14)
      at /private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/tmpca5ycjyg/lib/program.js:7970:134
      at Kernel._wrapSandboxCode (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/tmpca5ycjyg/lib/program.js:8582:24)
      at /private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/tmpca5ycjyg/lib/program.js:7970:107
      at Kernel._ensureSync (/private/var/folders/ln/r1dlp_xj6t57ddclvh7zgl8m0000gp/T/tmpca5ycjyg/lib/program.js:8563:28)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/amir.szekely/Documents/dev/cdk-playground/app.py", line 91, in <module>
    app.synth()
  File "/Users/amir.szekely/Library/Caches/pypoetry/virtualenvs/cdk-playground-5iem8SJB-py3.9/lib/python3.9/site-packages/aws_cdk/core/__init__.py", line 16432, in synth
    return typing.cast(aws_cdk.cx_api.CloudAssembly, jsii.invoke(self, "synth", [options]))
  File "/Users/amir.szekely/Library/Caches/pypoetry/virtualenvs/cdk-playground-5iem8SJB-py3.9/lib/python3.9/site-packages/jsii/_kernel/__init__.py", line 128, in wrapped
    return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
  File "/Users/amir.szekely/Library/Caches/pypoetry/virtualenvs/cdk-playground-5iem8SJB-py3.9/lib/python3.9/site-packages/jsii/_kernel/__init__.py", line 340, in invoke
    response = self.provider.invoke(
  File "/Users/amir.szekely/Library/Caches/pypoetry/virtualenvs/cdk-playground-5iem8SJB-py3.9/lib/python3.9/site-packages/jsii/_kernel/providers/process.py", line 359, in invoke
    return self._process.send(request, InvokeResponse)
  File "/Users/amir.szekely/Library/Caches/pypoetry/virtualenvs/cdk-playground-5iem8SJB-py3.9/lib/python3.9/site-packages/jsii/_kernel/providers/process.py", line 326, in send
    raise JSIIError(resp.error) from JavaScriptError(resp.stack)
jsii.errors.JSIIError: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
Subprocess exited with error 1

Environment

  • CDK CLI Version: 1.119.0
  • Framework Version: 1.119.0
  • Node.js Version: v16.7.0
  • OS : Mac OS X
  • Language (Version): Python 3.9.6

Other


This is 🐛 Bug Report

@amirfireeye amirfireeye added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 22, 2021
@github-actions github-actions bot added the @aws-cdk/pipelines CDK Pipelines library label Aug 22, 2021
@rix0rrr
Copy link
Contributor

rix0rrr commented Aug 24, 2021

The wrong argument type is going into writeFileSync somewhere.

@rix0rrr
Copy link
Contributor

rix0rrr commented Aug 24, 2021

Did some investigation. This does not work currently, and it's not trivial to make it work either.

We're trying to serialize something with CFN references in there, which can't work:

      {
        "Fn::Join": [
          "",
          [
            "{\n  \"version\": \"0.2\",\n  \"phases\": {\n    \"pre_build\": {\n      \"commands\": [\n        \"mkdir $HOME/.cdk\",\n        \"echo '{\\\"version\\\":\\\"1.0\\\",\\\"domainCredentials\\\":{\\\"",
            {
              "Fn::Select": [
                0,
                {
                  "Fn::Split": [
                    "/",
                    {
                      "Fn::Join": [
                        "",
                        [
                          "0123456789012.dkr.ecr.eu-west-1.",
                          {
                            "Ref": "AWS::URLSuffix"
                          },
                          "/Repo"
                        ]
                      ]
                    }
                  ]
                }
              ]
            },
            "\\\":{\\\"ecrRepository\\\":true}}}' > $HOME/.cdk/cdk-docker-creds.json\"\n      ]\n    },\n    \"install\": {\n      \"commands\": [\n        \"npm install -g cdk-assets\"\n      ]\n    },\n    \"build\": {\n      \"commands\": [\n        \"cdk-assets --path \\\"assembly-Stack-AssetApp/StackAssetAppStack49426810.assets.json\\\" --verbose publish \\\"4b0bf2f37027b09f3a67f81c664f1e9c59817962c6cedbcd95831848f69ae076:current_account-current_region\\\"\"\n      ]\n    }\n  }\n}"
          ]
        ]
      }

Fortunately it only seems to be { "Ref": "AWS::URLSuffix" }, which is returned from repository.repositoryUri.

As a workaround, creating your own subclass of IRepository that returns amazonaws.com directly in that spot would do it.

rix0rrr added a commit that referenced this issue Aug 24, 2021
…essage

When a buildspec is written to disk at synth time and the BuildSpec
contains CFN references, the error produced is:

```
The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
```

Because it's trying to write the `{ Fn::Join }` instead of a plain
string. This error message is pretty useless.

Supporting the feature correctly is a lot more complicated, but at
least we can detect this situation and give a more readable error
message.

Relates to #16164.
mergify bot pushed a commit that referenced this issue Aug 24, 2021
#16196)

…essage

When a buildspec is written to disk at synth time and the BuildSpec
contains CFN references, the error produced is:

```
The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
```

Because it's trying to write the `{ Fn::Join }` instead of a plain
string. This error message is pretty useless.

Supporting the feature correctly is a lot more complicated, but at
least we can detect this situation and give a more readable error
message.

Relates to #16164.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@amirfireeye
Copy link
Contributor Author

amirfireeye commented Aug 24, 2021

Thanks @rix0rrr. It wanted grantPull and complained about the account and region for me so I ended up with:

@jsii.implements(aws_ecr.IRepository)
class RepoWrapper:
    def __init__(self, repo: aws_ecr.Repository, account: str, region: str):
        self._repo = repo
        self._uri = f"{account}.dkr.ecr.{region}.amazonaws.com/{repo.repository_name}"

    @property
    @jsii.member(jsii_name="repositoryUri")
    def repository_uri(self):
        return self._uri

    @jsii.member(jsii_name="grantPull")
    def grant_pull(self, grantee):
        return self._repo.grant_pull(grantee)

And then used it with:

    publish_assets_in_parallel=False,
    docker_credentials=[
        pipelines.DockerCredential.ecr(
            [
                RepoWrapper(
                    aws_ecr.Repository.from_repository_name(
                        pipeline_stack,
                        "EcrAllRepos",
                        repository_name="*",
                    ),
                    "12345",
                    "us-west-2",
                ),
            ]
        ),

This is the first time I got jsii interface implementation working in Python 😁

hollanddd pushed a commit to hollanddd/aws-cdk that referenced this issue Aug 26, 2021
aws#16196)

…essage

When a buildspec is written to disk at synth time and the BuildSpec
contains CFN references, the error produced is:

```
The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
```

Because it's trying to write the `{ Fn::Join }` instead of a plain
string. This error message is pretty useless.

Supporting the feature correctly is a lot more complicated, but at
least we can detect this situation and give a more readable error
message.

Relates to aws#16164.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
TikiTDO pushed a commit to TikiTDO/aws-cdk that referenced this issue Sep 6, 2021
aws#16196)

…essage

When a buildspec is written to disk at synth time and the BuildSpec
contains CFN references, the error produced is:

```
The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
```

Because it's trying to write the `{ Fn::Join }` instead of a plain
string. This error message is pretty useless.

Supporting the feature correctly is a lot more complicated, but at
least we can detect this situation and give a more readable error
message.

Relates to aws#16164.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@rix0rrr rix0rrr added effort/medium Medium work item – several days of effort p1 and removed needs-triage This issue or PR still needs to be triaged. labels Sep 7, 2021
@rix0rrr rix0rrr removed their assignment Sep 7, 2021
david-doyle-as24 pushed a commit to david-doyle-as24/aws-cdk that referenced this issue Sep 7, 2021
aws#16196)

…essage

When a buildspec is written to disk at synth time and the BuildSpec
contains CFN references, the error produced is:

```
The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Object
```

Because it's trying to write the `{ Fn::Join }` instead of a plain
string. This error message is pretty useless.

Supporting the feature correctly is a lot more complicated, but at
least we can detect this situation and give a more readable error
message.

Relates to aws#16164.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

github-actions bot commented Sep 7, 2022

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

@github-actions github-actions bot added closing-soon This issue will automatically close in 4 days unless further comments are made. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/pipelines CDK Pipelines library bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. effort/medium Medium work item – several days of effort p1
Projects
None yet
Development

No branches or pull requests

2 participants