Use the Amazon Alexa Skill CLI to update the Interaction Model - amazon

Trying to update the interaction model of my skill using the command line based AWS CLI. Until now I've been copying the interaction model directly into the online skill editor. What's the best process for doing this programmatically?

To Update your Alexa Skill Interaction Model Via the AWS CLI:
1) Setup an AWS CLI Profile using credentials from your AWS IAM Profile
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html
$ aws configure --profile [PREFERED PROFILE NAME]
AWS Access Key ID [None]: AKIAIOSFODNN7_EXAMPLE_FOUND_IN_IAM
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCY_EXAMPLE_KEY
Default region name [None]: us-east-1
Default output format [None]: json
In the Command Line:
SKILL_ID=[YOUR SKILL ID FOUND AT DEVELOPER.AMAZON.COM]
CLI_PROFILE=[YOUR CLI PROFILE CREATED ABOVE]
ask api update-model -s ${SKILL_ID} -p ${CLI_PROFILE} -l en-US -f [PATH TO FILE]/InteractionModel.json
Note:
en-US updates the english interaction model
Return Data:
Model for en-US submitted.
Please use the following command to track the model build status:
ask api get-skill-status -s amzn1.ask.skill.4245ff2e-476c-418b-8004-dc63346dc432e4
To Track your progress be sure to append your AWS_CLI profile
ask api get-skill-status -s amzn1.ask.skill.4245ff2e-476c-418b-8004-dc63346dc432e4 -p ${CLI_PROFILE}
Tracking Result Data:
{
"interactionModel": {
"en-US": {
"eTag": "f05823449ac35d318acb4096d061eaa8",
"lastUpdateRequest": {
"status": "IN_PROGRESS"
}
}
},
"manifest": {
"eTag": "df3b0a7c544b5c0ee006e34cf726dcd2",
"lastUpdateRequest": {
"status": "SUCCEEDED"
}
}
}
LastUpdateRequest Status: Should Eventually Read SUCCEEDED
Forewarning:
You cannot update the Invocation Name of a live skill. This is the only error I've run across so far. "message": "InvalidStageInvocationNameChange: You cannot change the invocation name for a live skill."

I don't use this, but you probably want the "ASK CLI":
https://developer.amazon.com/docs/smapi/ask-cli-command-reference.html

Related

Google API Node.js Library - Permission denied on `getIamPolicy` for projects in organization

