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

codepipeline-actions: RuntimeError: Error: The 'account' property must be a concrete value #29361

Open
subhashisbhowmik opened this issue Mar 5, 2024 · 8 comments
Labels
@aws-cdk/pipelines CDK Pipelines library bug This issue is a bug. effort/medium Medium work item – several days of effort p2

Comments

@subhashisbhowmik
Copy link

Describe the bug

I am seeing RuntimeError: Error: The 'account' property must be a concrete value during cdk synth

Expected Behavior

cdk synth succeeds

Current Behavior

cdk synth fails with RuntimeError: Error: The 'account' property must be a concrete value

During cdk synth --profile <profile> I get:

(.venv) (py311) PS C:\Users\Subhashis\Desktop\DHCDK> cdk synth --profile <profile>
123456789
ap-south-1
jsii.errors.JavaScriptError:
  @jsii/kernel.RuntimeError: Error: The 'account' property must be a concrete value (action: 'DeployBeta')
      at Kernel._Kernel_ensureSync (C:\Users\SUBHAS~1\AppData\Local\Temp\tmpllzgwr8m\lib\program.js:10491:23)
      at Kernel.invoke (C:\Users\SUBHAS~1\AppData\Local\Temp\tmpllzgwr8m\lib\program.js:9855:102)
      at KernelHost.processRequest (C:\Users\SUBHAS~1\AppData\Local\Temp\tmpllzgwr8m\lib\program.js:11696:36)
      at KernelHost.run (C:\Users\SUBHAS~1\AppData\Local\Temp\tmpllzgwr8m\lib\program.js:11656:22)
      at Immediate._onImmediate (C:\Users\SUBHAS~1\AppData\Local\Temp\tmpllzgwr8m\lib\program.js:11657:46)
      at process.processImmediate (node:internal/timers:476:21)

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

