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

Service Catalog Deploy Action for CodePipeline #3744

Closed
khornberg opened this issue Aug 21, 2019 · 5 comments
Closed

Service Catalog Deploy Action for CodePipeline #3744

khornberg opened this issue Aug 21, 2019 · 5 comments
Assignees
Labels
@aws-cdk/aws-codepipeline Related to AWS CodePipeline bug This issue is a bug. language/python Related to Python bindings p2 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@khornberg
Copy link

❓ General Issue

The Question

What am I doing wrong when trying to implement the IAction interface since CDK lacks a Service Catalog deploy action?

I am trying to work from the instructions for Python and the code in #2516.

Is this not possible in Python?

Some of my code was taken from the classes implemented in the python package.

In raw CloudFormation yaml what I am looking for looks like:

Actions:
- Name: PublishToServiceCatalog
  RunOrder: 1
  ActionTypeId:
    Category: Deploy
    Owner: AWS
    Provider: ServiceCatalog
    Version: '1'
  InputArtifacts:
    - Name: Artifact
  Configuration:
    ConfigurationFilePath: 'service-config.json'
    ProductId:
      Ref: ServiceCatalogProduct

Thus the base question would be, how do I get that into my synthesized stack when the Pipeline StageProps expect an IAction object?

Perhaps I am thinking about all of this wrongly or something.

Environment

  • CDK CLI Version: 1.5.0
  • Module Version: 1.5.0
  • OS: SX Mojave
  • Language: Python

Other information

With

import jsii

from aws_cdk.aws_codepipeline_actions import Action

from aws_cdk.aws_codepipeline import IAction
from aws_cdk.aws_codepipeline import ActionArtifactBounds
from aws_cdk.aws_codepipeline import ActionBindOptions
from aws_cdk.aws_codepipeline import ActionCategory
from aws_cdk.aws_codepipeline import ActionProperties
from aws_cdk.aws_codepipeline import CommonAwsActionProps


class ServiceCatalogApprovalActionProps(CommonAwsActionProps):
    def __init__(self, *args, **kwargs):
        self._values = {"action_name": kwargs["action_name"]}

    @property
    def action_name(self):
        return self._values.get("action_name")

    def __eq__(self, rhs) -> bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs) -> bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceCatalogActionProps(%s)" % ", ".join(k + "=" + repr(v) for k, v in self._values.items())


@jsii.implements(IAction)
class ServiceCatalogAction(Action):
    def __init__(self, action_name, *args, run_order=None, **kwargs):
        artifact_bounds = ActionArtifactBounds(max_inputs=1, max_outputs=0, min_inputs=1, min_outputs=0)
        category = ActionCategory.DEPLOY
        provider = "ServiceCatalog"
        self.action_properties = ActionProperties(
            action_name=action_name,
            artifact_bounds=artifact_bounds,
            category=category,
            provider=provider
        )
        props = ServiceCatalogApprovalActionProps(action_name=action_name)
        jsii.create(ServiceCatalogAction, self, [props])

    @jsii.member(jsii_name="bound")
    def _bound(self, scope, _stage, *, bucket, role):
        options = ActionBindOptions(bucket=bucket, role=role)
        return jsii.invoke(self, "bound", [scope, _stage, options])

I get

└──➤ cdk synth --path-metadata false --version-reporting false
Traceback (most recent call last):
  File "resources/app.py", line 8, in <module>
    Stack(app, REPO)
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_runtime.py", line 66, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/Users/kyle/projects/python-api-example/resources/stack.py", line 36, in __init__
    self.create()
  File "/Users/kyle/projects/python-api-example/resources/stack.py", line 102, in create
    action_name="Publish-Service", run_order=1, input=deploy_artifact, configuration={}
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_runtime.py", line 66, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/Users/kyle/projects/python-api-example/resources/custom_cdk.py", line 57, in __init__
    provider=provider
AttributeError: can't set attribute

With

