← Blog

A successful deployment is not a working automation

What setting up an employee provisioning workflow taught me about schedules, permissions, and knowing when a system actually works.

Written by
Naresh Kumar
Published
Reading time
4 min
Topic
Tech & AI

The first manual execution completed successfully. The job started, ran its synchronization process, and exited without an error.

That was an important milestone. But it answered only one question: could this job run when I explicitly started it?

The requirement was for it to run without me.

I encountered this distinction while connecting an organization’s identity directory to its password manager. The work included single sign-on and automated employee provisioning. I’m leaving out the organization’s details here because the useful part is the engineering lesson: a deployed job, a scheduled execution, and a completed user workflow each need their own evidence.

The job existed. The schedule still needed work.

The provisioning process ran as a containerized Google Cloud Run job. It used a dedicated service account and accessed a provisioning token through Secret Manager.

Getting to the first successful execution involved several pieces of setup: enabling services, configuring credentials, granting the required access, and making sure the container could run.

Once the manual execution succeeded, I still needed to configure Cloud Scheduler to invoke the job regularly. The deployment path I had used had not created that schedule for me.

This was the gap between having a runnable process and having an unattended workflow. The application could be perfectly capable of doing its work while never being asked to do it again.

I had to verify each boundary

Thinking about the system as a series of independently testable boundaries made the remaining work clearer.

Boundary Question I needed to answer
Deployment Does the job exist with the intended configuration?
Manual execution Can it start and finish in the deployed environment?
Scheduling Is there an enabled trigger for the intended cadence?
Invocation Is the scheduled caller authorized to start the job?
Runtime access Can the running job retrieve its credentials and reach the services it needs?
Application outcome Did the synchronization produce the intended result?

These checks help localize a failure. If no execution appears at the scheduled time, I would investigate the trigger and invocation path before changing the synchronization logic. If an execution starts but cannot retrieve a secret, the schedule has already done its part.

The distinction also matters when reading status messages. A successful request to start work is not, by itself, evidence that the work finished.

Permissions were part of the execution path

One detail that deserved explicit attention was permission to invoke the job. Configuring a schedule did not remove the need to authorize its caller.

The identity that starts a job and the identity under which that job runs have different responsibilities. The scheduled caller needs permission to initiate execution. The runtime identity needs access to whatever the application requires while it is running.

For this setup, I configured authenticated scheduling and the required invocation permission, alongside the runtime’s access to its secret.

Separating those responsibilities gave me a more useful debugging question than “Are the permissions correct?” I could ask which identity was attempting which operation, and inspect that specific boundary.

I waited for evidence from the schedule

After configuring the hourly trigger, I checked the scheduled invocations and the corresponding Cloud Run executions. Four consecutive scheduled runs completed successfully.

That gave me evidence that the unattended path worked repeatedly during the observation period. I was no longer relying only on an execution I had started myself.

Four successful runs do not establish permanent reliability. They do establish something concrete: the configured schedule was triggering the job, and those executions were completing successfully.

That is the level of precision I want in an operational update. It tells someone what has been verified without implying that every possible failure has been eliminated.

A completed job still wasn’t the whole outcome

Employee provisioning adds another layer of verification. A completed synchronization process does not establish that every employee has accepted an invitation, finished activation, or successfully signed in.

I needed to keep infrastructure status and user status separate. Scheduled executions could be working while individual onboarding steps remained open.

At that stage, broader membership reconciliation and invitation completion still needed follow-up. Alerting and ongoing maintenance also remained work to finish. I could accurately report that the scheduled infrastructure was operational without calling the entire rollout complete.

This is easy to lose in a dashboard full of green indicators. Each indicator describes a particular event. The engineering work includes understanding how far that evidence reaches.

What I would build into the next project earlier

I would define the acceptance checks alongside the initial implementation. That would make the schedule, invocation identity, and observation period explicit parts of the deliverable from the beginning.

For a similar workflow, my checklist would be:

  • A manual execution completes in the deployed environment.
  • The intended schedule is enabled, with its timezone recorded.
  • The scheduled caller can invoke the job.
  • Actual scheduled executions appear and complete.
  • The destination reflects the intended changes for a controlled test.
  • Repeated runs do not introduce unintended changes.
  • A named owner knows how to inspect failures, pause the workflow, and resume it.
  • Failure notification and credential maintenance have an explicit plan.

Some of these are checks I completed on this project. Others are requirements I would bring forward earlier next time. Keeping that distinction clear is part of documenting the work honestly.

The question I now carry into automation projects is simple: what evidence will show that this works when I’m no longer there to press Run?

Answering it changes where I put my attention. The deployment matters, and so do the trigger, the permissions between components, the execution history, and the result the person using the system actually needs.