AWS CloudFormation error: Could not create Change Set "change-set-name" due to: Parameters: "[ssm:param-name:167:167710252826] cannot be found - aws-cloudformation

I have a CF template (serverless Typescript file to be precise) which creates a container definition in the following way.
Type: "AWS::ECS::TaskDefinition",
Properties: {
Family: "client",
RequiresCompatibilities: ["FARGATE"],
NetworkMode: "awsvpc",
Memory: 1024,
CPU: 512,
TaskRoleArn: { Ref: ECS_TASK_ROLE },
ExecutionRoleArn: { Ref: ECS_TASK_ROLE },
ContainerDefinitions: [
{
Name: application,
Essential: true,
Image: `${ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/repository:client-{{resolve:ssm:param-name}}`,
.
.
.
},
],
}
Please note the usage of AWS SSM Dynamic Reference.
When I deploy it I get the following error
Could not create Change Set "change-set-name" due to: Parameters: "[ssm:param-name:167:167710252826] cannot be found.
It used to work fine and all of a sudden started breaking. Same code still works in a different env/AWS account.
Seems like it can't find a specific version of param-name for some reason. The latest param-name verion is 400. AWS SSM only keeps last 100 params. This parameter is updated quite often and it's been a long time since I deployed CF template. From the error message it seems like it is looking for version 167 (I could be wrong because I am not sure what is the number trailing 167 i.e. 167:167710252826)
What I tried:
I hardcoded the version number I pass as below and removed all the references to resolve:ssm:param-name.
Image: `${ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/repository:client-1.6.3`,
It still throws the same error. Which hints that the problem is not related to code. CF is trying to run an old change set from history to create a diff and can't find an old version of the same param.
What could be the solution to this?
I can't delete the old change set. It throws an error on deleting.
I can't go back and create a parameter in SSM with version 167 if it's a version issue.

Related

Serverless version > 2.35 error in variable replacement to Cloudformation template

How are you?
I'm facing to a very odd error after upgrading my Serverless version from 2.35 to any newer version.
Using the exactly the same .yml that deploys in 2.35, in newer versions the following error is thrown:
ProviderARNs need to be valid Cognito Userpools:
Serverless Error ----------------------------------------
An error occurred: ApiGatewayCognitoAuthorizer - ProviderARNs need to be valid Cognito Userpools. Invalid ARNs-
arn:aws:cognito-idp:${file(./src/config/dev.json):REGION}:${file(./src/config/dev.json):AWS_ACCOUNT}:userpool/${file(./src/config/dev.json):COGNITO_POOL_ID} (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: e8403d66-ec5c-4ead-9528-308baed7640f; Proxy: null).
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Issues: forum.serverless.com
Your Environment Information ---------------------------
Operating System: darwin
Node Version: 12.22.1
Framework Version: 2.50.0 (local)
Plugin Version: 5.4.4
SDK Version: 4.3.0
Components Version: 3.17.0
In the deep, the problem is that the CloudFormation template generated in the deployment is unable to resolve variables that 2.35 and previous versions resolved properly (specially those variables that depends on the config file), for example in my code:
ApiGatewayCognitoAuthorizer:
DependsOn:
- ApiGatewayRestApi
Type: AWS::ApiGateway::Authorizer
Properties:
Name: cognito-authorizer
IdentitySource: method.request.header.Authorization
ProviderARNs:
- "arn:aws:cognito-idp:${${self:custom.config}:REGION}:${${self:custom.config}:AWS_ACCOUNT}:userpool/${${self:custom.config}:COGNITO_POOL_ID}"
RestApiId:
Ref: ApiGatewayRestApi
Type: COGNITO_USER_POOLS
Same variable replacements are used in other resources, lambdas, etc. but the error is only thrown to API Cognito Authorizer, I don't understand...
Thank you all for your attention and help :)
Solved using https://www.serverless.com/framework/docs/environment-variables/, ie, loading environment variables from .env files instead custom .json files.
Thanks anyway to everybody.

Cloudformation conditional nested stack Unresolved resource dependencies

I have a Cloudformation stack that conditionally invokes a nested stack to create a RDS instance, only if an existing database URL is not passed in as a parameter.
If I pass a value to the DBExistingEndpoint parameter in the stack, the condition CreateDB is set to false, and it will not invoke the nested RDS stack at all.
The issue is that in the AutoScaling launch config resource, there is a conditional dependency. I need to reference either the URL output from the nested stack, or the URL passed in as a parameter to place in a file in the newly launched instance.
Parameters:
DBExistingEndpoint:
Type: String
Description: Set to a URL of a RDS instance to use an existing DB, otherwise create one
Default: ''
...
Conditions:
CreateDB:
!Equals [!Ref DBExistingEndpoint, '']
...
Resources:
# Database created only if existing URL not passed in
DB:
Type: AWS::CloudFormation::Stack
Condition: CreateDB
Properties:
TemplateURL: ...
...
ClusterInstanceLaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Metadata:
AWS::CloudFormation::Init:
config:
files:
/etc/dbenv:
mode: "000640"
owner: root
group: root
content:
!Join
- "\n"
-
- !Sub ["DB_HOST=${DBEndpointAddress}", DBEndpointAddress: !If [CreateDB, !GetAtt DB.Outputs.RDSEndPointAddress, !Ref DBExistingEndpoint]]
...
The issue is that if I pass in an existing endpoint URL, the DB resource is skipped (correctly), but the stack creation fails with Template format error: Unresolved resource dependencies [DB] in the Resources block of the template
Ideally the DB.output.RDSEndpointAddress reference in the ClusterInstanceLauchConfig resource should be ignored because the CreateDB condition in the !If is false
Does anybody know how to code around this limitation?
You should try to set the conditional statement on a different level than it is now.
What will work for sure, is having the conditional statement on the level of the LaunchConfiguration itself, which would also mean quite a lot of duplication of the code. But maybe you could try to see the conditional on the level of content or files etc, to see if there's a middle ground somewhere, to keep duplication low, but avoid the error you're getting right now.

