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

feat(servicecatalog): Add Product Stack Asset Support #22857

Merged
merged 15 commits into from
Dec 28, 2022

Conversation

wanjacki
Copy link
Contributor

@wanjacki wanjacki commented Nov 9, 2022

Currently Assets are not supported in Product Stacks. Service Catalog has an unique use case where assets need to be shared cross account and sharing the entire CDK asset bucket is not ideal. Users can either create their own ProductStackAssetBucket or have one automatically generated for them based on their account Id and region. By using S3 Deployments we able to copy the assets to that bucket and share it when a portfolio is shared in Service Catalog.

More details can be found here: #20690. Closes #20690

RFC: aws/aws-cdk-rfcs#458

All Submissions:

Adding new Unconventional Dependencies:

  • This PR adds new unconventional dependencies following the process described here

New Features

  • Have you added the new feature to an integration test?
    • [X ] Did you use yarn integ to deploy the infrastructure and generate the snapshot (i.e. yarn integ without --dry-run)?

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

Co-authored-by: Theron Mansilla[imanolympic]

@gitpod-io
Copy link

gitpod-io bot commented Nov 9, 2022

@github-actions github-actions bot added effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p1 labels Nov 9, 2022
@aws-cdk-automation aws-cdk-automation requested a review from a team November 9, 2022 22:19
@github-actions github-actions bot added the repeat-contributor [Pilot] contributed between 3-5 PRs to the CDK label Nov 9, 2022
@wanjacki wanjacki force-pushed the asset_support branch 5 times, most recently from 7c69300 to ffeaf9a Compare November 11, 2022 20:01
@corymhall corymhall marked this pull request as draft November 11, 2022 20:27
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

@wanjacki
Copy link
Contributor Author

@corymhall Hey Cory, sorry can you reopen this PR. Was trying to fix the the integ test build failing (passing locally) and this closed when I tried to rebase

@corymhall corymhall reopened this Nov 11, 2022
@aws-cdk-automation aws-cdk-automation dismissed their stale review November 11, 2022 21:02

✅ Updated pull request passes all PRLinter validations. Dissmissing previous PRLinter review.

Copy link
Contributor

@corymhall corymhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wanjacki sorry for the delay in reviewing this! I wanted to make sure I was
able to test it out myself. Overall this is looking really good! I only have a
couple of minor comments.

packages/@aws-cdk/aws-servicecatalog/README.md Outdated Show resolved Hide resolved
packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts Outdated Show resolved Hide resolved
packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts Outdated Show resolved Hide resolved
}