Traceback (most recent call last):
  File "C:\Users\Subhashis\Desktop\DHCDK\app.py", line 22, in <module>
    DhAppPipelineStack(app, "DhAppPipelineStack", cdk_pipeline=cdk_pipeline, env=env)
  File "C:\Users\Subhashis\Desktop\DHCDK\.venv\Lib\site-packages\jsii\_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Subhashis\Desktop\DHCDK\dhcdk\application_pipeline\dh_app_pipeline_stack.py", line 75, in __init__
    beta_ecs_stage = self.create_deploy_stage("Beta", pipeline, build_output, kwargs["env"])
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Subhashis\Desktop\DHCDK\dhcdk\application_pipeline\dh_app_pipeline_stack.py", line 107, in create_deploy_stage
    stage.add_action(deploy_action)
  File "C:\Users\Subhashis\Desktop\DHCDK\.venv\Lib\site-packages\aws_cdk\aws_codepipeline\__init__.py", line 5814, in add_action
    return typing.cast(None, jsii.invoke(self, "addAction", [action]))
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Subhashis\Desktop\DHCDK\.venv\Lib\site-packages\jsii\_kernel\__init__.py", line 149, in wrapped
    return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Subhashis\Desktop\DHCDK\.venv\Lib\site-packages\jsii\_kernel\__init__.py", line 399, in invoke
    response = self.provider.invoke(
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Subhashis\Desktop\DHCDK\.venv\Lib\site-packages\jsii\_kernel\providers\process.py", line 380, in invoke
    return self._process.send(request, InvokeResponse)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Subhashis\Desktop\DHCDK\.venv\Lib\site-packages\jsii\_kernel\providers\process.py", line 342, in send
    raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: Error: The 'account' property must be a concrete value (action: 'DeployBeta')

Reproduction Steps

app.py

#!/usr/bin/env python3
import aws_cdk as cdk

from dhcdk.infra_pipeline.dh_infra_pipeline_stack import DhInfraPipelineStack
from dhcdk.application_pipeline.dh_app_pipeline_stack import DhAppPipelineStack

account_id = '123456789'
region = 'ap-south-1'
env = cdk.Environment(account=account_id, region=region)

app = cdk.App()

DhInfraPipelineStack(app, "DhcdkPipelineStack", env=env)
DhAppPipelineStack(app, "DhAppPipelineStack", env=env)

app.synth()

dh_app_pipeline_stack.py:

from aws_cdk import (
    Stack,
    aws_codebuild as codebuild,
    aws_codepipeline as codepipeline,
    aws_codepipeline_actions as codepipeline_actions,
    aws_ecs as ecs,
    aws_ssm as ssm,
)
from constructs import Construct
from aws_cdk import aws_ecr as ecr
import aws_cdk

class DhAppPipelineStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        repository = ecr.Repository.from_repository_name(self, "drh_core_application", "drh_core_application")

        pipeline = codepipeline.Pipeline(
            self, "MyPipeline",
            pipeline_name="MyPipeline"
        )

        # Define the source stage
        source_output = codepipeline.Artifact()
        source_action = codepipeline_actions.CodeStarConnectionsSourceAction(
            connection_arn="arn:aws:codestar-connections:ap-south-1:123456789:connection/abcde",
            action_name="Source",
            output=source_output,
            owner="Artemis-Technologies",
            repo="CoreService",
            branch="main"
        )
        pipeline.add_stage(
            stage_name="Source",
            actions=[source_action]
        )

        # Define the build stage
        build_output = codepipeline.Artifact()
        build_action = codepipeline_actions.CodeBuildAction(
            action_name="Build",
            project=codebuild.PipelineProject(
                self, "CoreService",
                build_spec=codebuild.BuildSpec.from_source_filename("buildspec.yml"),
                environment=codebuild.BuildEnvironment(
                    build_image=codebuild.LinuxBuildImage.STANDARD_7_0
                )
            ),
            input=source_output,
            outputs=[build_output]
        )
        pipeline.add_stage(
            stage_name="Build",
            actions=[build_action]
        )

        # Define the deploy stages
        beta_ecs_stage = self.create_deploy_stage("Beta", pipeline, build_output, kwargs["env"])
        prod_ecs_stage = self.create_deploy_stage("Prod", pipeline, build_output, kwargs["env"])
        #
        # # Add manual approval action between beta and prod stages
        # manual_approval_action = codepipeline_actions.ManualApprovalAction(
        #     action_name="Approve",
        #     run_order=1
        # )
        # prod_ecs_stage.add_action(manual_approval_action)

    def create_deploy_stage(self, stage: str, pipeline: codepipeline.Pipeline,
                            build_output: codepipeline.Artifact, env) -> codepipeline.IStage:

        print(env.account)
        print(env.region)
        ecs_cluster_arn = ssm.StringParameter.value_for_string_parameter(self, f"/deploymentInfo/{stage}/DrhClusterArn")
        ecs_service_arn = ssm.StringParameter.value_for_string_parameter(self, f"/deploymentInfo/{stage}/DrhApplicationArn")
        ecs_cluster = ecs.Cluster.from_cluster_arn(self, f"{stage}-DrhCluster", cluster_arn=ecs_cluster_arn)
        ecs_service = ecs.FargateService.from_fargate_service_attributes(self, f"{stage}-DrhApplication", service_arn=ecs_service_arn, cluster=ecs_cluster)

        # print(ecs_service)
        deploy_action = codepipeline_actions.EcsDeployAction(
            action_name=f"Deploy{stage}",
            service=ecs_service,
            image_file=build_output.at_path("imageDetail.json"),
            run_order=1,
            deployment_timeout=aws_cdk.Duration.minutes(60),
        )

        stage = pipeline.add_stage(
            stage_name=stage
        )
        stage.add_action(deploy_action)

        return stage

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.82.0 (build 3a8648a)

Framework Version

No response

Node.js Version

v18.16.0

OS

Windows 10

Language

Python

Language Version

3.11

Other information

No response

@subhashisbhowmik subhashisbhowmik added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Mar 5, 2024
@github-actions github-actions bot added the @aws-cdk/pipelines CDK Pipelines library label Mar 5, 2024
@pahud
Copy link
Contributor

pahud commented Mar 6, 2024

Hi

2.82.0 was pretty old version. Can you try the latest CDK version v2.131.0 from a clean repo and see if this issue still exists?

@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 and removed needs-triage This issue or PR still needs to be triaged. labels Mar 6, 2024
@subhashisbhowmik
Copy link
Author

Hi,

Had some issues with updating CDK, so moved to wsl2. Still seeing the same issue with the updated CDK

(.venv) (base) root@Subhashis-Desktop:/mnt/c/Users/Subhashis/Desktop/DHCDK# cdk synth
123456789
ap-south-1
jsii.errors.JavaScriptError:
  @jsii/kernel.RuntimeError: Error: The 'account' property must be a concrete value (action: 'DeployBeta')
      at Kernel._Kernel_ensureSync (/tmp/tmp0upb_l2n/lib/program.js:10491:23)
      at Kernel.invoke (/tmp/tmp0upb_l2n/lib/program.js:9855:102)
      at KernelHost.processRequest (/tmp/tmp0upb_l2n/lib/program.js:11696:36)
      at KernelHost.run (/tmp/tmp0upb_l2n/lib/program.js:11656:22)
      at Immediate._onImmediate (/tmp/tmp0upb_l2n/lib/program.js:11657:46)
      at process.processImmediate (node:internal/timers:478:21)

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

Traceback (most recent call last):
  File "/mnt/c/Users/Subhashis/Desktop/DHCDK/app.py", line 14, in <module>
    DhAppPipelineStack(app, "DhAppPipelineStack", env=env)
  File "/root/miniconda3/lib/python3.11/site-packages/jsii/_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/c/Users/Subhashis/Desktop/DHCDK/dhcdk/application_pipeline/dh_app_pipeline_stack.py", line 59, in __init__
    beta_ecs_stage = self.create_deploy_stage("Beta", pipeline, build_output, kwargs["env"])
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/c/Users/Subhashis/Desktop/DHCDK/dhcdk/application_pipeline/dh_app_pipeline_stack.py", line 91, in create_deploy_stage
    stage.add_action(deploy_action)
  File "/root/miniconda3/lib/python3.11/site-packages/aws_cdk/aws_codepipeline/__init__.py", line 5814, in add_action
    return typing.cast(None, jsii.invoke(self, "addAction", [action]))
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/miniconda3/lib/python3.11/site-packages/jsii/_kernel/__init__.py", line 149, in wrapped
    return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/miniconda3/lib/python3.11/site-packages/jsii/_kernel/__init__.py", line 399, in invoke
    response = self.provider.invoke(
               ^^^^^^^^^^^^^^^^^^^^^
  File "/root/miniconda3/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 380, in invoke
    return self._process.send(request, InvokeResponse)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/miniconda3/lib/python3.11/site-packages/jsii/_kernel/providers/process.py", line 342, in send
    raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: Error: The 'account' property must be a concrete value (action: 'DeployBeta')

Subprocess exited with error 1
(.venv) (base) root@Subhashis-Desktop:/mnt/c/Users/Subhashis/Desktop/DHCDK# cdk --version
2.131.0 (build 92b912d)

@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 7, 2024
@subhashisbhowmik
Copy link
Author

subhashisbhowmik commented Mar 8, 2024

Even if I use CfnOutput + Fn.import_value, the result is the same
I suppose the issue is with codepipeline_actions.EcsDeployAction

        ecs_cluster = ecs.Cluster.from_cluster_arn(self, f"{stage}-DrhCluster", cluster_arn=ecs_cluster_arn)
        ecs_service = ecs.FargateService.from_fargate_service_attributes(self, f"{stage}-DrhApplication", service_arn=ecs_service_arn, cluster=ecs_cluster)

        # print(ecs_service)
        deploy_action = codepipeline_actions.EcsDeployAction(
            action_name=f"Deploy{stage}",
            service=ecs_service,
            image_file=build_output.at_path("imageDetail.json"),
            run_order=1,
            deployment_timeout=aws_cdk.Duration.minutes(60),
        )

        stage = pipeline.add_stage(
            stage_name=stage
        )
        stage.add_action(deploy_action)

@pahud
Copy link
Contributor

pahud commented Mar 13, 2024

Thank you for the report.

Let's simplify the provided code snippets.

Are you able to just create the EcsDeployAction by passing a static serviceArn like this?

This is a typescript sample that I can cdk synth with no error and I guess cdk python should work too.

export class DummyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const vpc = getDefaultVpc(this);
    const cluster = new ecs.Cluster(this, 'Cluster', { vpc });

    const sourceOutput = new codepipeline.Artifact();

    const accountId = 'YOUR_ACCOUNT_ID';

    // create a dummy sourceAction
    const sourceAction = new codepipelineActions.CodeStarConnectionsSourceAction({
      actionName: 'BitBucket_Source',
      owner: 'aws',
      repo: 'aws-cdk',
      output: sourceOutput,
      connectionArn: `arn:aws:codestar-connections:us-east-1:${accountId}:connection/12345678-abcd-12ab-34cdef5678gh`,
      variablesNamespace: 'SomeSpace',
    });
    
  
    const deployAction = new codepipelineActions.EcsDeployAction({
      actionName: 'foo',
      service: ecs.FargateService.fromFargateServiceAttributes(this, 'FGService', {
        cluster,
        serviceArn: `arn:aws:ecs:us-east-1:${accountId}:service/cluster-name/service-name`,
      }),
      input: sourceOutput,
    })

    const pipeline = new codepipeline.Pipeline(this, 'MyPipeline');
    pipeline.addStage({
      stageName: 'Source',
      actions: [sourceAction],
    });
    pipeline.addStage({
      stageName: 'Deploy',
      actions: [deployAction],
    });
  }
}

