Using CloudFormation to configure CloudFront with an S3 origin - aws-cloudformation

I am trying to use CloudFormation for the first time to configure a CloudFront distribution that uses an S3 bucket as its origin.
However I am receiving the error One or more of your origins do not exist when the template is run. I have assumed it is down to the origin DomainName being configured incorrectly, however have not been able to find a configuration that works.
I currently have the following template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"AssetBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "cdn-assets",
"AccessControl": "PublicRead",
"CorsConfiguration": {
"CorsRules": [
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"Id": "OpenCors",
"MaxAge": "3600"
}
]
}
}
},
"AssetCDN": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"Origins": [
{
"DomainName": {
"Fn::GetAtt": [
"AssetBucket",
"DomainName"
]
},
"Id": "AssetBucketOrigin",
"S3OriginConfig": {}
}
],
"Enabled": "true",
"DefaultCacheBehavior": {
"Compress": true,
"AllowedMethods": [
"GET",
"HEAD",
"OPTIONS"
],
"TargetOriginId": "origin-access-identity/cloudfront/AssetCDN",
"ForwardedValues": {
"QueryString": "false",
"Cookies": {
"Forward": "none"
}
},
"ViewerProtocolPolicy": "allow-all"
},
"PriceClass": "PriceClass_All",
"ViewerCertificate": {
"CloudFrontDefaultCertificate": "true"
}
}
},
"DependsOn": [
"AssetBucket"
]
}
}
}
I have not been able to find much advice on this, so hoping someone can point me in the right direction.

Your Cache Behavior's TargetOriginId property must match the value specified in the S3 Origin's Id property.
In your above example, TargetOriginId is origin-access-identity/cloudfront/AssetCDN while Id is AssetBucketOrigin, which is causing the error.

The real issue here is that Cloudfront have a dependency - S3 bucket. And so you should put this reference inside cloudfront object to let CFN know that first of all it should create S3 bucket. To do this you have to change your Origins.Id and DefaultCacheBehavior.TargetOriginId properties to Ref to your bucket config:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"AssetBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "cdn-assets",
"AccessControl": "PublicRead",
"CorsConfiguration": {
"CorsRules": [
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"Id": "OpenCors",
"MaxAge": "3600"
}
]
}
}
},
"AssetCDN": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"Origins": [
{
"DomainName": {
"Fn::GetAtt": [
"AssetBucket",
"DomainName"
]
},
"Id": { "Ref": "AssetBucket" }, /// HERE!!!!
"S3OriginConfig": {}
}
],
"Enabled": "true",
"DefaultCacheBehavior": {
"Compress": true,
"AllowedMethods": [
"GET",
"HEAD",
"OPTIONS"
],
"TargetOriginId": { "Ref": "AssetBucket" }, /// HERE!!!!
"ForwardedValues": {
"QueryString": "false",
"Cookies": {
"Forward": "none"
}
},
"ViewerProtocolPolicy": "allow-all"
},
"PriceClass": "PriceClass_All",
"ViewerCertificate": {
"CloudFrontDefaultCertificate": "true"
}
}
},
"DependsOn": [
"AssetBucket"
]
}
}
}

Related

Update Azure FrontdoorPremium Web Application Firewall Policy by API