Goal
get and set IAM Policies for auto-provisioned GCP Projects and Service Accounts within said projects using the Node.js Client Library for Google APIs. As well as give a the service account in the project the Dialogflow API Admin role (roles/dialogflow.admin)
Issue
I get the following error when I try to get the IAM policy for a project I just automatically created.
Error: 7 PERMISSION_DENIED: Permission 'resourcemanager.projects.getIamPolicy' denied on resource '//cloudresourcemanager.googleapis.com/projects/va-31b899e6' (or it may not exist).
at Object.callErrorFromStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/client.js:180:52)
at Object.onReceiveStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:365:141)
at Object.onReceiveStatus (/home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:328:181)
at /home/aeglad22/va-project-provisioning/node_modules/#grpc/grpc-js/build/src/call-stream.js:182:78
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
code: 7,
details: "Permission 'resourcemanager.projects.getIamPolicy' denied on resource '//cloudresourcemanager.googleapis.com/projects/va-31b899e6' (or it may not exist).",
metadata: Metadata {
internalRepr: Map(3) {
'grpc-server-stats-bin' => [Array],
'google.rpc.errorinfo-bin' => [Array],
'grpc-status-details-bin' => [Array]
},
options: {}
},
note: 'Exception occurred in retry method that was not classified as transient'
}
Here is the function I am trying to do this in.
async function setServiceAccountRolesV2(projectID, serviceAccountID){
const authClient = await auth.getClient();
const resourcemanagerClient = new ProjectsClient();
var request = {
resource: "projects/"+projectID,
auth: authClient
}
await resourcemanagerClient.getIamPolicy(request, function(err, response) {
if (err) {
console.error(err);
return;
}
console.log(JSON.stringify(response, null, 2));
});
}
Authentication Info
I am using a service account key to authenticate all of my functions in this node app with. This service account has the following permissions granted at the organization level
This service account I am using to authenticate my app with succeeds at getIamPolicy when I try to get the policy of the project it was created in itself. But I get the error when I try to get the policy of new projects I have created using this "admin project" service account.
Summary
Why is permissions denied when trying to get the IAM Policy of projects I have created programmatically, but successful when getting the policy of the "admin" project that I have this service account and the node.js app running. I thought that if I granted my service account proper permissions at the organization level, and the projects I am creating programmatically were in that same organization, my authenticating service account should inherit all of the right permissions to grant service account roles and change IAM policy in these newly generated accounts.
A potential thought/gut feeling I have that could be completely wrong - is it possible these new projects I'm making don't have IAM Policies at all? so when I try to get and set them there's nothing to change?
Update for clarifications
I have a project that acts as an "administration project" which contain hosts the VM my Node.js app for provisioning GCP resources runs on.
This project is also where I created my service account that the Node.js app authenticates with.
I am creating new projects and service accounts within those projects with this Node.js app.
I have given the aforementioned service account the Owner permission at the organization level.
In my setServiceAccountRolesV2() method, I have tried making the resource my provisioned project manually, as opposed to passed as a parameter to make sure the the project is located correctly. I manually copy and pasted the project ID from one of the auto-provisioned projects into the resource field like this for example
resource: "projects/va-31b899e6",
and I get the same permission denied error (full error message shown above).
However when I try to use this getIamPolicy method with the "admin" project that my node.js app and service account were created in, I get a successful policy return.
resource: "projects/provisioning-admin-339515"
I don't understand why one works, and one doesn't while the service account I'm using to make the call has Owner role at the organization level. The va-31b899e6 project shown above is in fact under the same organization my admin project is.
When I run the gcloud command gcloud projects get-iam-policy va-31b899e6 --format=json > ~/policy.json to check the policy of the api-generated project (not the admin project), I get the following policy back:
{
"bindings": [
{
"members": [
"serviceAccount:tf-admin-sa#provisioner-admin-339515.iam.gserviceaccount.com" ],
"role": "roles/owner"
}
],
"etag": "ByXXh29efSc=",
"version": 1
}
This service account listed in the members is the service account I authenticate my Node app with. Again, Owner granted at the Org level. This to me looks like it should be able to use the get and setIamPolicy methods on this project, as well as any other project in my organization.
New edits to follow trouble shooting tips from answer.
1
Confirmed I am using the correct project in the api call:
async function setServiceAccountRolesV2(projectID, serviceAccountID){
const authClient = await auth.getClient();
const resourcemanagerClient = new ProjectsClient();
var request = {
resource: "projects/va-31b899e6",
auth: authClient
};
await resourcemanagerClient.getIamPolicy(request, function(err, response) {
if (err) {
console.error(err);
return;
}
console.log(JSON.stringify(response, null, 2));
});
}
(project ID copied from GCP Console) : resource: "projects/va-31b899e6",
2
I have verified my credentials are used correctly, I am using a json key file of the service account I created to create more projects and service accounts programmatically. This is how I am authenticating :
const auth = new google.auth.GoogleAuth({
keyFile: 'provisioner-admin-339515-411d1e284a77.json',
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
});
Then in my function, I create a new instance of auth like this:
const authClient = await auth.getClient();
which is then sent in the request of the api call: auth: authClient
3
Verified permissions for my authenticating service account:
When I run
gcloud projects get-iam-policy va-31b899e6 \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:tf-admin-sa#provisioner-admin-339515.iam.gserviceaccount.com"
I get the output ROLE: roles/owner
Your service account has too many roles. Most of the roles are redundant and included within other roles that you assigned. For example, Billing Account Administrator contains the permissions of Billing Account User. The role Owner possesses almost all of the roles in your screenshot.
Next, you need to understand the Principle of Least Privilege. Seth Vargo put together a good intro video. In summary, only grant the required privileges and no more. Your service account IAM roles are vast and a serious security weakness.
To solve the problem in your question, follow these steps:
STEP 1:
Confirm that the Project ID is correct in the API call. Make sure you are using the Project ID and not the Project Name. List the projects:
gcloud projects list
STEP 2:
Verify that your code is using the correct credentials (the ones you think you configured). Your question does not show how you are authorizing your code. You are using ADC (Application Default Credentials) which means the credentials could be found from several sources (CLI remembered credentials, the environment variable, metadata server).
If you are using the environment variable GOOGLE_APPLICATION_CREDENTIALS, open the file using the variable and make sure that it is a service account JSON key:
vi $GOOGLE_APPLICATION_CREDENTIALS
If you are using the CLI credentials, verify which identity is being used:
gcloud auth list
As a debugging test, clear the environment variable and use a user identity that has the role Owner and then login. Then retest your application.
unset GOOGLE_APPLICATION_CREDENTIALS
gcloud auth application-default login
STEP 3:
Once you have determined the correct Project ID and which service account your code is using, double-check the roles assigned to the service account at the project level. List the IAM roles with this command. Replace with your Project ID and Service Account Email address:
gcloud projects get-iam-policy <PROJECT_ID> \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:<SERVICE_ACCOUNT_EMAIL>"
The service account needs one of these roles or similar to view IAM bindings:
roles/browser aka Browser
roles/iam.roleViewer aka Viewer
The service account needs this role or similar to modify IAM bindings:
roles/resourcemanager.projectIamAdmin aka Project IAM Admin
Manage access to projects, folders, and organizations

