Skip to content

Commit 4a1d6e9

Browse files
authored
Merge pull request #54 from awslabs/feat/region-from-env-var
now reads AWS_REGION env var if present
2 parents ad52544 + 267730c commit 4a1d6e9

3 files changed

Lines changed: 85 additions & 11 deletions

File tree

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Exits with a non-zero error code if any findings categorized as blocking are fou
7575
| Arguments | Required | Options | Description |
7676
| --------- | -------- | ---------| ----------- |
7777
| --template-path | Yes | FILE_NAME | The path to the CloudFormation template. |
78-
| --region | Yes | REGION | The destination region the resources will be deployed to. |
78+
| --region | | REGION | The destination region the resources will be deployed to. If not specified, defaults to the AWS_REGION or AWS_DEFAULT_REGION environment variable. |
7979
| --parameters | | KEY=VALUE [KEY=VALUE ...] | Keys and values for CloudFormation template parameters. Only parameters that are referenced by IAM policies in the template are required. |
8080
| --template-configuration-file | | FILE_PATH.json | A JSON formatted file that specifies template parameter values. Identical values passed in the --parameters flag override parameters in this file. Supports three formats: the [CodePipeline template configuration file](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15) format (`{"Parameters": {"Key": "Value"}}`), the [CloudFormation parameter file](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy.html) format (`[{"ParameterKey": "Key", "ParameterValue": "Value"}, ...]`), and a simple Key=Value string array (`["Key1=Value1", "Key2=Value2"]`).
8181
| --profile | | PROFILE | The named profile to use for AWS API calls. |
@@ -98,7 +98,7 @@ Parses IAM identity-based and resource-based policies from AWS CloudFormation te
9898
| Arguments | Required | Options | Description |
9999
| --------- | -------- | ---------| ----------- |
100100
| --template-path | Yes | FILE_NAME | The path to the CloudFormation template. |
101-
| --region | Yes | REGION | The destination region the resources will be deployed to. |
101+
| --region | | REGION | The destination region the resources will be deployed to. If not specified, defaults to the AWS_REGION or AWS_DEFAULT_REGION environment variable. |
102102
| --parameters | | KEY=VALUE [KEY=VALUE ...] | Keys and values for CloudFormation template parameters. Only parameters that are referenced by IAM policies in the template are required. |
103103
| --template-configuration-file | | FILE_PATH.json | A JSON formatted file that specifies template parameter values. Identical values passed in the --parameters flag override parameters in this file. Supports three formats: the [CodePipeline template configuration file](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15) format (`{"Parameters": {"Key": "Value"}}`), the [CloudFormation parameter file](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy.html) format (`[{"ParameterKey": "Key", "ParameterValue": "Value"}, ...]`), and a simple Key=Value string array (`["Key1=Value1", "Key2=Value2"]`).
104104
| --profile | | PROFILE | The named profile to use for AWS API calls. |
@@ -120,7 +120,7 @@ Parses IAM identity-based and resource-based policies from AWS CloudFormation te
120120
| Arguments | Required | Options | Description |
121121
| --------- | -------- | ---------| ----------- |
122122
| --template-path | Yes | FILE_NAME | The path to the CloudFormation template. |
123-
| --region | Yes | REGION | The destination region the resources will be deployed to. |
123+
| --region | | REGION | The destination region the resources will be deployed to. If not specified, defaults to the AWS_REGION or AWS_DEFAULT_REGION environment variable. |
124124
| --parameters | | KEY=VALUE [KEY=VALUE ...] | Keys and values for CloudFormation template parameters. Only parameters that are referenced by IAM policies in the template are required. |
125125
| --template-configuration-file | | FILE_PATH.json | A JSON formatted file that specifies template parameter values. Identical values passed in the --parameters flag override parameters in this file. Supports three formats: the [CodePipeline template configuration file](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15) format (`{"Parameters": {"Key": "Value"}}`), the [CloudFormation parameter file](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy.html) format (`[{"ParameterKey": "Key", "ParameterValue": "Value"}, ...]`), and a simple Key=Value string array (`["Key1=Value1", "Key2=Value2"]`).
126126
| --profile | | PROFILE | The named profile to use for AWS API calls. |
@@ -142,7 +142,7 @@ Parses resource-based policies from AWS CloudFormation templates. Then runs the
142142
| Arguments | Required | Options | Description |
143143
| --------- | -------- | ---------| ----------- |
144144
| --template-path | Yes | FILE_NAME | The path to the CloudFormation template. |
145-
| --region | Yes | REGION | The destination region the resources will be deployed to. |
145+
| --region | | REGION | The destination region the resources will be deployed to. If not specified, defaults to the AWS_REGION or AWS_DEFAULT_REGION environment variable. |
146146
| --parameters | | KEY=VALUE [KEY=VALUE ...] | Keys and values for CloudFormation template parameters. Only parameters that are referenced by IAM policies in the template are required. |
147147
| --template-configuration-file | | FILE_PATH.json | A JSON formatted file that specifies template parameter values. Identical values passed in the --parameters flag override parameters in this file. Supports three formats: the [CodePipeline template configuration file](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15) format (`{"Parameters": {"Key": "Value"}}`), the [CloudFormation parameter file](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy.html) format (`[{"ParameterKey": "Key", "ParameterValue": "Value"}, ...]`), and a simple Key=Value string array (`["Key1=Value1", "Key2=Value2"]`).
148148
| --profile | | PROFILE | The named profile to use for AWS API calls. |
@@ -163,7 +163,7 @@ Parses IAM identity-based and resource-based policies from AWS CloudFormation te
163163
| Arguments | Required | Options | Description |
164164
| --------- | -------- | ---------| ----------- |
165165
| --template-path | Yes | FILE_NAME | The path to the CloudFormation template. |
166-
| --region | Yes | REGION | The destination region the resources will be deployed to. |
166+
| --region | | REGION | The destination region the resources will be deployed to. If not specified, defaults to the AWS_REGION or AWS_DEFAULT_REGION environment variable. |
167167
| --parameters | | KEY=VALUE [KEY=VALUE ...] | Keys and values for CloudFormation template parameters. Only parameters that are referenced by IAM policies in the template are required. |
168168
| --template-configuration-file | | FILE_PATH.json | A JSON formatted file that specifies template parameter values. Identical values passed in the --parameters flag override parameters in this file. Supports three formats: the [CodePipeline template configuration file](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-cfn-artifacts.html#w2ab1c21c15c15) format (`{"Parameters": {"Key": "Value"}}`), the [CloudFormation parameter file](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy.html) format (`[{"ParameterKey": "Key", "ParameterValue": "Value"}, ...]`), and a simple Key=Value string array (`["Key1=Value1", "Key2=Value2"]`).
169169
| --profile | | PROFILE | The named profile to use for AWS API calls. |

cfn_policy_validator/main.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""
55
import argparse
66
import logging
7+
import os
78
import sys
89
import traceback
910
from cfn_policy_validator.validation import policy_analysis
@@ -95,6 +96,22 @@ def parse_from_cli(arguments):
9596
exit(0)
9697

9798

99+
def _resolve_region(region_from_cli):
100+
"""
101+
Resolve the region from the CLI argument, or fall back to AWS_DEFAULT_REGION / AWS_REGION environment variables.
102+
"""
103+
if region_from_cli is not None:
104+
return region_from_cli
105+
106+
region = os.environ.get('AWS_REGION') or os.environ.get('AWS_DEFAULT_REGION')
107+
if region is None:
108+
raise ApplicationError(
109+
'No region provided. Specify --region or set the AWS_REGION or AWS_DEFAULT_REGION environment variable.'
110+
)
111+
112+
return validate_region(region)
113+
114+
98115
def main(args=None):
99116
if args is None:
100117
args = sys.argv[1:]
@@ -103,8 +120,10 @@ def main(args=None):
103120
parent_parser.add_argument('--template-path', metavar="TEMPLATE_PATH", dest="template_path", required=True,
104121
help='The path to the CloudFormation template.')
105122

106-
parent_parser.add_argument('--region', dest="region", required=True, type=validate_region,
107-
help="The region the resources will be deployed to.")
123+
parent_parser.add_argument('--region', dest="region", required=False, type=validate_region,
124+
help="The region the resources will be deployed to. "
125+
"Defaults to the AWS_REGION or AWS_DEFAULT_REGION environment variable if not specified.",
126+
default=None)
108127

109128
parent_parser.add_argument('--parameters', action=DictionaryArgument, nargs="+", metavar="KEY=VALUE", dest="parameters",
110129
help='Parameter key and value in the format -p Key1=Value1 Key2=Value2. Only parameters'
@@ -250,6 +269,7 @@ def add_policy_analysis_subparsers():
250269
args = parser.parse_args(args)
251270

252271
try:
272+
args.region = _resolve_region(args.region)
253273
client.set_profile(args.profile)
254274
validate_credentials(args.region)
255275

cfn_policy_validator/tests/test_cli.py

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,61 @@ def test_path_is_required(self):
277277
self.validate_with_expected_error("the following arguments are required: --template-path")
278278

279279
@mock_validation_setup()
280-
def test_region_is_required(self):
280+
def test_region_is_required_when_env_var_not_set(self):
281281
self.args = [
282282
'validate', '--template-path', 'abcdef'
283283
]
284-
self.validate_with_expected_error("the following arguments are required: --region")
284+
with patch.dict(os.environ, {}, clear=True):
285+
with self.assertRaises(SystemExit) as context_manager, captured_output() as (out, err):
286+
main.main(self.args)
287+
self.assertEqual(1, context_manager.exception.code)
288+
self.assertIn("No region provided", err.getvalue())
289+
290+
@mock_validation_setup()
291+
def test_region_falls_back_to_aws_default_region_env_var(self):
292+
json_file_path = os.path.join(this_files_directory, '..', '..', 'test_files/test_file_2.json')
293+
args = [
294+
'validate',
295+
'--template-path', json_file_path,
296+
'--parameters', 'CodestarConnectionArn=fakeArn', 'EnvironmentName=prod',
297+
'--treat-finding-type-as-blocking', 'NONE'
298+
]
299+
with patch.dict(os.environ, {'AWS_DEFAULT_REGION': 'us-west-2'}, clear=False):
300+
with patch.object(main, 'validate_from_cli') as mock:
301+
main.main(args)
302+
mock.assert_called_once()
303+
self.assertEqual(mock.call_args[0][0].region, 'us-west-2')
304+
305+
@mock_validation_setup()
306+
def test_region_falls_back_to_aws_region_env_var(self):
307+
json_file_path = os.path.join(this_files_directory, '..', '..', 'test_files/test_file_2.json')
308+
args = [
309+
'validate',
310+
'--template-path', json_file_path,
311+
'--parameters', 'CodestarConnectionArn=fakeArn', 'EnvironmentName=prod',
312+
'--treat-finding-type-as-blocking', 'NONE'
313+
]
314+
with patch.dict(os.environ, {'AWS_REGION': 'eu-west-1'}, clear=False):
315+
with patch.object(main, 'validate_from_cli') as mock:
316+
main.main(args)
317+
mock.assert_called_once()
318+
self.assertEqual(mock.call_args[0][0].region, 'eu-west-1')
319+
320+
@mock_validation_setup()
321+
def test_region_cli_flag_takes_precedence_over_env_var(self):
322+
json_file_path = os.path.join(this_files_directory, '..', '..', 'test_files/test_file_2.json')
323+
args = [
324+
'validate',
325+
'--template-path', json_file_path,
326+
'--region', 'ap-southeast-1',
327+
'--parameters', 'CodestarConnectionArn=fakeArn', 'EnvironmentName=prod',
328+
'--treat-finding-type-as-blocking', 'NONE'
329+
]
330+
with patch.dict(os.environ, {'AWS_DEFAULT_REGION': 'us-west-2'}, clear=False):
331+
with patch.object(main, 'validate_from_cli') as mock:
332+
main.main(args)
333+
mock.assert_called_once()
334+
self.assertEqual(mock.call_args[0][0].region, 'ap-southeast-1')
285335

286336
@mock_validation_setup()
287337
def test_with_no_parameters(self):
@@ -484,11 +534,15 @@ def test_path_is_required(self):
484534
self.parse_with_expected_error("the following arguments are required: --template-path")
485535

486536
@mock_validation_setup()
487-
def test_region_is_required(self):
537+
def test_region_is_required_when_env_var_not_set(self):
488538
self.args = [
489539
'parse', '--template-path', 'abcdef'
490540
]
491-
self.parse_with_expected_error("the following arguments are required: --region")
541+
with patch.dict(os.environ, {}, clear=True):
542+
with self.assertRaises(SystemExit) as context_manager, captured_output() as (out, err):
543+
main.main(self.args)
544+
self.assertEqual(1, context_manager.exception.code)
545+
self.assertIn("No region provided", err.getvalue())
492546

493547
@mock_validation_setup()
494548
def test_allow_dynamic_ref_without_version_default(self):

0 commit comments

Comments
 (0)