I'm trying to update an Frontdoor WAF policy by API following the article in the link below but I'm running into several issues.
-Article seems to be focused on Frontdoor Classic, not premium, so the json in the article doesn't work.
-Adding an empty tags value solves the tags error.
https://learn.microsoft.com/en-us/rest/api/frontdoorservice/webapplicationfirewall/policies/create-or-update?tabs=HTTP#skuname
Can't get anywhere with MS Support, hoping anyone here has experience with this.
HTTP Respons:
{
"errors": {
"sku": [
"Could not find member 'sku' on object of type 'WebApplicationFirewallPatchRequestModel'. Path 'sku', line 1, position 7070."
],
"tags": [
"Required property 'tags' not found in JSON. Path '', line 1, position 7104."
],
"location": [
"Could not find member 'location' on object of type 'WebApplicationFirewallPatchRequestModel'. Path 'location', line 1, position 12."
],
"properties": [
"Could not find member 'properties' on object of type 'WebApplicationFirewallPatchRequestModel'. Path 'properties', line 1, position 35."
]
},
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-1006d4208c3a8e569d9ec0ff3513ca31-cc06e3e858308547-01"
}
Json post (shortend):
{
"location": "global",
"properties": {
"customRules": {
"rules": [
{
"name": "AllowCDN",
"enabledState": "Enabled",
"priority": 110,
"ruleType": "MatchRule",
"rateLimitDurationInMinutes": 1,
"rateLimitThreshold": 100,
"matchConditions": [
{
"matchVariable": "RequestUri",
"selector": null,
"operator": "Contains",
"negateCondition": false,
"matchValue": [
"snip.azureedge.net",
"snip.azureedge.net"
],
"transforms": [
"Lowercase"
]
}
],
"action": "Allow"
}
]
},
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "Microsoft_DefaultRuleSet",
"ruleSetVersion": "2.1",
"ruleSetAction": "Block",
"ruleGroupOverrides": [],
"exclusions": []
},
{
"ruleSetType": "Microsoft_BotManagerRuleSet",
"ruleSetVersion": "1.0",
"ruleSetAction": null,
"ruleGroupOverrides": [
{
"ruleGroupName": "GoodBots",
"rules": [
{
"ruleId": "Bot200200",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
}
],
"exclusions": []
},
{
"ruleGroupName": "UnknownBots",
"rules": [
{
"ruleId": "Bot300200",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
},
{
"ruleId": "Bot300600",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
},
{
"ruleId": "Bot300700",
"enabledState": "Enabled",
"action": "Log",
"exclusions": []
},
{
"ruleId": "Bot300400",
"enabledState": "Enabled",
"action": "Log",
"exclusions": []
},
{
"ruleId": "Bot300300",
"enabledState": "Enabled",
"action": "Block",
"exclusions": []
}
],
"exclusions": []
}
],
"exclusions": []
}
]
},
"policySettings": {
"enabledState": "Enabled",
"mode": "Prevention",
"redirectUrl": null,
"customBlockResponseStatusCode": null,
"customBlockResponseBody": null,
"requestBodyCheck": "Enabled"
}
},
"sku": {
"name": "Premium_AzureFrontDoor"
}
}
Updating an existing Frontdoor Premium WAF policy doesn't work.
I was able to execute the Update REST API above though for my Azure Front Door Standard. The process I followed was to make the GET REST API Call first and then copy the response body and then make the updates required in the JSON and use this JSON as a request Body in the Update REST API. The reference JSON below worked for me.
{
"id": "/subscriptions/xxxxx/resourcegroups/xxxxx/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/xxxxx",
"type": "Microsoft.Network/frontdoorwebapplicationfirewallpolicies",
"name": "xxxxx",
"location": "Global",
"tags": {
"Reason": "Repro",
"CreatedDate": "12/29/2022 2:40:29 AM",
"CreatedBy": "xxxxx",
"OwningTeam": "xxxxx"
},
"sku": {
"name": "Standard_AzureFrontDoor"
},
"properties": {
"policySettings": {
"enabledState": "Enabled",
"mode": "Detection",
"redirectUrl": null,
"customBlockResponseStatusCode": 403,
"customBlockResponseBody": null,
"requestBodyCheck": "Disabled"
},
"customRules": {
"rules": [
{
"name": "testcustomrule",
"enabledState": "Enabled",
"priority": 100,
"ruleType": "MatchRule",
"rateLimitDurationInMinutes": 1,
"rateLimitThreshold": 100,
"matchConditions": [
{
"matchVariable": "SocketAddr",
"selector": null,
"operator": "GeoMatch",
"negateCondition": false,
"matchValue": [
"UY"
],
"transforms": []
}
],
"action": "Block"
},
{
"name": "testcustomrule2",
"enabledState": "Enabled",
"priority": 101,
"ruleType": "MatchRule",
"rateLimitDurationInMinutes": 1,
"rateLimitThreshold": 100,
"matchConditions": [
{
"matchVariable": "SocketAddr",
"selector": null,
"operator": "GeoMatch",
"negateCondition": false,
"matchValue": [
"AU"
],
"transforms": []
}
],
"action": "Block"
}
]
},
"managedRules": {
"managedRuleSets": []
},
"frontendEndpointLinks": [],
"securityPolicyLinks": [
{
"id": "/subscriptions/xxxxx/resourcegroups/xxxxx/providers/Microsoft.Cdn/profiles/xxxxx/securitypolicies/xxxxx"
}
],
"routingRuleLinks": [],
"resourceState": "Enabled",
"provisioningState": "Succeeded"
}
}

Azure Front Door - multiple frontends IDs as a parameter (array) to routing rule?

