localstack / aws-cdk-local

Thin wrapper script for using the AWS CDK CLI with LocalStack
Apache License 2.0
267 stars 17 forks source link

Cannot create VPC for RDS service: #46

Closed okeeffed closed 3 years ago

okeeffed commented 3 years ago

Issue

Whenever requiring CDK to create a VPC, run into an issue:

botocore.exceptions.ClientError: An error occurred (UnrecognizedClientException) when calling the CreateCloudFormationTemplate operation: The security token included in the request is invalid.

It looks to only occur specifically with VPCs in my issues.

I have managed to work around this so far by using the aws-cli directly to create a local RDS instance or just simply ignoring the VPC/RDS stack during local dev and running a Postgres container. Of course, that does mean that I am not emulating my environment as close as possible locally and in CI/CD.

Construct I am trying to make

This is a basic one I was attempting to narrow things down.

import * as cdk from "@aws-cdk/core";
import * as rds from "@aws-cdk/aws-rds";
import * as ec2 from "@aws-cdk/aws-ec2";
export interface ConstructRdsProps {
  defaultDatabaseName: string;
}
export class ConstructRds extends cdk.Construct {
  public readonly vpc: ec2.Vpc;
  constructor(
    scope: cdk.Construct,
    id: string,
    { defaultDatabaseName }: ConstructRdsProps
  ) {
    super(scope, id);
    // Create the VPC needed for the Aurora DB instance
    const vpc = new ec2.Vpc(this, "RDSVPC");
    const instance = new rds.DatabaseInstance(this, "PostgresRDSInstance", {
      engine: rds.DatabaseInstanceEngine.postgres({
        version: rds.PostgresEngineVersion.VER_12_5,
      }),
      // optional, defaults to m5.large
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.BURSTABLE2,
        ec2.InstanceSize.MICRO
      ),
      vpc,
      vpcSubnets: {
        subnetType: ec2.SubnetType.PUBLIC,
      },
      publiclyAccessible: true,
      databaseName: defaultDatabaseName,
    });
    const myUserSecret = new rds.DatabaseSecret(this, "MyUserSecret", {
      username: "myuser",
      secretName: "my-user-secret", // optional, defaults to a CloudFormation-generated name
      masterSecret: instance.secret,
      excludeCharacters: "{}[]()'\"/\\", // defaults to the set " %+~`#$&*()|[]{}:;<>?!'/@\"\\"
    });
    const myUserSecretAttached = myUserSecret.attach(instance); // Adds DB connections information in the secret
    instance.addRotationMultiUser("MyUser", {
      // Add rotation using the multi user scheme
      secret: myUserSecretAttached,
    });
    new cdk.CfnOutput(this, "Password", {
      value: myUserSecret.secretValue.toString() || "",
    });
    new cdk.CfnOutput(this, "InstanceAddress", {
      value: instance.dbInstanceEndpointAddress,
    });
  }
}

Full stack trace