Use CAPABILITY_AUTO_EXPAND for nested stacks on CloudFormation

I am trying to use nested stack and when my ChangeSet is being executed, I got this error:
Requires capabilities : [CAPABILITY_AUTO_EXPAND]
I went and create a pipeline with cloudformation.
This can be use to create a pipeline:
Configuration:
ActionMode: CHANGE_SET_REPLACE
ChangeSetName: changeset
RoleArn: ??
Capabilities: CAPABILITY_IAM
StackName: appsync-graphql
TemplatePath: BuildArtifact::output.yaml
This can’t:
Configuration:
ActionMode: CHANGE_SET_REPLACE
ChangeSetName: changeset
RoleArn: ??
Capabilities:
- CAPABILITY_IAM
- CAPABILITY_AUTO_EXPAND
StackName: appsync-graphql
TemplatePath: BuildArtifact::output.yaml
The error was: “Value of property Configuration must be an object with String (or simple type) properties”
This is the closest docs that I find: https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_UpdateStack.html
It said: Type: Array of strings for capabilites, and the aws cli docs says similarly, but doesn’t give an example.
So I ran out of ideas about what else to try to have CAPABILITY_AUTO_EXPAND capability.
I tried another variant and it worked!
Configuration:
..
Capabilities: CAPABILITY_IAM,CAPABILITY_AUTO_EXPAND
...
I got the answer from Keeton Hodgson, this cli command works:
sam deploy --template-file output.yaml --stack-name <AppName> --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND
Notice that there is no comma.
I still don't know how to change the pipeline template for it to work.
I tried the solutions above and what worked for me today (June 2020) using the higher level sam was adding a space between the capabilities listed. It's complete insanity that there's no resilience in this text file interpretation. SAM's cli is open source so I guess I could put my code where my mouth is and submit a PR. Anyway.
samconfig.toml:
...
capabilities = "CAPABILITY_IAM CAPABILITY_AUTO_EXPAND"
...
Then:
sam deploy
Output:
...
Capabilities : ["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"]
...
Put the capabilities property at the very end like this
aws cloud formation deploy COMMAND --capabilities CAPABILITY_NAMED_IAM
Change the order
Configuration:
ActionMode: CHANGE_SET_REPLACE
ChangeSetName: changeset
RoleArn: ??
StackName: appsync-graphql
TemplatePath: BuildArtifact::output.yaml
Capabilities:
- CAPABILITY_IAM
- CAPABILITY_AUTO_EXPAND
After some research found that you can actually add those capabilities in console.
Reference Capabilities - optional section in the cfn deploy phase definition in console

Failing to put release

I'm getting the following error when trying to put a release in a private repo.
creating release ReleaseName error running command: POST https://api.github.com/repos/my-org/my-repo/releases: 404 Not Found []
prior to getting this error, I was getting:
error running command: GET https://api.github.com/repos/my-org/my-repo.git/releases: 404 Not Found []
so I know the get is now working, and it's something specific to the POST.
My resource config is as follows (admittedly doctored to protect the innocent)
- name: gh-release
type: github-release
source:
owner: my-org
repository: my-repo
access_token: {{access-token}}
and the put looks like this (again doctored):
- put: gh-release
params:
name: package/name
tag: version/version
tag_prefix: package/tag-prefix
commitish: package/commitish
globs:
- package/*.tar.gz
I know the access token works for the GET, and I've used it with curl successfully.
Any ideas what I might be doing wrong?
UPDATE: fixed indentation.
Turns out that it was a permissions problem. The user that the token was for only had read access to the repository. Using a different user token, or updating the repo access to write fixed the issue.

Bluemix cf push error with manifest: expected services to be a list of strings

I'm trying to push an app to Bluemix on a Linux OS. However, the command line returns an error involving the manifest file:
Error reading manifest file:
Expected services to be a list of strings.
Here is the code for the manifest file:
applications:
- name: IdeaSocial
memory: 1024M
instances: 1
host: IdeaSocial
domain: mybluemix.net
path: .
services:
-SQL Database-v5
How do I fix this? Is there a form that the file needs to be in for the current version of Bluemix?
Add quotes around SQL Database-v5 to have it treated as a single string even though there is a space in it. Spaces matter in YAML.
...
services:
- "SQL Database-v5"
The documentation has more information and examples.