Serverless: Your serverless.yml has an invalid value with key: "Ref" - dialogflow-es

While installing serverless with following command
sls plugin install -n serverless-alexa-skills --stage dev
I am getting an error like Your serverless.yml has an invalid value with key: "Ref"
The following is my sample serverless.yml file
plugins:
- serverless-webpack
- serverless-s3-sync
- serverless-plugin-git-variables
- serverless-alexa-skills
functions: ${file(./deploy/${opt:stage}.yml):functions}
resources: ${file(./deploy/${opt:stage}.yml):resources}
custom: ${file(./deploy/${opt:stage}.yml):custom}
outputs:
DialogflowFunctionArn:
Value:
Ref:
Got a block here. can some one help me here.

Ref is a Cloudformation intrinsic function. It needs to reference a resource. The whole outputs section is also optional, use it only if you need to reference the resources from one stack in another.

It basically says that Ref: is expecting a value. You have defined it but not assigned any value to it. If there is no use then you should remove this part from your code:
outputs:
DialogflowFunctionArn:
Value:
Ref:

Ref expects to reference something, right now you are not passing it anything to reference.
So, assuming you want the ARN of DialogflowFunction and that function config looks something like this in your functions file:
DialogflowFunction:
description: get the flow
handler: src/functions/dialog-controller.flow
events:
- http:
path: '/dialog/flow'
method: get
cors: true
Then your ref would look something like this:
outputs:
DialogflowFunctionArn:
Value:
Ref: DialogflowFunction
Ref takes the logical id of the resource for which you want to reference, in this case that is DialogflowFunction, and will return the ARN of that resource.

Related

App Insights Connection String reference, give ERROR BCP178, with for loop

