Azure DevOps Pipelines for deploying content to RStudio Connect
Moving from push-button or git-backed deployment to fully customizable programmatic deployment via the RStudio Connect Server API can be a challenging project to undertake.
This article describes the components of a simple template I use for constructing Azure DevOps content deployment pipelines to RStudio Connect:
What are we trying to build?
- Requires RStudio Connect 1.8.6 or higher
- Works with all supported content types on Connect (including Python)
This is how I structure project directories in GitHub to prepare them for RStudio Connect deployment via Azure DevOps:
The template feature on GitHub makes the process of replicating this framework incredibly easy:
Azure DevOps: Start a Project
In Azure DevOps, I’ve created discrete projects for each Connect server I manage content on. This is so I can make use of the global project library to store environment variables that I’ll need across all content items being deployed to each server.
- Establish Global Environment Variables for your Project
- Library > Add Variable Group
All Connect deployments require CONNECT_API_KEY and CONNECT_SERVER to be available for the construction of API requests.
API keys are scoped to the user who created them. This user will be the original owner of the deployed content, but content can be transferred to a different owner at a later time. When managing multiple deployments for a team of content developers, it’s best to use a Connect administrator account. Read: How to create an API Key in Connect
CONNECT_SERVER is the URL for your RStudio Connect server. Your RStudio Connect server URL is the same URL you use to access the RStudio Connect dashboard, minus the connect path. If you access the dashboard at https://rsc.company.com/connect/, the server URL is https://rsc.company.com/.
Once this variable group is established, you can reference it across multiple pipelines, avoiding the need to set CONNECT_API_KEY and CONNECT_SERVER as local variables on a per-pipeline basis:
variables:- group: ‘RStudio Connect Vars’
Additional Variables
In addition to the environment variables, I define three more variables to be used downstream in one or more tasks. These are specific to the content item, so I set them in the pipeline YAML itself:
CONTENT_DIRECTORYthe directory in the GH repo that contains the content bundle (code and manifest file)VANITY_NAMEa custom name to be used for the content vanity URL (may only include alphanumeric characters, hyphens, underscores, and slashes)UNIQ_NAMEa unique name reference for the content item
variables:- group: ‘RStudio Connect Vars’- name: CONTENT_DIRECTORYvalue: app-dir- name: VANITY_NAMEvalue: azure-devops-app- name: APP_NAMEvalue: unique-app-name-test
The additional optional tasks for setting a RunAs User and updating the Access Control List (ACL), also require input variable values that can be defined in the YAML as shown above, or in the Pipeline local variables pane:
I tend to store things like user and group GUIDs as local pipeline variables, but if you’re adding the same users or groups to multiple content items, it might make more sense to store them as project-scoped variables in the Library.
Preview the Pipeline Definition
Tasks Explained
The tasks themselves are shell scripts that execute requests to various RStudio Connect Server API endpoints. The full API documentation from the latest release of Connect can be found here.
create-upload-deploy.sh bundles everything in the content directory and utilizes the UNIQ_NAME to determine whether there is an existing content item on Connect to update, or whether a brand new content item should be created. This is a variant on the example provided with the API Cookbook documentation that creates a new content item regardless of whether an older version already exists — If you would prefer that type of deployment pattern, take a look at the code here.
The best resource to start with if you’re learning to customize the RStudio Connect deployment process is the API Cookbook chapter on Deploying Content.
Each of the optional task steps are broken out into separate scripts so I can easily choose whether or not to include them in the pipeline. These are the most common adjustments that I typically make to content items post-deployment.
runas-user.shuses the/v1/content/{guid}endpoint to update therun_asuser. Therun_asuser is the UNIX user account that executes the content, therefore it only applies to executable content types. An Admin API key is required to update this value.set-vanity-url.shuses the/v1/content/{guid}/vanityendpoint to set a vanity URL for the content item. A Connect server must be explicitly configured to allow Publisher permissions to set vanity URLs, otherwise administrator permissions are required.update-acl.shuses the/v1/content/{guid}/permissionsendpoint to give a pre-defined group of Connect users View access to the content item. There are endless variations on what you might want to do to adjust content access permissions post-deployment. Use the/permissionsendpoint to add specific users or groups as viewers or collaborators. Use the/v1/content/{guild}endpoint to update theaccess_typeas a whole.
Access type describes how this content manages its viewers. The value all is the most permissive; any visitor to RStudio Connect will be able to view this content. The value logged_in indicates that all RStudio Connect accounts may view the content. The acl value allows specifically enumerated users and groups to view the content. Users configured as collaborators may always view content.
Testing the pipeline
If all your variables are defined correctly, you should be able to run the pipeline successfully — check to make sure the content item has been created in the Connect content dashboard and all of your optional post-deployment tasks (vanity URL, access permissions, run_as user, etc.) have been completed correctly.
Finally — Add a status badge to your GitHub README
- In Azure Pipelines, go to the Pipelines page to view the list of pipelines. Select the pipeline you created in the previous section.
- In the context menu for the pipeline, select Status badge.
- Copy the sample Markdown from the status badge panel.
Kelly O’Briant is a Product Manager at RStudio, PBC.

