diff --git a/chalice/package.py b/chalice/package.py index 9f8c17dfa..f88ade91d 100644 --- a/chalice/package.py +++ b/chalice/package.py @@ -570,6 +570,9 @@ def generate(self, resources): 'terraform': { 'required_version': '> 0.11.0' }, + 'provider': { + 'aws': {'version': '> 2.0.0'}, + }, 'data': { 'aws_caller_identity': {'chalice': {}}, 'aws_region': {'chalice': {}} @@ -587,8 +590,8 @@ def _fref(self, lambda_function, attr='arn'): def _arnref(self, arn_template, **kw): # type: (str, str) -> str d = dict( - region='${aws_region.chalice.name}', - account_id='${aws_caller_identity.chalice.account_id}') + region='${data.aws_region.chalice.name}', + account_id='${data.aws_caller_identity.chalice.account_id}') d.update(kw) return arn_template % d @@ -620,17 +623,19 @@ def _generate_s3bucketnotification(self, resource, template): if resource.suffix: bnotify['filter_suffix'] = resource.suffix - template['resource'].setdefault('aws_s3_bucket_notification', {})[ - resource.resource_name] = { - 'bucket': resource.bucket, - 'lambda_function': bnotify - } + # we use the bucket name here because we need to aggregate + # all the notifications subscribers for a bucket. + template['resource'].setdefault( + 'aws_s3_bucket_notification', {}).setdefault( + resource.bucket + '_notify', + {'bucket': resource.bucket}).setdefault( + 'lambda_function', []).append(bnotify) template['resource'].setdefault('aws_lambda_permission', {})[ resource.resource_name] = { 'statement_id': resource.resource_name, 'action': 'lambda:InvokeFunction', - 'function_name': self._fref(resource.lambda_function), + 'function_name': resource.lambda_function.function_name, 'principal': 's3.amazonaws.com', 'source_arn': 'arn:aws:s3:::%s' % resource.bucket } @@ -664,8 +669,7 @@ def _generate_snslambdasubscription(self, resource, template): } template['resource'].setdefault('aws_lambda_permission', {})[ resource.resource_name] = { - 'function_name': self._fref( - resource.lambda_function), + 'function_name': resource.lambda_function.function_name, 'action': 'lambda:InvokeFunction', 'principal': 'sns.amazonaws.com', 'source_arn': topic_arn @@ -691,7 +695,7 @@ def _generate_scheduledevent(self, resource, template): template['resource'].setdefault( 'aws_lambda_permission', {})[ resource.resource_name] = { - 'function_name': self._fref(resource.lambda_function), + 'function_name': resource.lambda_function.function_name, 'action': 'lambda:InvokeFunction', 'principal': 'events.amazonaws.com', 'source_arn': "${aws_cloudwatch_event_rule.%s.arn}" % ( @@ -753,8 +757,21 @@ def _generate_restapi(self, resource, template): # terraform will set them back to empty. 'name': swagger_doc['info']['title'], 'binary_media_types': swagger_doc[ - 'x-amazon-apigateway-binary-media-types'] - } + 'x-amazon-apigateway-binary-media-types'], + 'endpoint_configuration': {'types': [resource.endpoint_type]} + } + + if 'x-amazon-apigateway-policy' in swagger_doc: + template['resource'][ + 'aws_api_gateway_rest_api'][ + resource.resource_name]['policy'] = swagger_doc[ + 'x-amazon-apigateway-policy'] + if resource.minimum_compression.isdigit(): + template['resource'][ + 'aws_api_gateway_rest_api'][ + resource.resource_name][ + 'minimum_compression_size'] = ( + resource.minimum_compression) template['resource'].setdefault('aws_api_gateway_stage', {})[ resource.resource_name] = { @@ -773,7 +790,7 @@ def _generate_restapi(self, resource, template): template['resource'].setdefault('aws_lambda_permission', {})[ resource.resource_name + '_invoke'] = { - 'function_name': self._fref(resource.lambda_function), + 'function_name': resource.lambda_function.function_name, 'action': 'lambda:InvokeFunction', 'principal': 'apigateway.amazonaws.com', 'source_arn': @@ -790,7 +807,7 @@ def _generate_restapi(self, resource, template): for auth in resource.authorizers: template['resource']['aws_lambda_permission'][ auth.resource_name + '_invoke'] = { - 'function_name': self._fref(auth), + 'function_name': auth.function_name, 'action': 'lambda:InvokeFunction', 'principal': 'apigateway.amazonaws.com', 'source_arn': ( diff --git a/docs/source/topics/tf.rst b/docs/source/topics/tf.rst index 332f0d964..144d5b25b 100644 --- a/docs/source/topics/tf.rst +++ b/docs/source/topics/tf.rst @@ -51,10 +51,9 @@ First install the necessary packages:: $ cd test-tf-deploy At this point we've installed chalice and the AWS CLI and we have -a basic app created locally. Next we'll run the ``package`` command -and look at its contents:: +a basic app created locally. Next we'll run the ``package`` command:: - $ $ chalice package --pkg-format terraform /tmp/packaged-app/ + $ chalice package --pkg-format terraform /tmp/packaged-app/ Creating deployment package. $ ls -la /tmp/packaged-app/ -rw-r--r-- 1 j wheel 3355270 May 25 14:20 deployment.zip @@ -67,24 +66,19 @@ and look at its contents:: -------- ------- 9826899 723 files - $ head < /tmp/packaged-app/chalice.tf.json - { - "resource": { - "aws_lambda_function": { - "function_name": "radical-dev-sfn_origin", - "runtime": "python3.7", - As you can see in the above example, the ``package --pkg-format`` command created a directory that contained two files, a ``deployment.zip`` file, which is the Lambda deployment package, and a ``chalice.tf.json`` file, which is the Terraform template that can be deployed using Terraform. Next we're going to use the Terraform CLI -to deploy our app. +to deploy our app. Note terraform will deploy run against all terraform +files in this directory, so we can add additional resources for our +application by adding terraform additional files here. First let's run Terraform init to install the AWS Terraform Provider:: - $ cd /tmp-packaged-app + $ cd /tmp/packaged-app $ terraform init Now we can deploy our app using the ``terraform apply`` command:: @@ -117,7 +111,7 @@ Now we can deploy our app using the ``terraform apply`` command:: This will take a minute to complete, but once it's done, the endpoint url will be available as an output which we can then curl:: - $ http "https://7bnxriulj5.execute-api.us-east-1.amazonaws.com/dev" + $ http "$(terraform output EndpointURL)" HTTP/1.1 200 OK Connection: keep-alive Content-Length: 18