Configuring CI/CD with Yandex Cloud Functions

In SourceCraft, you can store code of a function from Yandex Cloud Functions and deploy new function versions if there are changes in the repository.

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:

  1. Create a service account.
  2. Create a repository.
  3. Create a service connection.
  4. Edit the CI/CD configuration.
  5. Test CI/CD.
  6. Check the function updates.

If you no longer need the resources you created, delete them.

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.

  1. Log in to the Yandex Cloud management console.
  2. On the left side of the screen, click the line with the name of the folder where you want to deploy a function from Cloud Functions.
  3. In the list of services, select Identity and Access Management.
  4. Click Create service account.
  5. Enter the service account name: functions-cicd-sa.
  6. Click Add role and select the functions.admin role.
  7. Click Create.
  1. Create a service account named functions-cicd-sa:

    yc iam service-account create --name functions-cicd-sa
    

    Result:

    id: ajehb3tcdfa1********
    folder_id: b1g86q4m5vej********
    created_at: "2025-05-28T16:05:14.237381531Z"
    name: functions-cicd-sa
    
  2. Assign the functions.admin role for the folder to the service account:

    yc resource-manager folder add-access-binding <folder_ID> \
      --role functions.admin \
      --subject serviceAccount:<service_account_ID>
    

    Result:

    done (3s)
    effective_deltas:
      - action: ADD
        access_binding:
          role_id: functions.admin
          subject:
            id: ajehb3tcdfa1********
            type: serviceAccount
    

To create a service account, use the create REST API method for the ServiceAccount resource or the ServiceAccountService/Create gRPC API call.

To assign the functions.admin role for a folder to a service account, use the setAccessBindings method for the ServiceAccount resource or the ServiceAccountService/SetAccessBindings gRPC API call.

Create a repository

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.

  1. Open the SourceCraft home page.

  2. In the left-hand panel, click Create repository.

  3. In the window that opens, select Blank repository.

  4. 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.

  5. 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.
  6. Click Create repository.

Create a service connection

  1. Open the SourceCraft home page.

  2. Navigate to the Organizations tab.

  3. Select the organization where you created the Yandex Cloud service account.

  4. On the organization page, in the Settings section, go to the Service connections section.

  5. Click New service connection.

  6. 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.

  7. 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.

Edit the CI/CD configuration

  1. Open the SourceCraft home page.

  2. On the Home tab, under Your craftspace, navigate to Repositories.

  3. Select the repository you created earlier.

  4. Select .sourcecraft/ci.yaml.

  5. In the top-right corner, click Edit.

  6. In the deploy-nodejs-function workflow, edit the parameters of your new function:

    • YC_FUNCTION_NAME: Function name, e.g., test-function-nodejs.
    • YC_FUNCTION_RUNTIME: Runtime environment, e.g., nodejs22.
    • 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:

  7. In the top-right corner, click Commit changes.

  8. Commit:

    1. Enter a message about the changes.
    2. Under Commit branch, select Commit directly to the branch: main.
    3. Under After commit action, select Just commit.
    4. 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.

Automatic startup example for python312
on:
  push:
    - workflows: [deploy-python-function] 
      filter: 
        branches: ["master", "main"]

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 tag
    scope: repo

workflows:
  cicd:
    tasks:
      - name: deploy-latest
        env:
          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-token
            env:
              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-function
            env:
              # 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:latest
              entrypoint: ""
            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-version
            env:
              # 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:latest
              entrypoint: ""
            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

Test CI/CD

  1. Open the SourceCraft home page.
  2. On the Home tab, under Your craftspace, navigate to Repositories.
  3. Select the repository you created earlier.
  4. Under Code on the repository page, go to CI/CD.
  5. 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.

  1. In the management console, go to the folder where you previously created the service account.

  2. In the list of services, select Cloud Functions.

  3. The list should now contain test-function-nodejs. Select it.

  4. Under Version history, you should now see the function's version with the same timestamp as the CI/CD process execution.

  5. Navigate to the Editor tab.

  6. In the code editor, index.js should now feature this code:

    // Example Node.js function handler
        export const handler = async function (event, context) {
            // Log the incoming event for debugging
            console.log('Received event:', event);
    
            // Access request body (if it's a POST request)
            const requestBody = event.body ? JSON.parse(event.body) : {};
    
            // Access query parameters
            const 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,
                }),
            };
        };
    
  1. 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 .

  2. 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.

To get a list of functions, use the list REST API method for the Function resource or the FunctionsService/List gRPC API call.

The list should now feature the test-function-nodejs function.

To get a list of function versions, use the listVersions REST API method for the Function resource or the FunctionsService/ListVersions gRPC API call.

The list should now contain a new version of the function with the same timestamp as the CI/CD process execution.

Delete the resources you created

If you no longer need the resources you created, delete them:

  1. Delete the function.
  2. Delete the service account.

See also