Configure External Automation (Webhook-Based) Approval in your Deployment Config File
Before you begin
You have read the External Automation Overview guide, which explains how webhook-based approval works in CD-as-a-Service.
In order to configure webhook-based approval, you should have the following:
The URL to trigger your external job
Client Credentials (Client ID and Client Secret) with Deployments Full Access permission. You need these to fetch an OATH token to use in the callback that sends the job result to CD-as-a-Service.
Show me how
- Access the CD-as-a-Service Console.
- Go to the Configuration tab.
- If you have more than one tenant, make sure you select the desired tenant in the User context menu.
- In the left navigation menu, select Access Management > Client Credentials.
- In the upper right corner, select New Credential.
- Create a credential for your RNA. Use a descriptive name for the credential that matches what it is being used for. For example, name the credentials the same as the account name you assigned the target deployment cluster if creating a credential for an Remote Network Agent (RNA).
- Select an RBAC role from the Select Roles list. You must assign an RBAC role in order for the credential to access CD-as-a-Service.
- If the credential for is a Remote Network Agent, select Remote Network Agent.
- If you plan to use the credential to deploy from a GitHub Action or similar tool, select Deployments Full Access.
- Note the values for both Client ID and Client Secret. You need these values when configuring the RNA or any other service that you want to grant access to. Make sure to store the secret somewhere safe. You are not shown the value again.
Steps to use webhook-based approval
Create your external job and note the URL to trigger the job
- Your job does not have to be accessible from the internet. CD-as-a-Service can use your Remote Network Agent as a proxy.
- You can send context variables from CD-as-a-Service to your job.
- The job result should be a boolean pass or fail.
Configure the webhook in your deployment config file.
- You define the
callbackUri
that CD-as-a-Service passes in the request to trigger your job. - You can include context variables for CD-as-a-Service to pass to your job.
- You define the
Configure your external job to send the result to CD-as-a-Service.
- Extract the
callbackUri
. - Fetch an OAUTH token from CD-as-a-Service.
- Send the job result to the callback URI, including the OAUTH token.
- Extract the
Create your external job
How you create your job varies from system to system and is beyond the scope of this guide.
A few things to keep in mind:
- You can send send context variables from CD-as-a-Service to your job.
- The result that you send to CD-as-a-Service is a boolean. See the Configure your external job section later in this guide for callback format.
Configure the webhoook in your deployment config file
In your deployment file, you configure your webhook by adding a top-level webhooks
section with the following information:
webhooks:
- name: <webhook-name>
method: <endpoint-method-type>
uriTemplate: <endpoint-uri>
networkMode: <network-mode>
agentIdentifier: <remote-network-agent-id>
headers:
- key: Authorization
value: <auth-type-and-value>
bodyTemplate:
inline: >-
{
}
retryCount: <num-retries>
name
: the unique name of your webhookmethod
: (Required) REST API method type of the webhookuriTemplate
: (Required) webhook URL; supports placeholders that are replaced at runtimenetworkMode
: (Optional; Default:direct
)direct
orremoteNetworkAgent
;direct
means a direct connection to the internet; if your webhook is not internet-accessible, use theremoteNetworkAgent
as a proxy.agentIdentifier
: (Optional) Use whennetworkMode
isremoteNetworkAgent
; the Remote Network Agent identifier to use as a proxy; the identifier must match the Agent Identifier value listed on the Agents UI screen; if not specified, Armory CD-as-a-Service uses the Remote Network Agent associated with the environment account.headers
: (Optional) Request headers; theAuthorization
header is required if your webhook requires authorization. Also supports use ofcontext
andarmory
provided variables.bodyTemplate
: (Optional) the body of the REST API request; the inline content depends on the endpoint you are calling.retryCount
: (Optional; Default: 0) if the first connection attempt fails, the number of retries before failing and declaring that the webhook cannot be reached.disableCallback
: (Optional; Default: false) if set totrue
, Armory CD-as-a-Service does not wait for a callback before moving on to the next deployment step.
Callback URI
You must pass the callback URI as {{armory.callbackUri}}/callback
. Armory CD-as-a-Service generates the value for armory.callbackUri
and fills it in at runtime.
Where you configure the callback URI depends on your external automation tool. If you use a GitHub workflow, for example, you configure the callback URI in the inline
section of the bodyTemplate
.
Webhooks context variables
You can use variables in the webhook templates you define in the webhooks
block of your deployment for the follow fields: webhooks.[].uriTemplate
, webhooks.[].headers
, and webhooks.[].bodyTemplate
.
Armory-provided context variables
Armory provides the following variables for every webhook execution:
Variable | Annotation | Environment variable | Notes |
---|---|---|---|
applicationName | deploy.armory.io/application | ARMORY_APPLICATION_NAME | Added as annotation resources and as environment variables on pods* |
deploymentId | deploy.armory.io/deployment-id | ARMORY_DEPLOYMENT_ID | Added as annotation resources and as environment variables on pods* |
environmentName | deploy.armory.io/environment | ARMORY_ENVIRONMENT_NAME | Added as annotation resources and as environment variables on pods* |
replicaSetName | deploy.armory.io/replica-set-name | ARMORY_REPLICA_SET_NAME | Added as annotation resources and as environment variables on pods* |
accountName | - | - | The name of the account (or agentIdentifier) used to execute the deployment |
namespace | - | - | The namespace resources are being deployed to |
Prefix the variable with armory
and surround with {{}}
. For example, to use applicationName
, add {{armory.applicationName}}
to the webhook query template.
Custom context variables
Add your custom variables to the strategies.<strategyName>.canary.steps.runWebhook.context
section of your deployment file:
strategies:
...
canary:
steps:
...
- runWebhook:
name: <webhookName>
...
context:
<variableName>: <variableValue>
You need to configure your custom variables for each webhook step that references them.
In supported webhook fields, you reference them with the following format: {{context.<variableName>}}
. For example, if you create a variable called uri
for webhooks.[].uriTemplate
, you reference it in webhooks.[].bodyTemplate
with {{context.uri}}
, so that uriTemplate: {{context.uri}}
is the address the webhook calls.
Configuration examples
The first example configures a GitHub webhook that uses token authorization, with the token value configured as a CD-as-a-Service secret. This webhook requires you to pass the callback URI in the request body. The payload also contains context variables that you pass in when invoking the webhook in your deployment file.
|
|
The second example configures a webhook that is not accessible from the internet. The networkMode
is set to remoteNetworkAgent
and the agentIdentifier
specifies which Remote Network Agent to use. The agentIdentifier
value must match the Agent Identifier value listed on the Agents UI screen. The Authorization Bearer value is configured as a CD-as-a-Service secret. Note that in this example, the callback URI is passed in the header.
|
|
Trigger a webhook
You can trigger a webhook from the following areas:
- Deployment constraints:
beforeDeployment
andafterDeployment
- A canary step within a canary strategy
- The
redirectTrafficAfter
section of a blue/green strategy
You add a runWebhooks
section where you want to trigger the webhook.
- runWebhook:
name: <webhook-name>
context:
myCustomKey: myCustomValue
name
: (Required) webhook name; must match the name you gave your webhook in thewebhooks
configuration section.context
: (Optional) dictionary; declare values to use in templates or headers.
Deployment constraints
Before deployment
In this example, you have a webhook named Update-Database-Schema
. You want to trigger this webhook before your app gets deployed. So you trigger the webhook in the beforeDeployment
constraint of your environment deployment.
|
|
App deployment proceeds only if the Update-Database-Schema
callback sends a “success: true” message.
After deployment
In this example, you have a webhook named Run-Integration-Tests
. You want to trigger this webhook after your app has been deployed to staging but before it gets deployed to production. So you trigger the webhook in the afterDeployment
constraint of your staging environment deployment.
|
|
Deployment to production proceeds only if the Run-Integration-Tests
callback sends a “success: true” message.
Blue/Green strategy
In this example, there is a security-scan
webhook that scans your deployed app. You have a blue/green deployment strategy in which you want to run that security scan on the preview version of your app before switching traffic to it. You add the runWebhook
section to the redirectTrafficAfter
section in your blue/green strategy configuration.
|
|
Since tasks in the redirectTrafficAfter
section run in parallel, both tasks in this example must be successful for deployment to continue. If the analysis
task fails, rollback is manual. If the runWebhook
task fails, rollback is automatic.
Canary strategy
In this example, there is a system-health
webhook that you want to trigger as part of your canary strategy. Add the runWebhook
section to your steps
configuration.
|
|
Configure your external job’s callback
After you have configured your webhook in your deployment config file, you should configure the callback in your job.
Extract the callback URI from the HTTP Request that CD-as-a-Service sent to trigger your job. How you do this depends on what external automation tool you use.
Fetch an OAUTH token from CD-as-a-Service.
Replace
<CLIENT-ID>
and<CLIENT-SECRET>
with your values.Request format:
curl --request POST \ --url https://auth.cloud.armory.io/oauth/token \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data data=audience=https://api.cloud.armory.io \ --data grant_type=client_credentials \ --data client_id=<CLIENT-ID> \ --data client_secret=<CLIENT-SECRET>
Example response:
{ "access_token": "<very long access token>", "expires_in": 86400, "token_type": "Bearer" }
Configure the callback
curl --request POST \ --url '<CALLBACK-URI>' \ --header 'Authorization: Bearer <OAUTH_TOKEN>' \ --header 'Content-Type: application/json' \ --data '{"success": <true|false>, "mdMessage": "<MESSAGE>"}'
<CALLBACK-URI>
: Replace with the callback URI you extracted from the HTTP Request that CD-as-a-Service sent to trigger your job.<OAUTH_TOKEN>
: Replace with the OAUTH token you fetched from CD-as-a-Service.data
dictionary job outcome: CD-as-a-Service looks for asuccess
value of true or false to determine the webhook’s success or failure.mdMessage
should contain a user-friendly message for CD-as-a-Service to display in the UI and write to logs.
What’s next
- Tutorial: Deploy a Sample App That Uses GitHub Webhook-Based Approval
- Webhooks section in the deployment config file reference
- Troubleshoot Webhooks
Feedback
Was this page helpful?
Thank you for letting us know!
Sorry to hear that. Please tell us how we can improve.
Last modified October 31, 2023: (f370fe9)