Imagine: you set up a trigger on Object Storage, the function is written, but when uploading a file you get a 403 Forbidden. Logs are silent. After an hour of debugging, it turns out: the function's service account doesn't have read permission on the bucket. Or, worse, the trigger can't invoke the function due to the missing functions.invoker role. Such errors are the daily bread of a DevOps engineer. Over 10+ years, we've dissected hundreds of similar cases on Yandex Cloud and developed templates that eliminate these problems at the Terraform configuration level. In this article we break down serverless on Yandex Cloud: IAM setup, triggers, cold start management, Lockbox integration, and monitoring – everything you need for production-grade serverless. The main rule: without understanding IAM, any serverless architecture becomes a headache. So let's start with it. According to Yandex Cloud Functions documentation, a service account is mandatory for access to resources. Evaluate your current architecture: what's the call budget, what integrations are needed, what execution time requirements do you have? Contact us – we'll analyze your project and propose optimizations.
Why the function fails: typical IAM errors?
Every function in Yandex Cloud Functions is tied to a service account. This is not optional – without it, the function cannot access Object Storage, Managed PostgreSQL, secrets in Lockbox, or send messages to Message Queue. The most common mistake: the function is created, the trigger is configured, but logs show 403 Forbidden – because the function's service account was forgotten to be assigned the necessary roles.
Minimal Terraform for a function with access to Object Storage:
resource "yandex_function" "handler" {
name = "my-handler"
runtime = "nodejs18"
entrypoint = "index.handler"
memory = 256
execution_timeout = "30"
service_account_id = yandex_iam_service_account.fn_sa.id
content {
zip_filename = "function.zip"
}
environment = {
BUCKET_NAME = yandex_storage_bucket.data.bucket
LOG_LEVEL = "info"
}
}
resource "yandex_function_iam_binding" "invoker" {
function_id = yandex_function.handler.id
role = "functions.functionInvoker"
members = ["serviceAccount:${yandex_iam_service_account.trigger_sa.id}"]
} How to reduce cold start?
Cold start for Node.js functions on YC ranges from 300 ms to 1.5 s depending on package size. If the function handles HTTP requests via API Gateway, this is noticeable. Solutions:
- Minimize the package: don't drag
node_modulesas a whole, useesbuildfor bundling - Set a minimum
min_instances: 1via console (provisioned instances) – but this is paid - For Python use the
python312runtime instead ofpython38– it cold starts faster
Test: a Node.js function with aws-sdk in dependencies weighed 18 MB and started in 1.1 s. After bundling via esbuild – 340 KB, start 180 ms. Yandex Cloud Functions optimization: bundling and provisioned instances reduce compute costs by up to 70%.
| Runtime | Typical cold start (ms) | Recommendation |
|---|---|---|
| Node.js 18 (no bundle) | 800–1500 | Use esbuild |
| Node.js 18 (with bundle) | 150–300 | Optimal for HTTP |
| Python 3.12 | 200–500 | Faster than older versions |
Triggers: Message Queue, Timer, Object Storage
The three most used trigger types: Timer – simplest, runs on cron. Timezone is always UTC, don't forget when setting schedule.
Message Queue trigger – reads messages from Yandex Message Queue in batches (up to 10 messages). The function must return 200, otherwise messages return to the queue. Important: the trigger requires a separate service account with the ymq.reader role on the queue.
Object Storage trigger – fires on create, update, delete events in a bucket. Useful for processing uploaded files (image resizing, CSV parsing). Downside: with mass file uploads, the trigger can create a burst of requests, and if the function is slow, the call queue grows.
resource "yandex_function_trigger" "s3_trigger" {
name = "process-uploads"
object_storage {
bucket_id = yandex_storage_bucket.uploads.id
create = true
suffix = ".csv"
}
function {
id = yandex_function.processor.id
service_account_id = yandex_iam_service_account.trigger_sa.id
}
}Order an audit of your triggers – we'll optimize them for your load.
How to store secrets in Yandex Cloud Functions?
Storing credentials in function environment variables is bad practice. Yandex Lockbox integrates directly with Cloud Functions: the secret is mounted as an env variable at runtime.
secrets {
id = yandex_lockbox_secret.db_password.id
version_id = yandex_lockbox_secret_version.v1.id
key = "DB_PASSWORD"
environment_variable = "DB_PASSWORD"
}The function's service account must have the lockbox.payloadViewer role on that specific secret – not on the entire Lockbox. The cost of storing 100 secrets is less than $1–1 per month.
Monitoring and logs
Function logs go to Cloud Logging. Default retention is 3 days, can be increased to 365. Metrics (invocations, errors, duration) are automatically available in Yandex Monitoring. We set an alert on functions.errors_per_second > 5 – this immediately signals a broken deployment. Contact us for an audit of your project – we'll help set up monitoring and alerts.
Process of work
- Audit: what needs to be launched, which triggers, which integrations (DB, queues, storage)
- IAM design: service accounts, roles, Lockbox for secrets
- Writing Terraform configuration for functions and triggers
- Setting up CI/CD for Yandex Cloud Functions (GitLab CI / GitHub Actions)
- Configuring monitoring and alerts
- Documentation: dependency scheme, description of environment variables, deployment procedure
What's included in the work
- Full documentation of IAM schema and dependencies
- Terraform configurations for functions, triggers, Lockbox
- CI/CD pipeline setup (GitLab CI / GitHub Actions)
- Team training: up to 2 hours online
- Support for 14 days after deployment
How we guarantee quality?
All engineers are Yandex Cloud certified. We follow best practices: every change goes through code review, deployment only via CI/CD, monitoring with alert thresholds. We guarantee that after project handover you will be able to independently deploy new functions using our template.
Typical mistake: 403 Forbidden
If the function cannot access Object Storage, check the service account roles. Add `storage.viewer` or `storage.editor` on the bucket. Use `yandex_function_iam_binding` for the trigger's invoker role.| Task scale | Timeline |
|---|---|
| 1-2 functions with basic triggers | 1 day |
| 5-10 functions with IAM, Lockbox, monitoring | 2-3 days |
| Full serverless backend with API Gateway | from 5 days |
Cost is calculated individually after auditing requirements. Contact us for a project assessment. Get a consultation on seamless function deployment.







