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.

To set up CI/CD:

  1. Create a service account and authorized key.
  2. Create a repository.
  3. Create a secret in your repository.
  4. Push your changes to the repository.
  5. Check the CI/CD process.
  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 and authorized key

SourceCraft will use this service account to create a function and its versions.

Create a service account

  1. In the management console, select Identity and Access Management from the list of services.
  2. Click Create service account.
  3. Enter the service account name: functions-cicd-sa.
  4. Click Add role and select the functions.admin role.
  5. 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 an authorized key

  1. In the management console, select Identity and Access Management from the list of services.
  2. Select the functions-cicd-sa service account.
  3. In the top panel, click Create new key and select Create authorized key.
  4. Select the encryption algorithm.
  5. Click Create.
  6. Click Download file with keys. Make sure the file is saved on the computer. You will need its contents to create a secret. You will not be able to view the public key in the management console.

Run this command:

yc iam key create --service-account-name sa-function -o functions-cicd-sa_key_file.json

If successful, the authorized key data will be written to the functions-cicd-sa_key_file.json file. Here is an example:

{
  "id": "ajek6nubd5g3********",
  "service_account_id": "ajelprpohp7r********",
  "created_at": "2025-05-28T16:17:17.721526532Z",
  "key_algorithm": "RSA_2048",
  "public_key": "-----BEGIN PUBLIC KEY-----\nMI...QAB\n-----END PUBLIC KEY-----\n",
  "private_key": "PLEASE DO NOT REMOVE THIS LINE! Yandex.Cloud SA Key ID \u003cajek6nubd5g3********\u003e\n-----BEGIN PRIVATE KEY-----\nMI...WdQ=\n-----END PRIVATE KEY-----\n"
}

To create an authorized access key, use the create REST API method for the Key resource or the Key/Create gRPC API call.

Create a repository

The repository will store the function parameters and code, and the 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 to create the repository in.

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

Create a secret in the repository

The secret will store the encrypted authorized service account key for access to the function.

  1. Open the SourceCraft home page.

  2. On the Home tab, navigate to Repositories.

  3. Select the repository you created earlier.

  4. Under Repository settings on the repository page, go to Secrets.

  5. On the page with secrets, click New secret.

  6. In the window that opens:

    • In the Name field, name your secret: authorized-key.
    • In the Secret field, paste the authorized key file contents you saved earlier.
  7. Click Add secret.

Push your changes to the repository

Create the following files in the repository:

  • index.js with function code.
  • .sourcecraft/ci.yaml with function parameters and CI/CD settings.
  1. Open the SourceCraft home page.

  2. On the Home tab, navigate to Repositories.

  3. Select the repository you created earlier.

  4. Click Browse all repository files.

  5. To the right of the branch name, click → File.

  6. Enter index.js for the file name and click Create file.

  7. Paste the following code into index.js:

    module.exports.handler = async function (event, context) {
        return {
            statusCode: 200,
            body: 'Hello from SourceCraft!',
        };
    };
    
  8. Repeat these steps to create a file named .sourcecraft/ci.yaml. Paste the code below into it stating the ID of the folder you want to create your function in:

    on:
      push:
        - workflows: cicd
          filter:
            branches: [ main ]
    workflows:
      cicd:
        tasks:
          - name: deploy-latest
            env:
              TMP_PATH: ./tmp
              YC_AUTHORIZED_KEY_JSON: ${{ secrets.<secret_name> }}
              YC_FOLDER_ID: <folder_ID>
              YC_FUNCTION_NAME: cicd-test
              YC_FUNCTION_RUNTIME: nodejs22
              YC_FUNCTION_ENTRYPOINT: index.handler
              YC_FUNCTION_MEMORY: 128m
            cubes:
              - name: install-and-configure-yc
                script:
                  - curl -o ./yc-install.sh -L https://storage.yandexcloud.net/yandexcloud-yc/install.sh
                  - chmod +x ./yc-install.sh && ./yc-install.sh -i /tmp/yc -n && mv /tmp/yc/bin/yc /usr/bin/yc
                  - echo "$YC_AUTHORIZED_KEY_JSON" > key.json
                  - yc config profile create sa-profile
                  - yc config set service-account-key key.json
                  - yc config set format json
                  - yc config set folder-id $YC_FOLDER_ID
    
              - name: check-and-create-function
                script:
                  - |
                    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
    
              - name: deploy-function-version
                script:
                  - mkdir -p $TMP_PATH
                  - cp ./*.js* $TMP_PATH
                  - echo "Deploying new function version..."
                  - |
                    yc serverless function version create \
                      --function-name=$YC_FUNCTION_NAME \
                      --runtime $YC_FUNCTION_RUNTIME \
                      --entrypoint $YC_FUNCTION_ENTRYPOINT \
                      --memory $YC_FUNCTION_MEMORY \
                      --execution-timeout 5s \
                      --source-path $TMP_PATH
    

    Where:

    • YC_FOLDER_ID: ID of the folder to host your function.
    • YC_FUNCTION_NAME: Function name.
    • YC_FUNCTION_RUNTIME: Runtime environment.
    • YC_FUNCTION_ENTRYPOINT: Entry point.
    • YC_FUNCTION_MEMORY: Amount of RAM.
  9. In the top-right corner, click Commit changes.

  10. 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 and back to Read mode.

Check the CI/CD process

Make sure the CI/CD process completes successfully.

  1. Open the SourceCraft home page.
  2. On the Home tab, 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 Cloud Functions now features a function named cicd-test.

  1. In the management console, go to the folder you specified in the .sourcecraft/ci.yaml file.

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

  3. The list should now contain cicd-test. 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:

    module.exports.handler = async function (event, context) {
        return {
            statusCode: 200,
            body: 'Hello from SourceCraft!',
        };
    };
    
  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******** | cicd-test | aoek49ghmknn******** | ACTIVE |
    +----------------------+-----------+----------------------+--------+
    

    The command output should now contain the function named cicd-test.

  2. Get a list of versions of the cicd-test 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 cicd-test 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.