How to show stack trace with aws cdk synth/deploy - aws-cdk

So I'm a cdk and typescipt beginner.
After successfully deploying a couple of stacks I'm not getting the following error with cdk synth: Unexpected token export. Subprocess exited with error 1.
I'm less interested in solving this issue and more interested to where the stack trace is, or any kind of additional info about the error. Doing a --trace or -v does not really provide much helpful info.
Any ideas how I can obtain such information????

What happened behind the scene is that CDK converts to stack into a cloudformation template and saves it into S3 - The S3 bucket created when running cdk bootstrap(More info here).
When you run cdk synth, CDK trying to convert the code ( in your case typescript) into cloudformation stack. this error: Unexpected token export. could be since async call that didn't end, in addition, this error means that your code could not be transferred into cloudformation stack, but it doesn't mean your "cdk" code is broke.
When you run cdk deploy cdk compare the transferred template with the S3 template. And deploy only the diffs.
Update:
Yesterday DevopsStart publish new article about debuuging cdk in vs code.
This might be helpful.
CDK Debugging in VSCode.

I believe the issue is because npx is used to run ts-node under the hood and npx appears to swallow the stack as described here.
One work around is add a try/catch block, e.g.
try {
main()
} catch (e) {
console.log(e)
throw e
}

So I think this is being caused by some javascript (yours or possibly in an imported module) that is using ESM export syntax.
This confused me a little at first because I'm using import/export syntax all over my project however the project is written in typescript which means that it's being compiled to javascript before execution and most likely all of these ESM statements are being emitted in CJS syntax. I however was also using lodash-es because I preferred the import syntax. This module internally uses ESM syntax in javascript and as such this is interpreted directly by the node runtime. Modern versions of node can use ESM syntax however only under specific package configs which mine did not have. My solution was just to remove the offending package however you may be able to go the other direction and configure your package.json such that ESM is enabled in node. This may also require your tsconfig.json to be updated such that the typescript compiler also emits ESM.
https://nodejs.org/api/esm.html

Passing --debug flag helped me.
cdk synth --debug

Related

How to tackle pipeline slow down due to `mypy --install-types`

Problem summary
When running mypy on my code, I keep getting many Library stubs not installed errors.
Few examples below:
/opt/conda/envs/my_ci/lib/python3.9/site-packages/ray/core/generated/agent_manager_pb2.py:5: error: Library stubs not installed for "google.protobuf.internal.enum_type_wrapper" (or incompatible with Python 3.9)
/opt/conda/envs/my_ci/lib/python3.9/site-packages/torch/utils/tensorboard/summary.py:8: error: Library stubs not installed for "six.moves" (or incompatible with Python 3.9)
/opt/conda/envs/my_ci/lib/python3.9/site-packages/ray/rllib/algorithms/algorithm.py:28: error: Library stubs not installed for "pkg_resources" (or incompatible with Python 3.9)
Currently I have to use the command
mypy --install-types --non-interactive my_folder --config-file=mypy.ini.
And although it solves the issue, the problem now is that it takes at least 2 min for installing missing types. This is very long for our CI/CD pipeline.
Question
What are alternative ways of addressing missing library stubs? E.g., such that I could maybe 'split' mypy install types (or other solution that is more time-consuming and potentially can be put as part of docker image), from pure run mypy command (that takes less time and runs as part of gitlab ci/cd pipeline).
I tried running mypy --install-types command first, and then run mypy without success. Could it be that I am doing something wrong?
I will appreciate any help and ideas!

How to determine and change AWS CDK bootstrap version?