I have a bicep that creates apps in for loop.
var App = {
(...)
}
module app 'app:latest' = [for i in range(0, length(App.appServices)): {
name: 'app${i}'
params: {
(...)
}
}]
I want to connect it with app insights.
I found I could use reference to resolve APPLICATIONINSIGHTS_CONNECTION_STRING:
siteConfig: {
linuxFxVersion: 'NODE|14-lts'
appSettings: [
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: reference(resourceId(resourceGroup().name,'Microsoft.insights/components/', 'app1'), '2020-02-02').ConnectionString
}
And unfortunately this throw error:
Error BCP178: This expression is being used in the for-expression, which requires a value that can be calculated at the start of the deployment. You are referencing a variable which cannot be calculated at the start ("App" -> "applicationinsights_connection_string" -> "reference").
INFO: Command ran in 17.855 seconds (init: 0.252, invoke: 17.602)
How do I make it work? How do I force bicep to resolve it first?
Is there another way to link apps created with for loop with application insights?
P.S
code above works fine without for loop for a single app.
Error BCP178: This expression is being used in the for-expression, which requires a value that can be calculated at the start of the deployment.
This error means that referencing value must be given before the loop begins. So, build an array of connection strings outside of the loop and then reference that array within the loop.
create an array of connection strings by using a for loop outside of the module declaration. We then reference this array inside the loop that creates the app modules and assign the appropriate connection string to the params. appInsightsConnectionString property.
var appInsightsConnections = [ for i in range(0, length(app1.appServices)): ```
reference(resourceId(resourceGroup().name,'Microsoft.insights/components/', 'app1'), '2020-02-02').ConnectionString]
Add this in your bicep code:
params: {
(...)
appInsightsConnectionString: appInsightsConnections[i]
}
I made the above changes and ran a sample template taken from MSDoc and was able to deploy it successfully.
Refer this template to connect an app service with application insights.

Azure Bicep - Subresource reference with resourceId()

I am deploying an App Gateway on Azure using a Bicep template (relevant pieces shown below).
var applicationGatewayId = resourceId('Microsoft.Network/applicationGateways', applicationGatewayName)
resource applicationGateway 'Microsoft.Network/applicationGateways#2021-08-01' = {
properties: {
urlPathMaps: [
{
properties: {
defaultBackendAddressPool: {
id: '${applicationGatewayId}/backendAddressPools/backendpool-test'
}
}
]
}
}
My question is about the id of the backendAddressPool in the example. I get a warning when compiling: Warning use-resource-id-functions: If property "id" represents a resource ID, it must use a symbolic resource reference, be a parameter or start with one of these functions: extensionResourceId, guid, if, reference, resourceId, subscription, subscriptionResourceId, tenantResourceId. [https://aka.ms/bicep/linter/use-resource-id-functions].
I tried using ${applicationGateway.id}/backendAddressPools/backendpool-test, but that results in a cyclic reference error. For other resource types I used resourceId(), but for this example I wouldn't know how to.
I tried, e.g., resourceId('Microsoft.Network/ApplicationGatewayBackendAddressPool', '${prefix}-backendpool-infocat'), but that seems to result in a different resource type altogether (doesn't compile into the same id, at least).
This question is applicable to other subresources too, such as:
applicationGateway.urlPathMaps.defaultBackendAddressPool
applicationGateway.urlPathMaps.pathRules.backendAddressPool
applicationGateway.urlPathMaps.pathRules.backendHttpSettings
...
So how does one refer to these subresources properly, when there's no readily defined resourceType to be used in resourceId()? Can the warnings be avoided?
Thanks in advance!
Try this:
id:resourceId('Microsoft.Network/applicationGateways/backendAddressPools', applicationGatewayName, applicationGatewayBackendAddressPoolName)

Rundeck job notification error (server response: 415 Unsupported Media Type)

rundeck ver: 4.0.0
I want to send job execution result to specific webhook url.
So I set job notification use GUI
Trigger: On success
Notification Type: Send Webhook
URL(s): specific incoming webhook url
Payload Format: JSON
Method: POST
Rundeck job notification error is occured. (server response: 415 Unsupported Media Type)
Is there a configuration file that needs to be added other than the job notifications settings?
To send the job execution result you can use the HTTP notification plugin and put an export variable (containing the result) in the body section.
For this, you need to "capture" the output and store it on a global variable to put in the notification, I made a workable example that works with webhooks.site test service:
- defaultTab: nodes
description: ''
executionEnabled: true
id: bcee72e0-b6fa-4e8e-a065-9937a67f3de7
loglevel: INFO
name: HelloWorld
nodeFilterEditable: false
notification:
onsuccess:
plugin:
configuration:
authentication: None
body: ${export.myexport}
contentType: application/json
method: POST
remoteUrl: https://webhook.site/xxxx-xxxx-xxxx-xxxx-xxxx
timeout: '30000'
type: HttpNotification
notifyAvgDurationThreshold: null
options:
- name: opt1
value: localhost
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: nmap ${option.opt1}
plugins:
LogFilter:
- config:
hideOutput: 'false'
logData: 'true'
name: myoutput
regex: (.*)
type: key-value-data-multilines
- description: only for debug
exec: echo ${data.myoutput}
- configuration:
export: myexport
group: export
value: ${data.myoutput*}
nodeStep: false
type: export-var
keepgoing: false
strategy: node-first
uuid: bcee72e0-b6fa-4e8e-a065-9937a67f3de7
Run command and capture the output in a data capture filter, I use the Multiline Regex Data Capture plugin, now the output is saved on a data variable called ${data.myoutput}.
Then using the Global Variable Workflow Step, take the ${data.myoutput} (using the ${data.myoutput*} format) and create the ${export.myexport} variable to use in notifications (just putting the ${export.myexport} variable).
Check the result.

How to get content-encoding from ApiGateway caching resource

We have an endpoint that returns a gzip encoding. We want to cache the value and we are using ApiGateway to do that for us. The resource method is defined as follows,
GetManifestApiGatewayMethod: # very good
Type: "AWS::ApiGateway::Method"
Properties:
AuthorizationType: "NONE"
HttpMethod: "GET"
ResourceId:
Ref: ManifestConfigurationResource
RestApiId:
Ref: ApiGatewayRestApi
RequestParameters:
method.request.path.seasonCode: true
method.request.path.facilityCode: true
method.request.path.configurationCode: true
method.request.querystring.policyCode: true
method.request.header.PAC-Authorization: true
method.request.header.PAC-Application-ID: true
method.request.header.PAC-API-Key: true
method.request.header.PAC-Channel-Code: true
method.request.header.PAC-Organization-ID: true
method.request.header.PAC-Developer-ID: true
method.request.header.PAC-Request-ID: false
method.request.header.Accept-Encoding: true
MethodResponses:
- StatusCode: 200
# ResponseParameters:
# method.response.header.Content-Encoding: true
Integration:
IntegrationHttpMethod: GET
Type: HTTP
Uri: https://${self:provider.environment.PDI_HOST}/pdi/v1/manifest/{seasonCode}/{facilityCode}/{configurationCode}
PassthroughBehavior: WHEN_NO_MATCH
CacheKeyParameters:
- method.request.path.seasonCode
- method.request.path.facilityCode
- method.request.path.configurationCode
- method.request.querystring.policyCode
IntegrationResponses:
- StatusCode: 200
SelectionPattern: '\d\d\d'
# ResponseParameters:
# method.response.header.content-encoding: integration.response.body.headers.content-encoding
RequestParameters:
integration.request.path.seasonCode: method.request.path.seasonCode
integration.request.path.facilityCode: method.request.path.facilityCode
integration.request.path.configurationCode: method.request.path.configurationCode
integration.request.querystring.policyCode: method.request.querystring.policyCode
integration.request.header.Authorization: method.request.header.PAC-Authorization
integration.request.header.PAC-Application-ID: method.request.header.PAC-Application-ID
integration.request.header.PAC-API-Key: method.request.header.PAC-API-Key
integration.request.header.PAC-Channel-Code: method.request.header.PAC-Channel-Code
integration.request.header.PAC-Organization-ID: method.request.header.PAC-Organization-ID
integration.request.header.PAC-Developer-ID: method.request.header.PAC-Developer-ID
integration.request.header.PAC-Request-ID: method.request.header.PAC-Request-ID
integration.request.header.Accept-Encoding: method.request.header.Accept-Encoding
http.get method has the following logic in it:
const encoding = response.headers["content-encoding"];
if (encoding && encoding.indexOf("gzip") >= 0) {...} // handle the gzip
but when we use the integration method above, I am not getting that header that I would normally get from directly hitting the api it proxies to. There is some commented code where I tried to pass that along but Im getting internal server error when those response mappings are used.
From the looks of your code template, the Method response header looks correct.
method.response.header.Content-Encoding: true
However your integration response, ResponseParameters is seems wrong.
method.response.header.content-encoding: integration.response.body.headers.content-encoding
Firstly, the property Key should exactly match, so potentially the capitalisation may be adding to the issue. However, your Value looks to be the real issue. As per the AWS Documentation:
Use the destination as the key and the source as the value:
The destination must be an existing response parameter in the
MethodResponse property.
The source must be an existing method request parameter or a static
value. You must enclose static values in single quotation marks and
pre-encode these values based on the destination specified in the
request.
It looks as if you're trying to map a integration response method to the value instead of a Method Request parameter.

Puppet nested resources create_resources, can't convert string into hash

trying to build a DNS with this module: ref. But getting this error:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, can't convert String into Hash.
I have nested YAML, but not sure if it's correctly formatted or not or problems with something else within my code.
This is my dns profile dns.pp:
class profile::bind {
validate_hash($conf)
$conf = hiera_hash('bind::zone', undef)
create_resources('profile::bind::make::zone', $conf)
}
This is how I define my zone with make_zone.pp:
define profile::bind::make::zone (
$hash_data,
$zone,
$ensure,
$zone_contact,
$zone_ns,
$zone_serial,
$zone_ttl,
$zone_origin,
) {
validate_hash($hash_data)
bind::zone { $zone :
ensure => $ensure,
zone_contact => $zone_contact,
zone_ns => [$zone_ns],
zone_serial => $zone_serial,
zone_ttl => $zone_ttl,
zone_origin => $zone_origin,
}
}
This is my host1.yaml data:
---
version: 5
bind::zone:
zone: test.ltd
ensure: present
zone_contact: 'contact.test.ltd'
zone_ns:
-'ns0.test.ltd'
-'ns1.test.ltd'
zone_serial: '2018010101'
zone_ttl: '767200'
zone_origin: 'test.ltd'
hash_data:
"newyork":
owner: "11.22.33.44"
"tokyo":
owner: "22.33.44.55"
"london":
owner: "33.44.55.66"
bind::cname:
ensure: present
record_type: master
There are a number of mistakes and misunderstandings in the code. I fixed them up so that the code at least compiles and ended up with this.
Changes to profile::bind:
class profile::bind {
include bind
$conf = lookup('bind::zone')
create_resources(profile::bind::make::zone, $conf)
}
Changes to profile::bind::make::zone:
define profile::bind::make::zone (
Enum['present','absent'] $ensure,
String $zone_contact,
Array[String] $zone_ns,
String $zone_serial,
String $zone_ttl,
String $zone_origin,
Hash[String, Hash[String, String]] $hash_data,
) {
bind::zone { $name:
ensure => $ensure,
zone_contact => $zone_contact,
zone_ns => $zone_ns,
zone_serial => $zone_serial,
zone_ttl => $zone_ttl,
zone_origin => $zone_origin,
}
}
Changes to host1.yaml:
---
bind::zone:
'test.ltd':
ensure: present
zone_contact: 'contact.test.ltd'
zone_ns:
- 'ns0.test.ltd'
- 'ns1.test.ltd'
zone_serial: '2018010101'
zone_ttl: '767200'
zone_origin: 'test.ltd'
hash_data:
"newyork":
owner: "11.22.33.44"
"tokyo":
owner: "22.33.44.55"
"london":
owner: "33.44.55.66"
Some explanation:
immediate problem:
Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Function Call, can't convert String into Hash.
This error was caused because your Hiera data was not correctly structured as a Hash[String, Hash[String, String]]. Notice in the yaml I have removed your key "zone" and created a nested Hash there.
must include the bind class
The camptocamp BIND module requires the bind class to also be declared. See its documentation.
validate_hash function is legacy and in the wrong place
As John Bollinger mentioned in the comment, you had the validate_hash on the wrong line. I think that was a cut/paste issue, because you would have got a different error message if that was really your code. Anyway, since you're using Puppet 5 (I guess that by the version => 5 in your Hiera), don't use the legacy validate functions ; use Puppet's data type validation. So I just deleted that line.
use lookup() instead of hiera_hash()
Again, since you're using Puppet 5, use the lookup() function instead of the deprecated hiera_hash() function.
version 5 belongs in hiera.yaml, not host1.yaml
It won't cause you any problems, but the line version: 5 won't do anything here, and it belongs in your hiera.yaml file. I used a hiera.yaml file as follows for testing:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Host 1"
paths:
- host1.yaml
zone_ns type confusion
You had 2 problems with the zone_ns - firstly, a typo in your YAML (no space after the -) ; and secondly, you passed in an Array of zone NS's and then tried to coerce the array to an array in your defined type.
zone parameter should be the name var
Notice I had to delete the $zone parameter in your defined type, and I used the special $name variable instead, to get the name from the title.
refactored to use data type validation
Notice how I used Puppet's data type validation on your inputs in the defined type, and then I had no further need for the legacy validate_hash function and other related validate functions. Read more about that here.
I think that's all. Hope that helps!

Resources