class ServiceCatalogApprovalActionProps(CommonAwsActionProps):
    def __init__(self, *args, **kwargs):
        self._values = {"action_name": kwargs["action_name"]}
        self._values['artifact_bounds'] = ActionArtifactBounds(max_inputs=1, max_outputs=0, min_inputs=1, min_outputs=0)
        self._values['category'] = ActionCategory.DEPLOY
        self._values['provider'] = "ServiceCatalog"

    @property
    def action_name(self):
        return self._values.get("action_name")

    def __eq__(self, rhs) -> bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs) -> bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ServiceCatalogActionProps(%s)" % ", ".join(k + "=" + repr(v) for k, v in self._values.items())


@jsii.implements(IAction)
class ServiceCatalogAction(Action):
    def __init__(self, action_name, *args, run_order=None, **kwargs):
        props = ServiceCatalogApprovalActionProps(action_name=action_name)
        jsii.create(ServiceCatalogAction, self, [props])

    @jsii.member(jsii_name="bound")
    def _bound(self, scope, _stage, *, bucket, role):
        options = ActionBindOptions(bucket=bucket, role=role)
        return jsii.invoke(self, "bound", [scope, _stage, options])

Stacktrace

└──➤ cdk synth --path-metadata false --version-reporting false
jsii.errors.JavaScriptError:
  Error: Missing required properties for @aws-cdk/aws-codepipeline.ActionProperties: artifactBounds,category,provider
      at validateRequiredProps (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:12544:15)
	  at Object.deserialize (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_em[21/1842]ii/jsii-runtime.js:12212:21)
      at Kernel._toSandbox (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7031:61)
      at /Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7084:33
      at Array.map (<anonymous>)
      at Kernel._boxUnboxParameters (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7084:19)
      at Kernel._toSandboxValues (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7069:21)
      at /Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6666:66
      at Kernel._wrapSandboxCode (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:7134:19)
      at Kernel._create (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6666:26)
      at Kernel.create (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6419:21)
      at KernelHost.processRequest (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6191:28)
      at KernelHost.run (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6137:14)
      at /Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6137:45
      at KernelHost.processRequest (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6233:16)
      at KernelHost.run (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6137:14)
      at /Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6137:45
      at KernelHost.processRequest (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6233:16)
      at KernelHost.run (/Users/kyle/.pyenv/versions/3.7.3/envs/python-api-example/lib/python3.7/site-packages/jsii/_embedded/jsii/jsii-runtime.js:6137:14)

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

Traceback (most recent call last):
  File "resources/app.py", line 8, in <module>
    Stack(app, REPO)
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_runtime.py", line 66, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/Users/kyle/projects/python-api-example/resources/stack.py", line 36, in __init__
    self.create()
  File "/Users/kyle/projects/python-api-example/resources/stack.py", line 102, in create
    action_name="Publish-Service", run_order=1, input=deploy_artifact, configuration={}
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_runtime.py", line 66, in __call__
    inst = super().__call__(*args, **kwargs)
  File "/Users/kyle/projects/python-api-example/resources/custom_cdk.py", line 64, in __init__
    jsii.create(ServiceCatalogAction, self, [props])
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_kernel/__init__.py", line 208, in create
    overrides=overrides,
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_kernel/providers/process.py", line 331, in
create
    return self._process.send(request, CreateResponse)
  File "/Users/kyle/.pyenv/versions/python-api-example/lib/python3.7/site-packages/jsii/_kernel/providers/process.py", line 316, in
send
    raise JSIIError(resp.error) from JavaScriptError(resp.stack)
jsii.errors.JSIIError: Missing required properties for @aws-cdk/aws-codepipeline.ActionProperties: artifactBounds,category,provider
Subprocess exited with error 1

Pip list

