code: def main(stack_name, template, mustache_variables):
      'Update or create stack'
  
      template_data = _parse_template(template, mustache_variables)
      params = {
          'StackName': stack_name,
          'TemplateBody': template_data
      }
  
      try:
          if _stack_exists(stack_name):
              print('Updating {}'.format(stack_name))
              stack_result = cf.update_stack(
                  **params,
                  Capabilities=['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM'])
              waiter = cf.get_waiter('stack_update_complete')
              waiter.wait(StackName=stack_name)
          else:
              print('Creating {}'.format(stack_name))
              stack_result = cf.create_stack(
                  **params,
                  Capabilities=['CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM'])
              try:
                  waiter = cf.get_waiter('stack_create_complete')
                  print("...waiting for stack to be ready...")
                  waiter.wait(StackName=stack_name)
              except Exception as ex:
                  print(ex)
                  print()
                  exit(1)
  
      except botocore.exceptions.ClientError as ex:
          error_message = ex.response['Error']['Message']
          if error_message == 'No updates are to be performed.':
              print("No changes")
          else:
              raise
      else:
          print(json.dumps(
              cf.describe_stacks(StackName=stack_result['StackId']),
              indent=2,
              default=json_serial
          ))
docs: Update or create stack