I am getting this error:
arn:aws:cloudformation:us-east-1:<account>:stack/cdk-workshop/79cdc290-bb48-11ec-87f4-0a9e17cd1915
current credentials could not be used to assume 'arn:aws:iam::<account>:role/cdk-hnb659fds-lookup-role-<account>-us-east-1', but are for the right account. Proceeding anyway.
(To get rid of this warning, please upgrade to bootstrap version >= 8)
Everything works correctly, but I cannot find any documentation to tell me what bootstrap version I am on or how to change it. I have used npm to update the CDK version and then re-ran bootstrap without succcess.
You can check the AWS Cloudformation stack, and find a stack named "CDKToolkit". The version of the value of the output key name "BootstrapVersion" in the stack. If you can't find the "CDKToolkit" stack or just try to fix the problem quickly. You can exec 'npm bootstrap' under your project. CDK will create/update it for you.

Use Of experiments=no_use_multiple_sdk_containers in Google cloud dataflow

Issue Summary:
Hi,
I am using avro version 1.11.0 for parsing an avro file and decoding it. We have a custom requirement, so i am not able to use ReadFromAvro. When trying this with dataflow there arises a dependency issues as avro-python3 with version 1.82 is already available. The issue is of class TimestampMillisSchema which is not present in avro-python3. It fails stating Attribute TimestampMillisSchema not found in avro.schema. I then tried passing a requirements file with avro==1.11.0 but now the dataflow was not able to start giving error "Error syncing pod" which seems to be because of dependencies conflicts.
To Solve the issue , we set an experiment flag (--experiments=no_use_multiple_sdk_containers ) which ran fine.
I want to know a better solution of my issue and also does the above flag will effect the pipeline performance.
Please try with the dataflow run command:
--prebuild_sdk_container_engine=cloud_build --experiments=use_runner_v2
this would use cloud build to build the container with your extra dependencies and then would use it within the dataflow run.

cdk watch command never returns

I'm following the workshop provided by aws, https://cdkworkshop.com/20-typescript/30-hello-cdk/300-cdk-watch.html.
When I issue
$ cdk watch
After the command is succeeded, it never returns. I can see that the new function is deployed correctly on the aws console. But it seems like it didn't finish normally.
When I issue
$ cdk deploy --hotswap
I get no error. It deploys and returns cleanly.
Anyone knows or experiences the same?
This is the expected behaviour. "watch mode (cdk deploy --watch, or cdk watch for short) continuously monitors your CDK app's source files and assets for changes and immediately performs a deployment of the specified stacks when a change is detected".
Watch mode is a common CLI idiom. Typescript's tsc --watch, works similarly, for instance, continuously compiling to js as you make changes.

Running AWS SAM build from within Python script

