@@ -26,6 +26,7 @@ def __init__(
2626 data_dir : str | None = None ,
2727 s3_bucket : str | None = None ,
2828 s3_key : str = "" ,
29+ assume_read_role : tuple [str , str ] | None = None ,
2930 assume_role : tuple [str , str ] | None = None ,
3031 ):
3132 """Initialize main.
@@ -41,8 +42,10 @@ def __init__(
4142 :param s3_key: if s3_bucket is defined, then all uploaded resources
4243 will be stored under a subkey of s3_key. If not defined the root
4344 of the bucket is used.
45+ :param assume_read_role: tuple containing the two values that are passed
46+ to Session.assume_role() for read-only
4447 :param assume_role: tuple containing the two values that are passed
45- to Session.assume_role()
48+ to Session.assume_role() for deploy
4649 """
4750 super (CFNMain , self ).__init__ (platform_args = False )
4851 self .argument_parser .add_argument (
@@ -132,7 +135,9 @@ def __init__(
132135 self .s3_data_url = None
133136 self .s3_template_key = None
134137 self .s3_template_url = None
138+ self .assume_read_role = assume_read_role
135139 self .assume_role = assume_role
140+ self .aws_env : Session | AWSEnv | None = None
136141
137142 self .timestamp = datetime .utcnow ().strftime ("%Y-%m-%d/%H:%M:%S.%f" )
138143
@@ -191,13 +196,13 @@ def execute_for_stack(self, stack: Stack, aws_env: Session | None = None) -> int
191196 """
192197 assert self .args is not None
193198 try :
194- if self .args .command != "show" :
195- self .start_session (
196- profile = self .args .profile , region = self .args .region , aws_env = aws_env
197- )
199+ self .start_session (
200+ profile = self .args .profile , region = self .args .region , aws_env = aws_env
201+ )
198202
199203 if self .args .command in ("push" , "update" ):
200204 # Synchronize resources to the S3 bucket
205+ assert self .aws_env
201206 s3 = self .aws_env .client ("s3" )
202207 with tempfile .TemporaryDirectory () as tempd :
203208 # Push data associated with CFNMain and then all data
@@ -388,13 +393,27 @@ def start_session(
388393 if aws_env is not None :
389394 self .aws_env = aws_env
390395 else :
391- if self .assume_role :
392- main_session = Session (regions = self .regions , profile = profile )
393- self .aws_env = main_session .assume_role (
394- self .assume_role [0 ], self .assume_role [1 ]
395- )
396- # ??? needed since we still use a global variable for AWSEnv
397- Env ().aws_env = self .aws_env
396+ assert self .args is not None
397+ is_show = self .args .command == "show"
398+ assume_role = self .assume_read_role if is_show else self .assume_role
399+ if assume_role :
400+ try :
401+ main_session = Session (regions = self .regions , profile = profile )
402+ self .aws_env = main_session .assume_role (
403+ assume_role [0 ], assume_role [1 ]
404+ )
405+ # ??? needed since we still use a global variable for AWSEnv
406+ Env ().aws_env = self .aws_env
407+ except botocore .exceptions .NoCredentialsError :
408+ # Don't force assume the role for the show command. The stacks
409+ # that require AWS API calls to generate the template can display
410+ # dummy values
411+ if not is_show :
412+ raise
398413 else :
399414 self .aws_env = AWSEnv (regions = self .regions , profile = profile )
400- self .aws_env .default_region = self .regions [0 ] if region is None else region
415+
416+ if self .aws_env :
417+ self .aws_env .default_region = (
418+ self .regions [0 ] if region is None else region
419+ )
0 commit comments