Enable Overriding of AWS::AccountId psuedo-parameter for local lambda invocation
- Dominant language
- Python
- Stars
- 6.7k
- Forks
- 1.2k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 52
Description
### Describe your idea/feature/enhancement
I'd like to be able to override the `AWS::AccountId` pseudo parameter in `sam local` commands , similar to how the `--region` option overrides the `AWS::Region` pseudo-parameter.
This most common use-case where this would be needed is if you have parameterized ARNs in the `Layers` node of the template ([issue #1736](https://github.com/aws/aws-sam-cli/issues/1736)). However, I have a use-case where even in local development, I may want to do end-to-end testing which interacts with SNS topics, whose ARN's also have the `AWS::AccountId` pseudo-parameter in my template.
At this point, if you depend on this parameter to access deployed resources from the local context, you receive a `403`, because you don't have access to resources from account `123456789012`
### Proposal
1. add `--account-id abcde12345` option in `sam local` commands, possibly like the the `aws_creds_options` (doing it this way would mean adding an `account_id` prop to the Context obj-- not sure if it'd just be preferable to have it be a standalone value accessible through `account_id` in the `cli` method, so as not to modify the existing Context object), and then constructing `InvokeContext` with an additional kwarg `aws_account_id=ctx.account_id`
```
def account_id_option(f):
"""
Configures --account-id option for CLI
:param f: Callback Function to be passed to Click
"""
def callback(ctx, param, value):
state = ctx.ensure_object(Context)
state.account_id = value
return value
return click.option(
"--account-id",
expose_value=False,
help="Select a specific account to associate with your invocation.",
callback=callback,
)(f)
```
2.) Update the `InvokeContext` class, to handle _aws_account_id:
```
@property
def parameter_overrides(self):
# Override certain CloudFormation pseudo-parameters based on values provided by customer
if self._aws_region:
self._parameter_overrides["AWS::Region"] = self._aws_region
if self._aws_account_id:
self._parameter_overrides["AWS::AccountId"] = self._aws_account_id
return self._parameter_overrides
```
3. ) Change `IntrinsicSymbolTable.handle_pseudo_account_id`
from:
```
@staticmethod
def handle_pseudo_account_id():
"""
This gets a default account id from SamBaseProvider.
Return
-------
A pseudo account id
"""
return IntrinsicsSymbolTable.DEFAULT_PSE
```
to (matching the impl of `handle_psuedo_region)`:
```
def handle_pseudo_account_id(self):
"""Gets the accountId from the environment and defaults to a the default accountId from the global variables.
This is only run if it is not specified by the logical_id_translator as a default.
Return
-------
An account id
"""
return (
self.logical_id_translator.get(IntrinsicsSymbolTable.AWS_REGION)
or os.getenv("AWS_ACCOUNT_ID")
or IntrinsicsSymbolTable.DEFAULT_PSEUDO_PARAM_VALUES.get(IntrinsicsSymbolTable.AWS_ACCOUNT_ID)
)
```
Things to consider:
1. Will this require any updates to the [SAM Spec](https://github.com/awslabs/serverless-application-model)
No
### Additional Details
I've tested it out locally and it does work as expected. I'm willing and ready to put together a PR, if this seems like a good plan.
Contributor guide
Assessment
This issue has not been assessed yet.