Using Stripe CLI to Delete Errant Custom Accounts through Terminal

I will admit that I am not that savvy when it comes to Stripe and I'm just learning.
In the process of setting up our Connect Account we added some Custom Accounts that were rejected or restricted. I have been informed the only way of removing said accounts is via Stripe API.
I installed Stripe CLI on my Mac in hopes that this would be easy. All I get are errors. This is currently what I am using as code and the response I get as an error:
$ stripe accounts delete acct_1JDDIoQSOur1AOsw --live
This command will be executed on the account with the following details:
> Mode: Live
> Account Name: LocalGood2Go
Are you sure you want to perform the command: DELETE?
Enter 'yes' to confirm: yes
{
"error": {
"message": "This application is not authorized to delete this account.",
"type": "invalid_request_error"
}
}
Is it not possible to delete account through the CLI? If not then please advise how I can use the API.
Much appreciated.

Workload identity federation with #google-cloud

Does anybody know if there are any other ways of authentication/authorization for access to Google Cloud Storage besides of Service Account key when I use #google-cloud/storage Node.js module from here?
I have read about “Workload identity federation”, but it seems for me that I cannot use this approach when I use #google-cloud/storage library.
I was not able to find any suitable constructor, only these two:
const {Storage} = require('#google-cloud/storage');
var storage = new Storage({
projectId : `my_google_project_id`,
keyFilename : `my_google_key_file.json` // service account key is inside of this file
});
// or this one:
var storage = new Storage(); // service account key is inside of file specified by environment variable GOOGLE_APPLICATION_CREDENTIALS
Any recommendations?
Thank you
Most Google Clients support a new secrets key file with the type external_account. The following demonstrates how to create this file and setup Application Default Credentials (ADC) to load this file.
To use Workload Identity Federation with Google Client libraries, save the federated credentials to a file and then specify that file via the environment variable GOOGLE_APPLICATION_CREDENTIALS. The Storage client will use ADC and locate the credentials from the environment.
Example for AWS:
# Generate an AWS configuration file.
gcloud iam workload-identity-pools create-cred-config \
projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AWS_PROVIDER_ID \
--service-account $SERVICE_ACCOUNT_EMAIL \
--aws \
--output-file /path/to/generated/config.json
Example for Azure:
# Generate an Azure configuration file.
gcloud iam workload-identity-pools create-cred-config \
projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$AZURE_PROVIDER_ID \
--service-account $SERVICE_ACCOUNT_EMAIL \
--azure \
--output-file /path/to/generated/config.json
Note: I generated my credentials on an Azure VM. I added the following command line option to the above command:
--app-id-uri=https://iam.googleapis.com/projects/REDACTED/locations/global/workloadIdentityPools/pool-azure/providers/provider-id
The output-file value is used to set the environment:
set GOOGLE_APPLICATION_CREDENTIALS=/path/to/generated/config.json
The file has the following structure. This example is for Azure:
{
"type": "external_account",
"audience": "//iam.googleapis.com/projects/REDACTED/locations/global/workloadIdentityPools/pool-azure/providers/provider-id",
"subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
"token_url": "https://sts.googleapis.com/v1/token",
"credential_source": {
"url": "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://iam.googleapis.com/projects/REDACTED/locations/global/workloadIdentityPools/pool-azure/providers/provider-id",
"headers": {
"Metadata": "True"
},
"format": {
"type": "json",
"subject_token_field_name": "access_token"
}
},
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/REDACTED#REDACTED.iam.gserviceaccount.com:generateAccessToken"
}
Use this style to create a client:
var storage = new Storage();

AWS CodeBuild SDK, source from GitHub

