code: func (p *Provisioner) Apply(
  	o terraform.UIOutput,
  	s *terraform.InstanceState,
  	c *terraform.ResourceConfig) error {
  	var connData, configData *ResourceData
  
  	{
  		// We first need to turn the connection information into a
  		// terraform.ResourceConfig so that we can use that type to more
  		// easily build a ResourceData structure. We do this by simply treating
  		// the conn info as configuration input.
  		raw := make(map[string]interface{})
  		if s != nil {
  			for k, v := range s.Ephemeral.ConnInfo {
  				raw[k] = v
  			}
  		}
  
  		c, err := config.NewRawConfig(raw)
  		if err != nil {
  			return err
  		}
  
  		sm := schemaMap(p.ConnSchema)
  		diff, err := sm.Diff(nil, terraform.NewResourceConfig(c), nil, nil, true)
  		if err != nil {
  			return err
  		}
  		connData, err = sm.Data(nil, diff)
  		if err != nil {
  			return err
  		}
  	}
  
  	{
  		// Build the configuration data. Doing this requires making a "diff"
  		// even though that's never used. We use that just to get the correct types.
  		configMap := schemaMap(p.Schema)
  		diff, err := configMap.Diff(nil, c, nil, nil, true)
  		if err != nil {
  			return err
  		}
  		configData, err = configMap.Data(nil, diff)
  		if err != nil {
  			return err
  		}
  	}
  
  	// Build the context and call the function
  	ctx := p.StopContext()
  	ctx = context.WithValue(ctx, ProvConnDataKey, connData)
  	ctx = context.WithValue(ctx, ProvConfigDataKey, configData)
  	ctx = context.WithValue(ctx, ProvOutputKey, o)
  	ctx = context.WithValue(ctx, ProvRawStateKey, s)
  	return p.ApplyFunc(ctx)
  }
docs: // Apply implementation of terraform.ResourceProvisioner interface.