I'm in the process of migrating entire CloudFormation stacks to Troposphere, including Lambda and Lambda-reliant CFN Custom Resources.
One of my goals is to circumvent the creation of template files altogether, making the Python code the sole "source of truth" (i.e without template files that are created and therefore can be edited, causing config drift).
This requires the ability to:
Pass a file-like object to the SAM builder (instead of a file-name)
Calling the AWS SAM builder from Python and not the CLI
My first naive idea was that I would be able to import a few modules from aws-sam-cli put a wrapper for io.StringIO around it (to hold the template as file-like object) and presto! Then I looked at the source code for sam build and all hope left me:
I may not be able to use Docker/containers for building, as I it will map the build environment, including template files.
AWS SAM CLI is not designed to have a purely callable set of library functions, similar to boto3. Close, but not quite.
Here is the core of the Python source
with BuildContext(template,
base_dir,
build_dir,
clean=clean,
manifest_path=manifest_path,
use_container=use_container,
parameter_overrides=parameter_overrides,
docker_network=docker_network,
skip_pull_image=skip_pull_image,
mode=mode) as ctx:
builder = ApplicationBuilder(ctx.function_provider,
ctx.build_dir,
ctx.base_dir,
manifest_path_override=ctx.manifest_path_override,
container_manager=ctx.container_manager,
mode=ctx.mode
)
try:
artifacts = builder.build()
modified_template = builder.update_template(ctx.template_dict,
ctx.original_template_path,
artifacts)
move_template(ctx.original_template_path,
ctx.output_template_path,
modified_template)
click.secho("\nBuild Succeeded", fg="green")
msg = gen_success_msg(os.path.relpath(ctx.build_dir),
os.path.relpath(ctx.output_template_path),
os.path.abspath(ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR))
click.secho(msg, fg="yellow")
This relies on a number of imports from a aws-sam-cli internal library with the build focused ones being
from samcli.commands.build.build_context import BuildContext
from samcli.lib.build.app_builder import ApplicationBuilder, BuildError, UnsupportedBuilderLibraryVersionError, ContainerBuildNotSupported
from samcli.lib.build.workflow_config import UnsupportedRuntimeException
It's clear that this means it's not as simple as creating something like a boto3 client and away I go! It looks more like I'd have to fork the whole thing and throw out nearly everything to be left with the build command, context and environment.
Interestingly enough, sam package and sam deploy, according to the docs, are merely aliases for aws cloudformation package and aws cloudformation deploy, meaning those can be used in boto3!
Has somebody possibly already solved this issue? I've googled and searched here, but haven't found anything.
I use PyCharm and the AWS Toolkit which if great for development and debugging and from there I can run SAM builds, but it's "hidden" in the PyCharm plugins - which are written in Kotlin!
My current work-around is to create the CFN templates as temp files and pass them to the CLI commands which are called from Python - an approach I've always disliked.
I may put in a feature request with the aws-sam-cli team and see what they say, unless one of them reads this.
I've managed to launch sam local start-api from a python3 script.
Firstly, pip3 install aws-sam-cli
Then the individual command can be imported and run.
import sys
from samcli.commands.local.start_api.cli import cli
sys.exit(cli())
... provided there's a template.yaml in the current directory.
What I haven't (yet) managed to do is influence the command-line arguments that cli() would receive, so that I could tell it which -t template to use.
Edit
Looking at the way aws-sam-cli integration tests work it seems that they actually kick off a process to run the CLI. So they don't actually pass a parameter to the cli() call at all :-(
For example:
class TestSamPython36HelloWorldIntegration(InvokeIntegBase):
template = Path("template.yml")
def test_invoke_returncode_is_zero(self):
command_list = self.get_command_list(
"HelloWorldServerlessFunction", template_path=self.template_path, event_path=self.event_path
)
process = Popen(command_list, stdout=PIPE)
return_code = process.wait()
self.assertEquals(return_code, 0)
.... etc
from https://github.com/awslabs/aws-sam-cli/blob/a83aa9e620ff679ca740496a3f1ff4872b88894a/tests/integration/local/invoke/test_integrations_cli.py
See also start_api_integ_base.py in the same repo.
I think on the whole this is to be expected because the whole thing is implemented in terms of the click command-line application framework. Unfortunately.
See for example http://click.palletsprojects.com/en/7.x/testing/ which says "The CliRunner.invoke() method runs the command line script in isolation ..." -- my emphasis.
I am using following python script to run sam cli commands. This should work for you too.
import json
import sys
import os
try:
LAMBDA_S3_BUCKET="s3-bucket-name-in-same-region"
AWS_REGION="us-east-1"
API_NAME = "YourAPIName"
BASE_PATH="/path/to/your/project/code/dir"
STACK_NAME="YourCloudFormationStackName"
BUILD_DIR="%s/%s" % (BASE_PATH, "build_artifact")
if not os.path.exists(BUILD_DIR):
os.mkdir(BUILD_DIR)
os.system("cd %s && sam build --template template.yaml --build-dir %s" % (BASE_PATH, BUILD_DIR))
os.system("cd %s && sam package --template-file %s/template.yaml --output-template-file packaged.yaml --s3-bucket %s" %(BASE_PATH, BUILD_DIR, LAMBDA_S3_BUCKET))
os.system("cd %s && sam deploy --template-file packaged.yaml --stack-name %s --capabilities CAPABILITY_IAM --region %s" %(BASE_PATH, STACK_NAME, AWS_REGION))
except Exception as e:
print(e.message)
exit(1)

Resources