localstack_1  | 2021-04-19T08:52:58:ERROR:cloudformation_api: Exception on / [POST]
localstack_1  | Traceback (most recent call last):
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
localstack_1  |     response = self.full_dispatch_request()
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
localstack_1  |     rv = self.handle_user_exception(e)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask_cors/extension.py", line 165, in wrapped_function
localstack_1  |     return cors_after_request(app.make_response(f(*args, **kwargs)))
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
localstack_1  |     reraise(exc_type, exc_value, tb)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
localstack_1  |     raise value
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
localstack_1  |     rv = self.dispatch_request()
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
localstack_1  |     return self.view_functions[rule.endpoint](**req.view_args)
localstack_1  |   File "/opt/code/localstack/localstack/services/cloudformation/cloudformation_api.py", line 744, in handle_request
localstack_1  |     result = func(req_params)
localstack_1  |   File "/opt/code/localstack/localstack/services/cloudformation/cloudformation_api.py", line 557, in create_change_set
localstack_1  |     template_deployer.prepare_template_body(req_params)
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 1056, in prepare_template_body
localstack_1  |     return template_preparer.prepare_template_body(req_data)
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudformation/template_preparer.py", line 64, in prepare_template_body
localstack_1  |     modified_template_body = transform_template(req_data)
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudformation/template_preparer.py", line 46, in transform_template
localstack_1  |     transformed = transform_sam(parsed, {}, MockPolicyLoader())
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/translator/transform.py", line 16, in transform
localstack_1  |     return translator.translate(input_fragment, parameter_values=parameter_values, feature_toggle=feature_toggle)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/translator/translator.py", line 104, in translate
localstack_1  |     self.sam_parser.parse(sam_template=sam_template, parameter_values=parameter_values, sam_plugins=sam_plugins)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/parser/parser.py", line 13, in parse
localstack_1  |     sam_plugins.act(LifeCycleEvents.before_transform_template, sam_template)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/__init__.py", line 139, in act
localstack_1  |     raise ex
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/__init__.py", line 133, in act
localstack_1  |     getattr(plugin, method_name)(*args, **kwargs)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/application/serverless_app_plugin.py", line 110, in on_before_transform_template
localstack_1  |     service_call(app_id, semver, key, logical_id)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/application/serverless_app_plugin.py", line 186, in _handle_create_cfn_template_request
localstack_1  |     response = self._sar_service_call(create_cfn_template, logical_id, app_id, semver)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/application/serverless_app_plugin.py", line 365, in _sar_service_call
localstack_1  |     raise e
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/application/serverless_app_plugin.py", line 355, in _sar_service_call
localstack_1  |     response = service_call_lambda(*args)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/samtranslator/plugins/application/serverless_app_plugin.py", line 183, in <lambda>
localstack_1  |     create_cfn_template = lambda app_id, semver: self._sar_client.create_cloud_formation_template(
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/botocore/client.py", line 357, in _api_call
localstack_1  |     return self._make_api_call(operation_name, kwargs)
localstack_1  |   File "/opt/code/localstack/.venv/lib/python3.8/site-packages/botocore/client.py", line 676, in _make_api_call
localstack_1  |     raise error_class(parsed_response, operation_name)
localstack_1  | botocore.exceptions.ClientError: An error occurred (UnrecognizedClientException) when calling the CreateCloudFormationTemplate operation: The security token included in the request is invalid.

Environment

$ env | grep AWS
AWS_VAULT=default
AWS_DEFAULT_REGION=us-west-1
AWS_REGION=us-west-1
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test

$ localstack -v
0.12.9.1

$ docker images   
REPOSITORY                      TAG          IMAGE ID       CREATED        SIZE
localstack/localstack           latest       a3e8ad4dd397   2 days ago     683MB

$ docker image inspect localstack/localstack 
# some code omitted
"LOCALSTACK_BUILD_DATE=2021-04-18",
"LOCALSTACK_BUILD_GIT_HASH=b0a496ac",

Other potentially useful tidbits:

whummer commented 3 years ago

Thanks for reporting @okeeffed . We have pushed a couple of enhancements which should (hopefully) resolve this issue. Can you please pull the latest Docker image and give it another try? Please let us know if the problem persists... Thanks for your help!

okeeffed commented 3 years ago

Thanks @whummer ! Pulled the latest and it looks a lot better!

My stack still failed to build but the error looks as if it might be my CDK setup . It is just before 6am here in Aus so I will play around after work today!

localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Handling "Add" for resource "BasicRDSExampleMyUserSecretAttachmentRotationSchedule8535F0B4" (5/5) type "AWS::SecretsManager::RotationSchedule" in loop iteration 2
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Handling "Add" for resource "BasicRDSExampleRDSVPCPublicSubnet1RouteTableAssociation369E37D6" (1/4) type "AWS::EC2::SubnetRouteTableAssociation" in loop iteration 3
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Running action "create" for resource type "EC2::SubnetRouteTableAssociation" id "BasicRDSExampleRDSVPCPublicSubnet1RouteTableAssociation369E37D6"
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Request for resource type "EC2::SubnetRouteTableAssociation" in region us-west-1: associate_route_table {'RouteTableId': 'rtb-0f85acb2', 'SubnetId': 'subnet-69508d6e'}
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Extract resource attribute: EC2::SubnetRouteTableAssociation PhysicalResourceId
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Dependencies for "BasicRDSExampleRDSVPCPublicSubnet1RouteTableAssociation369E37D6" not yet satisfied, retrying in next loop: Unable to fetch details for resource "BasicRDSExampleRDSVPCPublicSubnet1RouteTableAssociation369E37D6" (attribute "PhysicalResourceId")
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Handling "Add" for resource "BasicRDSExampleRDSVPCPublicSubnet2RouteTableAssociationA663259D" (2/4) type "AWS::EC2::SubnetRouteTableAssociation" in loop iteration 3
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Running action "create" for resource type "EC2::SubnetRouteTableAssociation" id "BasicRDSExampleRDSVPCPublicSubnet2RouteTableAssociationA663259D"
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Request for resource type "EC2::SubnetRouteTableAssociation" in region us-west-1: associate_route_table {'RouteTableId': 'rtb-0f85acb2', 'SubnetId': 'subnet-2970bfa3'}
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Extract resource attribute: EC2::SubnetRouteTableAssociation PhysicalResourceId
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Dependencies for "BasicRDSExampleRDSVPCPublicSubnet2RouteTableAssociationA663259D" not yet satisfied, retrying in next loop: Unable to fetch details for resource "BasicRDSExampleRDSVPCPublicSubnet2RouteTableAssociationA663259D" (attribute "PhysicalResourceId")
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Handling "Add" for resource "BasicRDSExampleRDSVPCPrivateSubnet1RouteTableAssociation1B3E1389" (3/4) type "AWS::EC2::SubnetRouteTableAssociation" in loop iteration 3
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Running action "create" for resource type "EC2::SubnetRouteTableAssociation" id "BasicRDSExampleRDSVPCPrivateSubnet1RouteTableAssociation1B3E1389"
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Request for resource type "EC2::SubnetRouteTableAssociation" in region us-west-1: associate_route_table {'RouteTableId': 'rtb-0f85acb2', 'SubnetId': 'subnet-f20e17c3'}
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Extract resource attribute: EC2::SubnetRouteTableAssociation PhysicalResourceId
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Dependencies for "BasicRDSExampleRDSVPCPrivateSubnet1RouteTableAssociation1B3E1389" not yet satisfied, retrying in next loop: Unable to fetch details for resource "BasicRDSExampleRDSVPCPrivateSubnet1RouteTableAssociation1B3E1389" (attribute "PhysicalResourceId")
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Handling "Add" for resource "BasicRDSExampleRDSVPCPrivateSubnet2RouteTableAssociation949F3915" (4/4) type "AWS::EC2::SubnetRouteTableAssociation" in loop iteration 3
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Running action "create" for resource type "EC2::SubnetRouteTableAssociation" id "BasicRDSExampleRDSVPCPrivateSubnet2RouteTableAssociation949F3915"
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Request for resource type "EC2::SubnetRouteTableAssociation" in region us-west-1: associate_route_table {'RouteTableId': 'rtb-0f85acb2', 'SubnetId': 'subnet-0f8b357b'}
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Extract resource attribute: EC2::SubnetRouteTableAssociation PhysicalResourceId
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Dependencies for "BasicRDSExampleRDSVPCPrivateSubnet2RouteTableAssociation949F3915" not yet satisfied, retrying in next loop: Unable to fetch details for resource "BasicRDSExampleRDSVPCPrivateSubnet2RouteTableAssociation949F3915" (attribute "PhysicalResourceId")
localstack_1  | 2021-04-21T19:54:37:DEBUG:localstack.utils.cloudformation.template_deployer: Error applying changes for CloudFormation stack "InfraStack": Resource deployment loop completed, pending resource changes: [{'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPublicSubnet1RouteTableAssociation369E37D6', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}, {'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPublicSubnet2RouteTableAssociationA663259D', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}, {'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPrivateSubnet1RouteTableAssociation1B3E1389', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}, {'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPrivateSubnet2RouteTableAssociation949F3915', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}] Traceback (most recent call last):
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 1927, in _run
localstack_1  |     self.do_apply_changes_in_loop(changes, stack, stack_name)
localstack_1  |   File "/opt/code/localstack/localstack/utils/cloudformation/template_deployer.py", line 1988, in do_apply_changes_in_loop
localstack_1  |     raise Exception('Resource deployment loop completed, pending resource changes: %s' % changes)
localstack_1  | Exception: Resource deployment loop completed, pending resource changes: [{'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPublicSubnet1RouteTableAssociation369E37D6', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}, {'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPublicSubnet2RouteTableAssociationA663259D', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}, {'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPrivateSubnet1RouteTableAssociation1B3E1389', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}, {'Type': 'Resource', 'ResourceChange': {'Action': 'Add', 'LogicalResourceId': 'BasicRDSExampleRDSVPCPrivateSubnet2RouteTableAssociation949F3915', 'PhysicalResourceId': None, 'ResourceType': 'AWS::EC2::SubnetRouteTableAssociation', 'Replacement': 'False', 'ChangeSetId': None}}]
localstack_1  | 
localstack_1  | 2021-04-21T19:55:23:INFO:postgresql_proxy.proxy: postgresql_1 connection closing ('127.0.0.1', 44972)

Leaving closed giving that I think the reported problem is resolved. Thanks for getting back so fast 🙏