async update() {
    logger.debug('Updating service configuration for dev mode')
    // Makes sure we don't mutate the original IAM configuration
    this.originalIamConfig = _.cloneDeep(this.serverless.service.provider.iam)

    // Makes sure we support the old iam role statements syntax
    const oldIamRoleStatements = _.get(
      this.serverless.service.provider,
      'iamRoleStatements',
      [],
    )

    // Makes sure we support the new iam role statements syntax
    const newIamRoleStatements = _.get(
      this.serverless.service.provider,
      'iam.role.statements',
      [],
    )

    // Makes sure we don't overwrite existing IAM configurations
    const iamRoleStatements = [...oldIamRoleStatements, ...newIamRoleStatements]

    iamRoleStatements.push({
      Effect: 'Allow',
      Action: ['iot:*'],
      Resource: '*',
    })

    _.set(
      this.serverless.service.provider,
      'iam.role.statements',
      iamRoleStatements,
    )

    // The IoT endpoint is fetched and passed to the lambda function as env var to be used by the shim
    const iotEndpoint = await this.getIotEndpoint()
    const serviceName = this.serverless.service.getServiceName()
    const stageName = this.serverless.getProvider('aws').getStage()
    const localRuntimeVersion = process.version.split('.')[0].replace('v', '')
    const localRuntime = `nodejs${localRuntimeVersion}.x`
    let atLeastOneRuntimeVersionMismatch = false

    const allFunctions = this.serverless.service.getAllFunctions()

    const notNodeFunction = allFunctions.find((functionName) => {
      const functionConfig = this.serverless.service.getFunction(functionName)

      const functionRuntime =
        functionConfig.runtime ||
        this.serverless.service.provider.runtime ||
        'nodejs20.x'

      return !functionRuntime.startsWith('nodejs')
    })

    if (notNodeFunction) {
      const notNodeRuntime =
        this.serverless.service.getFunction(notNodeFunction).runtime ||
        this.serverless.service.provider.runtime

      throw new ServerlessError(
        `Dev mode does not yet support the "${notNodeRuntime}" runtime. It currently only supports JavaScript and TypeScript on the Node.js runtime. Please refer to the documentation for more information: https://www.serverless.com/framework/docs/providers/aws/cli-reference/dev`,
        'DEV_MODE_UNSUPPORTED_RUNTIME',
        { stack: false },
      )
    }

    const nodeFunctions = allFunctions.filter((functionName) => {
      const functionConfig = this.serverless.service.getFunction(functionName)

      const functionRuntime =
        functionConfig.runtime ||
        this.serverless.service.provider.runtime ||
        'nodejs20.x'

      if (functionRuntime.startsWith('nodejs')) {
        if (localRuntime !== functionRuntime) {
          atLeastOneRuntimeVersionMismatch = true
        }

        return true
      }

      return false
    })

    // Warn the user if the local runtime version does not match event one function runtime version
    if (atLeastOneRuntimeVersionMismatch) {
      logger.warning(
        `Your local machine is using Node.js v${localRuntimeVersion}, while at least one of your functions is not. Ensure matching runtime versions for accurate testing.`,
      )
    }

    // Update all node functions in the service to use the shim
    nodeFunctions.forEach((functionName) => {
      const functionConfig = this.serverless.service.getFunction(functionName)

      this.originalFunctionConfigs[functionName] = _.cloneDeep(functionConfig)

      // For build plugins we need to make the original handler path available in the functionConfig
      functionConfig.originalHandler = functionConfig.handler

      functionConfig.handler = 'index.handler'
      functionConfig.runtime = 'nodejs20.x'

      functionConfig.environment = functionConfig.environment || {}

      // We need to set the function identifier so the shim knows which function was invoked
      functionConfig.environment.SLS_IOT_ENDPOINT = iotEndpoint
      functionConfig.environment.SLS_SERVICE = serviceName
      functionConfig.environment.SLS_STAGE = stageName
      functionConfig.environment.SLS_FUNCTION = functionName

      // Make sure dev mode also supports the "serverless-iam-roles-per-function" plugin:
      // https://github.com/functionalone/serverless-iam-roles-per-function
      // Issue Ref: https://github.com/serverless/serverless/issues/12619
      if (
        functionConfig.iamRoleStatements &&
        Array.isArray(functionConfig.iamRoleStatements)
      ) {
        const functionIamRoleStatements = functionConfig.iamRoleStatements

        functionIamRoleStatements.push({
          Effect: 'Allow',
          Action: ['iot:*'],
          Resource: '*',
        })
      }
    })

    // Disable observability if it's enabled
    if (
      isDashboardObservabilityEnabled(
        this.serverless.configurationInput,
        this.serverless.getProvider('aws').getStage(),
      )
    ) {
      this.serverless.configurationInput.stages =
        this.serverless.configurationInput.stages || {}

      this.serverless.configurationInput.stages[stageName] = {
        observability: false,
      }
    }
  }
Updates the serverless service configuration with dev mode config needed for the shim to work. Specifically:
  1. Update all AWS Lambda functions' IAM roles to allow all IoT actions.
  2. Update all AWS Lambad function's handler to 'index.handler' as set in the shim
  3. Update all AWS Lambda functions' runtime to 'nodejs20.x' as expected by the shim
  4. Update all AWS Lambda functions' environment variables to include the IoT endpoint and a function identifier.

This method also backs up the original IAM configuration and function configurations to allow for later restoration.

@returns {Promise<void>} A promise that resolves once all configurations have been updated.
@throws {Error} Throws an error if retrieving the IoT endpoint fails.