private physicalNameOfBucket(bucket: IBucket) {
const resolvedName = cdk.Stack.of(bucket).resolve((bucket.node.defaultChild as CfnBucket).bucketName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should just be bucket.bucketName right?

const bucketName = bucket.bucketName;
// if the bucketName is undefined or is a token
if (!bucketName || Token.isUnresolved(bucketName)) {
  throw new Error(...);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bucketName is always a token regardless of if we pass a bucketName or not.
I asked Rico about a solution and he suggested his comment here: #21487 (comment).
Implementing his suggestion we access the underlying CfnBucket and retrieve the bucketName.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh ok. In that case I think you will just have to handle the case where someone passes an IBucket and there is no default child. Maybe

if (Resource.isOwnedResource(bucket)) {
  cdk.Stack.of(bucket).resolve((bucket.node.defaultChild as CfnBucket).bucketName);
} else {
  bucket.bucketName;
}


const physicalName = this.physicalNameOfBucket(this.assetBucket);

(this.boundStack as ProductStack)._addAsset(asset);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like we should manage the logic for _addAsset and _deployAssets
here instead of within ProductStack.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved them both over as suggested.

});

const testAssetBucket = new s3.Bucket(stack, 'TestAssetBucket', {
bucketName: 'product-stack-asset-bucket-12345678-test-region',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bucketName: 'product-stack-asset-bucket-12345678-test-region',
bucketName: `product-stack-asset-bucket-${stack.account}-${stack.region}`,

```
$ cdk destroy --app "node integ.product.js" integ-servicecatalog-product
```
*/

const app = new cdk.App();
const stack = new cdk.Stack(app, 'integ-servicecatalog-product');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const stack = new cdk.Stack(app, 'integ-servicecatalog-product');
const stack = new cdk.Stack(app, 'integ-servicecatalog-product', {
env: {
account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION,
},
});

This allows you to use the actual account+region in the bucket name. The
snapshot will contain the dummy values.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This results in an error that I'm not fully clear on. Are we missing something else?

Error: Resolution error: Resolution error: Resolution error: Resolution error: Cannot use resource 'integ-servicecatalog-product/S3AssetProduct/Custom::CDKBucketDeployment8693BB64968944B69AAFB0CC9EB8756C/ServiceRole' in a cross-environment fashion, the resource's physical name must be explicit set or use `PhysicalName.GENERATE_IF_NEEDED`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm i fixed it somehow.


product.associateTagOptions(tagOptions);
new cdk.CfnOutput(stack, 'PortfolioId', { value: portfolio.portfolioId });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the IntegTest for this test?

new IntegTest(app, 'integ-product', {
  testCases: [stack],
  enableLookups: true,
});

import { ProductStackHistory, ProductStackProps } from '../lib';

/**
* Follow these instructions to manually test provisioning a Product with an Asset with the resources provisioned in this stack:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the instructions!

Comment on lines +235 to +238
Furthermore, in order for a spoke account to provision a product with an asset, the role launching
the product needs permissions to read from the asset bucket.
We recommend you utilize a launch role with permissions to read from the asset bucket.
For example your launch role would need to include at least the following policy:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make the permissions more specific if they are using a launch role?
For example if they provide a launch role via portfolio.setLocalLaunchRoleName() then we could specify that as part of the bucket policy. From my testing it looks like the most specific we can get is something like this:

new iam.PolicyStatement({
	actions: [
		's3:GetObject*',
		's3:GetBucket*',
		's3:List*', ],
	effect: iam.Effect.ALLOW,
	resources: [
		bucket.bucketArn,
		bucket.arnForObjects('*'),
	],
	principals: [
		...this.sharedAccounts.map(account => new iam.ArnPrincipal(cdk.Stack.of(this).formatArn({
			service: 'iam',
			region: '',
			account,
			resource: 'role',
			resourceName: launchRoleName,
		}))),
	],
	conditions: {
		'ForAnyValue:StringEquals': {
			'aws:CalledVia': ['cloudformation.amazonaws.com'],
		},
		'Bool': {
			'aws:ViaAWSService': true,
		},
	},
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean actually adding that PolicyStatement to their launch role. We would have to save the LaunchRole in portfolio when it is set and add it our aspect, so we can propagate the sharedAccounts regardless of the order it is called. There can also be multiple bucket and multiple accounts and other possible complications trying to generate that PolicyStatement. I'm not if it worth the effort or if the customer wants us adding permissions to their launchRole for them.

Or do you mean adding this to the documentation as a recommended policy statement to use for launch role when deploying assets? I think this a good alternative as they can craft a PolicyStatement using that more specific template you provided and easily add it to their LaunchRole if needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No not to the launch role. This would be the policy that we add to the bucket. Rather than allowing read from any principal in the shared accounts, this only allows read from the launch role (if one is specified).

If this isn't going to cover all use cases though then we can leave the bucket policy as is and just add this as an example policy to the docs if users want to scope down the access more.

@corymhall corymhall marked this pull request as ready for review November 29, 2022 19:33
@mergify mergify bot dismissed corymhall’s stale review November 30, 2022 21:38

Pull request has been modified.

@wanjacki
Copy link
Contributor Author

@corymhall Hey Cory thanks for the feedback. I submitted a new commit with all suggested changes. I also updated the integ test to deploy an actual lambda with an asset. Let me know what you think.

mergify bot pushed a commit that referenced this pull request Dec 14, 2022
PR #22857 is introducing a use case where we need to be able to add additional sources after the `BucketDeployment` resource is created.

This PR adds an `addSource` method and changes all the sources evaluation within the construct to be lazy.


----

### All Submissions:

* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Construct Runtime Dependencies:

* [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@mergify mergify bot dismissed corymhall’s stale review December 15, 2022 18:57

Pull request has been modified.

corymhall
corymhall previously approved these changes Dec 16, 2022
Copy link
Contributor

@corymhall corymhall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wanjacki great work on this one! Thanks for being patient with us! 🚀

@mergify
Copy link
Contributor

mergify bot commented Dec 16, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@wanjacki
Copy link
Contributor Author

Hey @corymhall
Is that build failure something I need to fix on our side?

@corymhall
Copy link
Contributor

Is that build failure something I need to fix on our side?

@wanjacki we fixed a bug in the addSource functionality which is changing the snapshot diff. Can you just rerun the integ test? You can just run it with --dry-run.

@mergify mergify bot dismissed corymhall’s stale review December 27, 2022 16:54

Pull request has been modified.

@mergify
Copy link
Contributor

mergify bot commented Dec 28, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 6c76ac3
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit ceaac3a into aws:main Dec 28, 2022
@mergify
Copy link
Contributor

mergify bot commented Dec 28, 2022

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@pgarbe pgarbe mentioned this pull request Jan 4, 2023
11 tasks
brennanho pushed a commit to brennanho/aws-cdk that referenced this pull request Jan 20, 2023
PR aws#22857 is introducing a use case where we need to be able to add additional sources after the `BucketDeployment` resource is created.

This PR adds an `addSource` method and changes all the sources evaluation within the construct to be lazy.


----

### All Submissions:

* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Construct Runtime Dependencies:

* [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
brennanho pushed a commit to brennanho/aws-cdk that referenced this pull request Jan 20, 2023
Currently Assets are not supported in Product Stacks. Service Catalog has an unique use case where assets need to be shared cross account and sharing the entire CDK asset bucket is not ideal. Users can either create their own ProductStackAssetBucket or have one automatically generated for them based on their account Id and region. By using S3 Deployments we able to copy the assets to that bucket and share it when a portfolio is shared in Service Catalog.

More details can be found here: aws#20690. Closes aws#20690

RFC: aws/aws-cdk-rfcs#458
----

### All Submissions:

* [X ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [X] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [X ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
----
Co-authored-by: Theron Mansilla[[imanolympic](https://github.com/imanolympic)]
brennanho pushed a commit to brennanho/aws-cdk that referenced this pull request Feb 22, 2023
PR aws#22857 is introducing a use case where we need to be able to add additional sources after the `BucketDeployment` resource is created.

This PR adds an `addSource` method and changes all the sources evaluation within the construct to be lazy.


----

### All Submissions:

* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Construct Runtime Dependencies:

* [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
brennanho pushed a commit to brennanho/aws-cdk that referenced this pull request Feb 22, 2023
Currently Assets are not supported in Product Stacks. Service Catalog has an unique use case where assets need to be shared cross account and sharing the entire CDK asset bucket is not ideal. Users can either create their own ProductStackAssetBucket or have one automatically generated for them based on their account Id and region. By using S3 Deployments we able to copy the assets to that bucket and share it when a portfolio is shared in Service Catalog.

More details can be found here: aws#20690. Closes aws#20690

RFC: aws/aws-cdk-rfcs#458
----

### All Submissions:

* [X ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [X] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [X] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [X ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)?

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
----
Co-authored-by: Theron Mansilla[[imanolympic](https://github.com/imanolympic)]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p1 repeat-contributor [Pilot] contributed between 3-5 PRs to the CDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(servicecatalog): ProductStack does not support Assets
3 participants