Commonly, when there are multiple frontends IDs assigned to routing rule, they are described like this:
...
"routingRules": [
{
"name": "routingRule1",
"properties": {
"frontendEndpoints": [
{
"id": "[resourceId('Microsoft.Network/frontDoors/frontendEndpoints', parameters('frontDoorName'), 'frontendEndpoint')]"
},
{
"id": "[resourceId('Microsoft.Network/frontDoors/frontendEndpoints', parameters('frontDoorName'), 'frontendEndpoint2')]"
}
],
...
In my case I'd like to do this as a parameter type "array", but I receive error. Please see below my template, parameter file, and error message
this is front door ARM parameters deployment file
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"frontdoor_name": {
"value": "frontdoortest"
},
"frontends_all": {
"value": [
{
"name": "fe1",
"properties": {
"hostName": "frontdoortest.azurefd.net",
"sessionAffinityEnabledState": "Disabled",
"sessionAffinityTtlSeconds": 0,
"resourceState": "Enabled"
}
},
{
"name": "fe1customdns1",
"properties": {
"hostName": "dev.custom1.com",
"sessionAffinityEnabledState": "Enabled",
"sessionAffinityTtlSeconds": 0,
"resourceState": "Enabled"
}
},
{
"name": "fe1customdns2",
"properties": {
"hostName": "dev.custom2.com",
"sessionAffinityEnabledState": "Enabled",
"sessionAffinityTtlSeconds": 0,
"resourceState": "Enabled"
}
}
]
},
"frontends_one": {
"value": [
{
"id": "[concat(resourceId('Microsoft.Network/frontdoors', parameters('frontdoor_name')), '/FrontendEndpoints/fe1customdns1')]",
},
{
"id": "[concat(resourceId('Microsoft.Network/frontdoors', parameters('frontdoor_name')), '/FrontendEndpoints/fe1customdns2')]",
}
]
}
}
this is part of front door ARM resource deployment template
...
"parameters": {
"frontends_all": {
"type": "array"
},
"frontends_one": {
"type": "array"
},
"frontdoor_name": {
"type": "string"
}
}
...
{
"type": "Microsoft.Network/frontDoors",
"apiVersion": "2020-01-01",
"name": "[parameters('frontdoor_name')]",
"location": "Global",
"properties": {
"resourceState": "Enabled",
"frontendEndpoints": "[parameters('frontends_all')]", #### NO ERROR
"routingRules": [
{
"name": "routingRule1",
"properties": {
"frontendEndpoints": "[parameters('frontends_one')]", #### ERROR !!!
"acceptedProtocols": [
"Https"
],
"patternsToMatch": [
"/*",
],
"enabledState": "Enabled",
"resourceState": "Enabled",
"routeConfiguration": {
"#odata.type": "#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration",
"forwardingProtocol": "MatchRequest",
"backendPool": {
"id": "[concat(resourceId('Microsoft.Network/frontdoors', parameters('frontdoor_name')), '/backendpools/test')]"
}
}
}
}
...
[error]BadRequest: Missing Hostname for FrontendEndpoint [resourceId('Microsoft.Network/frontDoors/frontendEndpoints', parameters('frontdoor_name'), 'fe1customdns2')] in RoutingRule routingRule1.,Missing Hostname for FrontendEndpoint [resourceId('Microsoft.Network/frontDoors/frontendEndpoints', parameters('frontdoor_name'), 'fe1customdns')] in RoutingRule routingRule1;
A resource reference was invalid: "[resourceId('Microsoft.Network/frontDoors/frontendEndpoints', parameters('frontdoor_name'), 'fe1customdns2')]";
A resource reference was invalid: "[resourceId('Microsoft.Network/frontDoors/frontendEndpoints', parameters('frontdoor_name'), 'fe1customdns1')]"

Google Assistant : account linking and Actions sdk : fail to see sign in message

I want to enable account linking on an Google Assistant application using Actions Sdk.
I have already provided the information in the Account Linking section of the AoG Console :
The grant Type is Authorization code.
I use Auth0 as Oauth Server and i checked that the endpoints are functional.
When the application is invoked using the simulator, the server application send the following json response :
{
"expectUserResponse": true,
"finalResponse": null,
"expectedInputs": [{
"possibleIntents": [{
"intent": "actions.intent.SIGN_IN",
"inputValueData": null
}],
"inputPrompt": {
"richInitialPrompt": {
"items": [{
"simpleResponse": {
"textToSpeech": "Merci de vous authentifier",
"ssml": null,
"displayText": "Merci de vous authentifier"
}
}]
}
}
}],
"conversationToken": null,
"isInSandbox": false
}
I expected then to see the message like : it looks like your account … is not linked
Instead of that, the assistant immediately sends the following request to the server :
{
"user": {
"userId": "ABwppHGK6fClByrbLlS8WDM4xfY0qEck5i_kOGMhlJtuj64SjC-8qDqlH3xZ3BN7f9Yz1JDza-sc",
"locale": "fr-CA",
"lastSeen": "2018-04-23T14:12:02Z"
},
"conversation": {"conversationId": "1524493058716", "type": "NEW"},
"inputs": [{
"intent": "actions.intent.SIGN_IN",
"rawInputs": [{"inputType": "KEYBOARD"}],
"arguments": [{
"name": "SIGN_IN",
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "ERROR"
}
}]
}],
"surface": {
"capabilities": [
{"name": "actions.capability.WEB_BROWSER"},
{"name": "actions.capability.MEDIA_RESPONSE_AUDIO"},
{"name": "actions.capability.SCREEN_OUTPUT"},
{"name": "actions.capability.AUDIO_OUTPUT"}
]
},
"isInSandbox": true,
"availableSurfaces": [
{
"capabilities": [
{"name": "actions.capability.SCREEN_OUTPUT"},
{"name": "actions.capability.AUDIO_OUTPUT"}
]
}
]
}
Did someone have the same problem ? Thanks
I have a working example, but it might be different of what you are doing because I ask the sign-in with dialogflow Integrations' tab for Google Assistant, and not explicitely with the SDK. The code is for the V2 of Dialogflow, I also have one for the V1 but it is now legacy.
This is my BONJOUR intent that is triggered when my app is launched:
const rp = require('request-promise');
app.intent('BONJOUR', (conv) => {
console.log("Debug: SAY_HELLO");
const accessToken = conv.user.access.token;
console.log("Access Token = "+accessToken);
//========Auth with OAuth website========
if (!accessToken) {
conv.ask(new SignIn());
} else {
let options = {
method: 'GET',
url: '[...]',//Oauth URL
headers:{
authorization: 'Bearer ' + accessToken,
}
};
// I use the RP lib as we need Promises for the V2 of Dialogflow.
return rp(options).then((body) => {
let data = JSON.parse(body);
console.log("auth data ="+JSON.stringify(data));
//You can access the auth data easily here
// For example if you want the name, it's in data.given_name, etc...
//Use conv.ask() to say something here
}).catch((error) => {
console.log("Error in auth request"+error);
})
}
});
Update:
This is my JSON mais the SignIn() is called, as I just tested it, it doesn't work (I created an intent that receives the actions_intent_SIGN_IN event from an example. And it never asks for sign In , I'm always in the else.)
Response {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "PLACEHOLDER"
}
}
]
},
"userStorage": "{\"data\":{}}",
"systemIntent": {
"intent": "actions.intent.SIGN_IN",
"data": {
"#type": "type.googleapis.com/google.actions.v2.SignInValueSpec"
}
}
}
},
"outputContexts": [
{
"name": [...],
"lifespanCount": 99,
"parameters": {
"data": "{}"
}
}
]
}
Then the request after that is:
Request {
"responseId": "5a711f0e-be66-4311-b776-2085e81e9bde",
"queryResult": {
"queryText": "actions_intent_SIGN_IN",
"parameters": {},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"outputContexts": [
{
"name": "..."
},
{
"name": ".../actions_intent_sign_in",
"parameters": {
"SIGN_IN": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "ERROR"
}
}
},
{
"name": "...",
"lifespanCount": 98,
"parameters": {
"data": "{}"
}
},
{
"name": "..."
},
{
"name": "..."
},
{
"name": "..."
},
{
"name": "..."
}
],
"intent": {
"name": "...",
"displayName": "Get Signin"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {},
"languageCode": "fr-fr"
},
"originalDetectIntentRequest": {
"source": "google",
"version": "2",
"payload": {
"isInSandbox": true,
"surface": {
"capabilities": [
{
"name": "actions.capability.WEB_BROWSER"
},
{
"name": "actions.capability.MEDIA_RESPONSE_AUDIO"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"inputType": "KEYBOARD"
}
],
"arguments": [
{
"extension": {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "ERROR"
},
"name": "SIGN_IN"
}
],
"intent": "actions.intent.SIGN_IN"
}
],
"user": {
"userStorage": "{\"data\":{}}",
"lastSeen": "2018-04-24T12:21:19Z",
"locale": "fr-FR",
"userId": "ABwppHHXrOc7N24RC5YS1dMvt7C-MbpzTb5TtzmufeIpGTCINVlReIMb8RKo4SGQMgBY7BUvO1qhn0B-"
},
"conversation": {
"conversationId": "1524572717282",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google\"]"
},
"availableSurfaces": [
{
"capabilities": [
{
"name": "actions.capability.SCREEN_OUTPUT"
},
{
"name": "actions.capability.AUDIO_OUTPUT"
}
]
}
]
}
},
"session": "..."
}
I hope it can help you somehow.