aws-cdk.assets                      1.5.0
aws-cdk.aws-apigateway              1.5.0
aws-cdk.aws-applicationautoscaling  1.5.0
aws-cdk.aws-autoscaling             1.5.0
aws-cdk.aws-autoscaling-common      1.5.0
aws-cdk.aws-autoscaling-hooktargets 1.5.0
aws-cdk.aws-certificatemanager      1.5.0
aws-cdk.aws-cloudformation          1.5.0
aws-cdk.aws-cloudfront              1.5.0
aws-cdk.aws-cloudwatch              1.5.0
aws-cdk.aws-codebuild               1.5.0
aws-cdk.aws-codecommit              1.5.0
aws-cdk.aws-codedeploy              1.5.0
aws-cdk.aws-codepipeline            1.5.0
aws-cdk.aws-codepipeline-actions    1.5.0
aws-cdk.aws-ec2                     1.5.0
aws-cdk.aws-ecr                     1.5.0
aws-cdk.aws-ecr-assets              1.5.0
aws-cdk.aws-ecs                     1.5.0
aws-cdk.aws-elasticloadbalancing    1.5.0
aws-cdk.aws-elasticloadbalancingv2  1.5.0
aws-cdk.aws-events                  1.5.0
aws-cdk.aws-events-targets          1.5.0
aws-cdk.aws-iam                     1.5.0
aws-cdk.aws-kms                     1.5.0
aws-cdk.aws-lambda                  1.5.0
aws-cdk.aws-logs                    1.5.0
aws-cdk.aws-route53                 1.5.0
aws-cdk.aws-route53-targets         1.5.0
aws-cdk.aws-s3                      1.5.0
aws-cdk.aws-s3-assets               1.5.0
aws-cdk.aws-secretsmanager          1.5.0
aws-cdk.aws-servicediscovery        1.5.0
aws-cdk.aws-sns                     1.5.0
aws-cdk.aws-sns-subscriptions       1.5.0
aws-cdk.aws-sqs                     1.5.0
aws-cdk.aws-ssm                     1.5.0
aws-cdk.aws-stepfunctions           1.5.0
aws-cdk.core                        1.5.0
aws-cdk.custom-resources            1.5.0
aws-cdk.cx-api                      1.5.0
aws-cdk.region-info                 1.5.0
@khornberg khornberg added the needs-triage This issue or PR still needs to be triaged. label Aug 21, 2019
@skinny85 skinny85 self-assigned this Aug 21, 2019
@skinny85
Copy link
Contributor

Thanks for reporting @khornberg . Just wanted to let you know we're working on this. I hope to have an update soon. Thanks for your patience.

@khornberg
Copy link
Author

Very much a hack. I have figured out that I can change the synthesized template from python like so:

application = app.synth()

with open(f"{application.directory}/{repo}.template.json", "r") as f:
    template = json.load(f)
    resources = template["Resources"]
    pipeline = resources[
        [
            resource
            for resource in resources.keys()
            if resource.startswith("Pipeline") and resources[resource]["Type"] == "AWS::CodePipeline::Pipeline"
        ][0]
    ]
    service_catalog_publish = {
        "Name": "ServiceCatalogPublish",
        "Actions": [
            {
                "ActionTypeId": {"Category": "Deploy", "Owner": "AWS", "Provider": "ServiceCatalog", "Version": "1"},
                "Configuration": {
                    "TemplateFilePath": f"{deploy_artifact_path}",
                    "ProductVersionName": f"{pipeline_branch}",
                    "ProductType": "CLOUD_FORMATION_TEMPLATE",
                    "ProductVersionDescription": f"Test service for the {pipeline_branch} branch",
                    "ProductId": {"Ref": "ServiceCatalogProduct"},
                },
                "InputArtifacts": [{"Name": "DeployArtifact"}],
                "Name": "Publish-Test-Service",
                "RunOrder": 1,
            }
        ],
    }

    pipeline["Properties"]["Stages"].append(service_catalog_publish)

with open(f"{application.directory}/{repo}.template.json", "w") as f:
    json.dump(template, f)

@NGL321 NGL321 added bug This issue is a bug. language/python Related to Python bindings @aws-cdk/aws-codepipeline Related to AWS CodePipeline and removed needs-triage This issue or PR still needs to be triaged. labels Oct 8, 2019
@skinny85 skinny85 added the p2 label Oct 31, 2019
@skinny85
Copy link
Contributor

skinny85 commented Sep 5, 2020

@khornberg can you update to the latest CDK version, and see if the original code works now?

Thanks,
Adam

@skinny85 skinny85 added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Sep 5, 2020
@khornberg
Copy link
Author

Thanks for following up on this
I no longer have the original code and shifted focus from what I was using this in

@skinny85
Copy link
Contributor

skinny85 commented Sep 9, 2020

OK. Let us know if you need anything else for this issue from our side.

@skinny85 skinny85 closed this as completed Sep 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-codepipeline Related to AWS CodePipeline bug This issue is a bug. language/python Related to Python bindings p2 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

4 participants