I have following use case. (Using AWS CodeBuild Node.js SDK)
I need to use a private GitHub repository as a source for CodeBuild project.
CASE no.1
When I go to CodeBuild project and "Edit Source" in place, I paste a personal access token and everything works as expected.
CASE no.2
The problem arises, when I want to achieve the very same thing, using AWS CodeBuild Node.js SDK.
I'm using the very same existing CodeBuild project and I set my AWS.CodeBuild.start params as following
{
projectName: CODEBUILD_PROJECT,
sourceLocationOverride: "https://github.com/owner/name",
buildspecOverride: buildspecYML,
sourceTypeOverride: "GITHUB",
sourceAuthOverride: {
// Deprecated, but TS requires it
type: "OAUTH",
resource: TOKEN
}
}
I get response:
InvalidInputException: No Access token found, please visit AWS CodeBuild console to connect to GitHub
My question is. Is my use-case supported with current state of the SDK? If yes, how do I achieve it?
One thing I noticed while going through TS type definitions is the comment that only OAUTH type is currently supported. For this reason, I'm not sure if there even is a way to achieve my use-case.
export interface SourceAuth {
/**
* This data type is deprecated and is no longer accurate or used. The authorization type to use. The only valid value is OAUTH, which represents the OAuth authorization type.
*/
type: SourceAuthType;
/**
* The resource value that applies to the specified authorization type.
*/
resource?: String;
}
Some more details:
What I'm trying to achieve here is building a simple CI, that will be managed from a GitHub App, so the token I will be passing is the users Access Token.
With a Github source, you have two options for authType:
OAUTH
PERSONAL_ACCESS_TOKEN
If using OAUTH, the only option to provide the credential is through AWS CodeBuild console. Start creating a project, under source, select 'Connect using OAuth', the click 'Connect to Github' and complete the process. You can cancel out of the Project after connecting to Github.
Confirm the credential is registered by executing the command:
$ aws codebuild list-source-credentials --region us-east-1
Output is something like:
{
"sourceCredentialsInfos": [
{
"arn": "arn:aws:codebuild:us-east-1:<ACCOUNTNUM>:token/github",
"serverType": "GITHUB",
"authType": "OAUTH"
},
{
"arn": "arn:aws:codebuild:us-east-1:<ACCOUNTNUM>:token/github_enterprise",
"serverType": "GITHUB_ENTERPRISE",
"authType": "PERSONAL_ACCESS_TOKEN"
}
]
}

AWS: Authentication issues trying to push metrics to CloudWatch from EC2

I am trying to set up an EC2 (RHEL7) instance to push metrics to cloudwatch using perl scripts as described in http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/mon-scripts.html
I get an HTTP status 400 message "The security token included in the request is invalid"
An instance profile is associated with the instance which has the following policy attached:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeTags"
],
"Resource": "*"
}
]
}
I am pulling the AWSAccessKeyId and AWSSecretKey from the instance meta-data as follows:
ROLE=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/)
CRED=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/$ROLE)
AWSAccessKeyId=$(sed '/AccessKeyId/!d; s/.*:\ \+"\(.\+\)",/\1/g' <<< "$CRED")
AWSSecretKey=$(sed '/SecretAccessKey/!d; s/.*:\ \+"\(.\+\)",/\1/g' <<< "$CRED")
...the values set in the above variables are correct when i check them...
I am running the script to push to cloudwatch as follows (using creds stored in variables from above):
./mon-put-instance-data.pl --mem-util --verbose --aws-access-key-id $AWSAccessKeyId --aws-secret-key $AWSSecretKey
Any ideas why it is rejecting my credentials?
Thanks in advance
If you're using an IAM profile, you don't need to put in the credentials for your script call. Remove the access key and secret key from your call.
./mon-put-instance-data.pl --mem-util --verbose
Yes. You are both right - it automatically picks up the role creds if you dont specify and seems to work.
Not sure why it doesnt work by manually setting the creds but i can look at the perl script to work this out fairly easily.
Thanks for your help.
From documentation:
The following examples assume that you provided an IAM role or awscreds.conf file. Otherwise, you must provide credentials using the --aws-access-key-id and --aws-secret-key parameters for these commands.
As an option when you get an error:
ERROR: Failed to call CloudWatch: HTTP 400. Message: The security token included in the request is invalid.
the script uses a config file (e.g. with wrong credentials):
aws-scripts-mon/awscreds.conf
So, an IAM role or awscreds.conf or --aws* params have to be provided.
And the IAM role has correct permissions:
cloudwatch:PutMetricData
cloudwatch:GetMetricStatistics
cloudwatch:ListMetrics
ec2:DescribeTags

Resources