@pahud pahud added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Mar 13, 2024
@pahud
Copy link
Contributor

pahud commented Mar 13, 2024

I am guessing as you are using ssm.StringParameter.value_for_string_parameter to represent the ecs_service_arn, which will be passed here as resource prop and might be having issue to determine the account in the synth time as it's a token but I am not 100% sure. Let's first check if passing a full static serviceArn works as my provided sample above.

@pahud pahud changed the title CDK: RuntimeError: Error: The 'account' property must be a concrete value codepipeline-actions: RuntimeError: Error: The 'account' property must be a concrete value Mar 13, 2024
@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 13, 2024
@subhashisbhowmik
Copy link
Author

Hi @pahud, yes, passing the arn directly works, but even if I use Fn.import it doesn't work
This works:

        ecs_cluster_arn = "arn:aws:ecs:ap-south-1:123456789:cluster/beta-DhcdkStack-betaDrhCluster86916E42-r9fuNYW5ZfTd"
        ecs_service_arn = "arn:aws:ecs:ap-south-1:123456789:service/beta-DhcdkStack-betaDrhCluster86916E42-r9fuNYW5ZfTd/beta-DrhApplication"

This doesn't:

        ecs_cluster_arn = Fn.import_value(f"{stage}-DrhClusterArn")
        ecs_service_arn = Fn.import_value(f"{stage}-DrhApplicationArn")

@moniyazi1
Copy link

Facing the same issue for exactly the same usecase @subhashisbhowmik described above. Any suggestions on how to proceed?

@subhashisbhowmik
Copy link
Author

Hi team, any update on this?

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. effort/medium Medium work item – several days of effort p2
Projects
None yet
Development

No branches or pull requests

3 participants