Invalid JSON file for DeploymentConfig for Kubernetes

I have this JSON file which was converted from YAML:
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "cdt-cae-deployment"
},
"spec": {
"template": {
"metadata": {
"labels": {
"name": "cdt-cae"
},
"annotations": {
"app_version": "latest"
}
},
"spec": {
"containers": [
{
"name": "cdt-cae",
"image": "containers.nabisco.com/cdt-org/cdt-dev:__IMAGETAG__",
"ports": [
{
"containerPort": 8080,
"protocol": "TCP"
}
],
"env": [
{
"name": "APP_NAME",
"value": "cdt-cae"
},
{
"name": "CISCO_LC",
"value": "dev"
},
{
"name": "OPENSHIFT_MONGODB_DB_USERNAME",
"value": "cdtdev"
},
{
"name": "OPENSHIFT_MONGODB_DB_PORT",
"value": "27058"
},
{
"name": "OPENSHIFT_MONGODB_DB_HOST",
"value": "secret stuff here"
},
{
"name": "OPENSHIFT_MONGODB_DB_PASSWORD",
"valueFrom": {
"secretKeyRef": {
"name": "refapp-secret",
"key": "mongodb-password"
}
}
},
{
"name": "NOTIFICATIONS_CLIENT_SECRET",
"valueFrom": {
"secretKeyRef": {
"name": "refapp-secret",
"key": "notifications-client-secret"
}
}
}
],
"volumeMounts": [
{
"name": "podinfo",
"mountPath": "/etc/metadata",
"readOnly": false
}
],
"imagePullPolicy": "IfNotPresent",
"securityContext": {
"capabilities": {},
"privileged": false
}
}
],
"volumes": [
{
"name": "podinfo",
"downwardAPI": {
"items": [
{
"path": "labels",
"fieldRef": {
"fieldPath": "metadata.labels"
}
},
{
"path": "annotations",
"fieldRef": {
"fieldPath": "metadata.annotations"
}
}
]
}
}
],
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst"
}
},
"replicas": 3,
"selector": {
"name": "cdt-cae"
},
"triggers": [
{
"type": "ConfigChange"
}
],
"strategy": {
"type": "Rolling",
"rollingParams": {
"updatePeriodSeconds": 1,
"intervalSeconds": 1,
"timeoutSeconds": 120
}
}
}
}
unfortunately this is invalid JSON - I get this message:
Does anyone know what's wrong with the config? It looks like it's actually valid JSON, only that perhaps the schema is wrong..
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
Don't mind this just adding more details
The
<value> expected, unexpected end of file
means that the thing processing the JSON thinks that the terminating } is missing.
The JSON quoted in the question is fine, but it's been changed from the original because of the secret fields. Maybe the secret has an unescaped quote?

Swagger: disabling security on one particular path

I have a Swagger file that starts with the following
{
"swagger": "2.0",
"basePath": "/api",
"schemes": [
"https"
],
"securityDefinitions": {
"internalApiKey": {
"type": "apiKey",
"name": "AAuthorization",
"in": "header"
}
},
"security" : [
{ "internalApiKey": [ ] }
],
This prolog applies the security setting to every path that follows in the file. Eg.
"paths": {
"/foo": {
"get": {
Is there some way I can disable security on just ONE particular Path or Method?
Sure. Simply add the "security" property to operation with an empty array [] as a value.
So something like
{
"tags": [
"pet"
],
"summary": "Updates a pet in the store with form data",
"description": "",
"operationId": "updatePetWithForm",
"consumes": [
"application/x-www-form-urlencoded"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be updated",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "Pet updated."
}
},
"security": [
]
}
would nullify the security for this operation.
You can try
security:
- NONE: []
This worked for me.
Reference