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

Context providers: return dummy values if env is undefined, but emit errors to fail "cdk synth" #227

Merged
merged 12 commits into from
Jul 19, 2018

Conversation

eladb
Copy link
Contributor

@eladb eladb commented Jul 3, 2018

Throwing if "env" is undefined makes it hard to unit test stacks that
use context providers. It requires dummy values for account and region,
which is boilerplate and non-intuitive.

Since we already have a concept of dummy context values, this change
short-circuits context resolution and returns the dummy values in case
the stack's env is undefined.

@eladb eladb requested a review from rix0rrr July 3, 2018 06:19
@@ -69,8 +80,7 @@ export class ContextProvider {
const region = stack.env.region;

if (account == null || region == null) {
// tslint:disable-next-line:max-line-length
throw new Error(`${providerDescription}: requires account and region information, but ${stack.name} doesn't have an "env" defined`);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not quite comfortable with this. How are we still guaranteeing that account and region information are available when invoking a context provider "for reals"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the realz worldz, a stack must be associated with an environment, either explicitly or implicitly. I don't think there's a use case for a stack without an env, is there?

Copy link
Contributor

Choose a reason for hiding this comment

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

As long as you don't use a context provider there's no reason to require it, but we could.

But what's the mechanism that's making sure this is true, once you remove this 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.

Let me get back to you 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@RomainMuller Is there a case where the toolkit invokes a CDK program with an undefined default environment (which is what "undefined env" translates to in the real world)?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't believe there's any case where it does so intentionally (meaning besides those cases when attempts to figure out a default environment failed).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As suggested by @rix0rrr, we decided that what we want is that the toolkit will fail synthesis with a meaningful error, but not through an exception but through error emitted as metadata during synthesis (similar to the warnings we have today). We will also add "info" messages, which will allow construct authors "communicate" information to users.

Throwing if "env" is undefined makes it hard to unit test stacks that
use context providers. It requires dummy values for account and region,
which is boilerplate and non-intuitive.

Since we already have a concept of dummy context values, this change
short-circuits context resolution and returns the dummy values in case
the stack's env is undefined.
Elad Ben-Israel added 10 commits July 19, 2018 11:18
The `bucketUrl` returns the URL of the bucket
and `urlForObject(key)` returns the URL of an
object within the bucket.

Furthermore: `iam.IIdentityResource` was soft-renamed
to `iam.IPrincipal` (IIdentityResource is 
still supported).
Assets represent local files or directories which can be bundled as part
of CDK constructs. During deployment, the toolkit will upload assets
to the "Toolkit Bucket", and use CloudFormation Parameters to reference
the asset in deploy-time.

Assets expose the following deploy-time attributes:

 * s3BucketName
 * s3ObjectKey
 * s3Url

Furthermore, the `asset.grantRead(principal)` will add IAM read permissions
for the asset to the desired principal.
…olved

Instead of throwing an error when context cannot be resolved, we return
dummy values but attach a metadata entry "aws:cdk:error" to the construct
with a message explaining that context cannot be resolved.

The toolkit picks up these metadata entries and will fail synthesis,
unless --ignore-errors is set.

The benefit is that this enables unit test use cases, where users are okay
with dummy contextual information.

INFO messages can also be emitted now using `context.addInfo(message)`.

The metadata keys for info, warning and errors are normalized to use
the "aws:cdk" prefix, and formally defined in cxapi.
@eladb eladb changed the title Context providers: return dummy values if env is undefined Context providers: return dummy values if env is undefined, but emit errors to fail "cdk synth" Jul 19, 2018
}

function printMessage(logFn: (s: string) => void, prefix: string, stackName: string, id: string, entry: cxapi.MetadataEntry) {
logFn(`${prefix}: ${entry.data} (at ${stackName}:${id})`);
Copy link
Contributor

Choose a reason for hiding this comment

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

What does this look like? Maybe better if turned around:

[${prefix} at ${stackName}:${id}] ${entry.data}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Here's how this looks now:

[Error at /app-with-vpc/MyVpc] Cannot determine scope for context provider availability-zones.
This usually happens when AWS credentials are not available and the default account/region cannot be determined.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah that may well be better :) Front-loading the actionable information :P

@eladb eladb merged commit d9e9726 into master Jul 19, 2018
@eladb eladb deleted the benisrae/dummy-context branch July 19, 2018 10:09
@NGL321 NGL321 added the contribution/core This is a PR that came from AWS. label Sep 27, 2019
@lestephane
Copy link

My cdk synth does not fail, despite:

  • The environment being defined
  • The ssm parameter not being present in ssm for that environment

image

From reading this PR summary, this should fail

What am I missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants