In this tutorial, you will set up CI/CD between Cloud Functions and SourceCraft. To make this work, you will create a repository, set up function deployment, and check the result. The integration between SourceCraft and Yandex Cloud will be implemented using a service connection.
Warning
To create a service connection, you need the Organization owner (organization-manager.organizations.owner) role.
To set up CI/CD for Cloud Functions function deployment from a SourceCraft repository, do the following:
If you no longer need the resources you created, delete them.
Required paid resources
The infrastructure support cost includes fees for function invocation count, computing resources allocated for the function, and outbound traffic (see Cloud Functions pricing).
Create a service account
This service account will be used to create a function and its versions.
The repository will be created from the yc-cloud-functions-template. This repository will store function code examples for different programming languages and frameworks, as well as CI/CD process settings.
In the window that opens, select Blank repository.
Under Your new repository details:
In the Owner field, select the organization in which you created the Yandex Cloud service account.
In the Name field, specify a name for the repository.
The name must be unique within the organization. The name may contain the following ASCII characters: lowercase and uppercase Latin letters, numbers, commas, hyphens, and underscores.
The address to access the repository at is displayed below the name.
Optionally, in the Description field, enter a description for the repository.
Under Repository template, click Browse templates. Select yc-cloud-functions-template and click Use template.
To view the template contents, click Preview.
The template contains:
.sourcecraft/ci.yaml file with a pre-installed configuration of a CI/CD process you can run manually to publish your function to a specific runtime or automatically for the nodejs22 runtime when creating a commit to the repository main branch.
Directories with function code examples for different programming languages and frameworks.
Select the organization where you created the Yandex Cloud service account.
On the organization page, in the Settings section, go to the Service connections section.
Click New service connection.
In the window that opens, do the following:
Under Basic information, give the connection a name, e.g., default-service-connection, and add an optional description.
Under Scope, select the repositories and branches the service connection will be available to, e.g., the repository you created earlier.
Under Yandex Cloud settings, select:
Folder for which you have assigned a role to the service account.
Service account you created earlier.
Tip
To re-request the list of clouds, folders, and service accounts from Yandex Cloud, click Synchronize. This can be of use if alongside creating a service connection you also created a folder or service account.
Click Create service connection.
Wait for the operation to complete. The page that opens will display the service connection details.
A Yandex Identity and Access Management workload identity federation will be automatically created in Yandex Cloud.
To view the parameters of the new OIDC provider, click the federation name under Workload identity federation.
YC_FUNCTION_ENTRYPOINT: Function entry point, e.g., index.handler. Specify it based on your runtime environment as described in this guide.
SOURCE_PATH: Repository path to the function code, e.g., ./nodejs.
You can also add optional parameters:
ENVIRONMENT: Environment variables for the function, e.g., MY_ENV=SOURCECRAFT. This is an equivalent of the --environment parameter in the yc serverless function version create Yandex Cloud CLI command.
Under Commit branch, select Commit directly to the branch: main.
Under After commit action, select Just commit.
Click Commit changes.
After saving the changes, the deploy-nodejs-function workflow will start.
Similarly, you can edit the function code in nodejs/index.js. This will also trigger the workflow for publishing the new function version.
Tip
The example below shows how to automatically start a workflow for the nodejs22 runtime environment. For other runtimes, use manual startup or edit the on section in .sourcecraft/ci.yaml.
To deploy a function from Cloud Functions in CI/CD configuration, use yc-function, a ready-made SourceCraft cube suitable for common use cases.
For more complex Cloud Functions deployment where you need all the Yandex Cloud CLI capabilities, you can use the yc-iam and yc-cli cubes.
Examples of CI/CD configuration with ready-made yc-iam and yc-cli cubes
on:push:-workflows: [cicd]
filter:branches: ["master", "main"]
tokens:# Token name (can be any).<token_name>:service_connection:default-service-connection# Requested access scope:# org: All repositories# repo: Specific repository# ref: Branch or tagscope:repoworkflows:cicd:tasks:-name:deploy-latestenv:SOURCE_PATH:"./nodejs"YC_FUNCTION_NAME:"test-function-nodejs"YC_FUNCTION_RUNTIME:"nodejs22"YC_FUNCTION_ENTRYPOINT:"index.handler"# The cube exchanges the SourceCraft token for the Yandex Cloud IAM token# and saves it to the `IAM_TOKEN` variable within the `outputs` section.cubes:-name:get-iam-tokenenv:ID_TOKEN:${{tokens.<token_name>.id_token}}YC_SA_ID:${{tokens.<token_name>.service_account_id}}image:cr.yandex/sourcecraft/yc-iam:latest# The cube with pre-installed Yandex Cloud CLI retrieves # the `IAM_TOKEN` variable from `outputs` and uses it to check if there is a function from Cloud Functions# with a certain name; if that function does not exist, the cube creates it.-name:check-and-create-functionenv:# Substitute to the `outputs` section the name of the IAM token cube,# e.g., `get-iam-token`.YC_IAM_TOKEN:${{cubes.<IAM_token_cube_name>.outputs.IAM_TOKEN}}YC_FOLDER_ID:${{tokens.<token_name>.folder_id}}image:name:cr.yandex/sourcecraft/yc-cli:latestentrypoint:""script:-|
yc config set folder-id $YC_FOLDER_ID
echo "Checking if function exists..."
if ! yc serverless function get --name=$YC_FUNCTION_NAME; then
echo "Function does not exist. Creating new function..."
yc serverless function create --name=$YC_FUNCTION_NAME
else
echo "Function already exists. Proceeding to version deployment..."
fi
# The cube with pre-installed Yandex Cloud CLI retrieves # the `IAM_TOKEN` variable from `outputs` and uses it to create a new version of the function from Cloud Functions.-name:deploy-function-versionenv:# Substitute to the `outputs` section the name of the IAM token cube,# e.g., `get-iam-token`.YC_IAM_TOKEN:${{cubes.<IAM_token_cube_name>.outputs.IAM_TOKEN}}YC_FOLDER_ID:${{tokens.<token_name>.folder_id}}image:name:cr.yandex/sourcecraft/yc-cli:latestentrypoint:""script:-mkdir-p./tmp-cp"$SOURCE_PATH"/*.js*./tmp-echo"Deploying new function version..."-|
yc config set folder-id $YC_FOLDER_ID
yc serverless function version create \
--function-name=$YC_FUNCTION_NAME \
--runtime $YC_FUNCTION_RUNTIME \
--entrypoint $YC_FUNCTION_ENTRYPOINT \
--execution-timeout 5s \
--source-path ./tmp
On the Home tab, under Your craftspace, navigate to Repositories.
Select the repository you created earlier.
Under Code on the repository page, go to CI/CD.
In the automation executions list, you will see a new execution with the Queued status. Wait for the status to change to Success.
Check that the function was created
Make sure in Cloud Functions there is now a function with the name you specified in .sourcecraft/ci.yaml, e.g., test-function-nodejs.
Management console
CLI
API
In the management console, go to the folder where you previously created the service account.
In the list of services, select Cloud Functions.
The list should now contain test-function-nodejs. Select it.
Under Version history, you should now see the function's version with the same timestamp as the CI/CD process execution.
Navigate to the Editor tab.
In the code editor, index.js should now feature this code:
// Example Node.js function handlerexportconst handler = asyncfunction (event, context) {
// Log the incoming event for debuggingconsole.log('Received event:', event);
// Access request body (if it's a POST request)const requestBody = event.body ? JSON.parse(event.body) : {};
// Access query parametersconst name = event.queryStringParameters ? event.queryStringParameters.name : 'World';
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: `Hello, ${name}! Your request body was:`,
data: requestBody,
}),
};
};
Get a list of functions in the folder specified in .sourcecraft/ci.yaml:
yc serverless function list
Result:
+----------------------+----------------------+----------------------+--------+
| ID | NAME | FOLDER ID | STATUS |
+----------------------+----------------------+----------------------+--------+
| b097d9ous3ge******** | test-function-nodejs | aoek49ghmknn******** | ACTIVE |
+----------------------+----------------------+----------------------+--------+
The command output should now contain the function named test-function-nodejs .
Get a list of versions of the test-function-nodejs function:
yc serverless function version list --function-id <function_ID>
Result:
+----------------------+----------------------+----------+---------------+---------+---------------------+
| ID | FUNCTION ID | RUNTIME | ENTRYPOINT | TAGS | CREATED AT |
+----------------------+----------------------+----------+---------------+---------+---------------------+
| b097d9ousd36******** | b097d9ous3ge******** | nodejs22 | index.handler | $latest | 2025-05-28 05:05:12 |
+----------------------+----------------------+----------+---------------+---------+---------------------+
The command output should now contain the function's version with the same timestamp as the CI/CD process execution.