CodePipeline CloudFormation Template configuration - aws-cloudformation

I'm trying to use the CloudFormation Template configuration field in a CodePipeline. If you edit the CloudFormation in CodePipeline it looks like this:
If my InputArtifactName is MyAppBuild and I have a CloudFormation config file in cfg-prd.json, my hope was I could enter MyAppBuild::cfg-prd.json and have it pick it up.
I get an error about the template file not being valid even though it works manually as:
--parameters cfg-prd.json

Note that the Template Configuration File has a different JSON structure than the format accepted by the --parameters option to aws cloudformation create-stack:
{
"Parameters" : {
"NameOfTemplateParameter" : "ValueOfParameter",
...
},
"StackPolicy" : {
"Statement" : [
StackPolicyStatement
]
}
}

A nice trick to see what the Cloudformation layout should be is to create a pipeline which you know will work. Then use the CLI to extract a cloudformation template.
aws codepipeline get-pipeline --name <pipelinename>
You will get the JSON of the Codepipeline resource. There will be a few changes required but from this you can see exactly what the syntax should be and from there parameterised your template and create Codepipelines programatically.

Related

Seems to conflict between Serverless syntax and CloudFormation syntax

The below is the part of CloudForamtion file loaded by Serverless.
# resource.yml
.
.
.
{"Fn::Sub": "arn:aws:sqs:*:${AWS::AccountId}:sqs-spoon-*-${env:SERVICE}"}
# serverless.yml
.
.
resources:
- ${file:resource.yml}
${AWS::AccountId} is CloudFormation Pseudo Parameter and ${env:SERVICE} is Serverless variable.
When I run sls deploy, it returns the error.
Invalid variable reference syntax for variable AWS::AccountId. You can only reference env vars, options, & files. You can check our docs for more info.
It seems to say that Serverless recognize ${AWS::AccountId} as Serverless variable, not as CloudFormation Pseudo Parameter.
Right?
If so, how to have Serverless not to parse Pseudo Parameter so that it will be parsed by CloudFormation later?
I can solve it with the plugin.
With the plugin, It cloud be solved by replacing ${AWS::AccountId} with #{AWS::AccountId}.
{"Fn::Sub": "arn:aws:sqs:*:#{AWS::AccountId}:sqs-spoon-*-${env:SERVICE}"}
You can accomplish support for the native AWS syntax with a single config line in serverless.yml to define the variableSyntax. Details can be found here https://github.com/serverless/serverless/pull/3694.
provider:
name: aws
runtime: nodejs8.10
variableSyntax: "\${((env|self|opt|file|cf|s3)[:\(][ :a-zA-Z0-9._,\-\/\(\)]*?)}"

How do I set environment properties in AWS codestar?

I created a spring project in AWS codestar.
I would like to pass environment properties to my application (e.g. DATA_SOURCE_URL). I can do it in elastic beanstalk in "Configuration" -> "Software" "modify" and adding the properties. But whenever a new deployment is triggered this configuration gets reseted.
I was wondering what is the way of setting environment properties when using AWS codestar.
As it may help other people that search a solution
I finally get it to work by using the Saved Configuration function in Beanstalk, and calling it via the cloud formation template.yml : EBConfigurationTemplate (from the autogenerated template.yml by codestar)
EBConfigurationTemplate:
[...]
SourceConfiguration:
ApplicationName: !Ref 'EBApplication'
TemplateName: "Saved Configuration Name"
After that my django application was able to read the os.environ['ENV_VAR_NAME']
as well as django.config that was able to connect to an RDS (Non-managed by beanstalk) to do the migration as a container_command

How can I check if a resource was created by CloudFormation?

I have inherited an AWS account with a lot of resources. Some of them were created manually, other by CloudFormation.
How can I check if a resource (in my case Security Group) was created by CloudFormation and belongs to a stack?
For some security groups aws ec2 describe-security-groups --group-ids real_id results in:
...
"Tags": [
{
"Value": "REAL_NAME",
"Key": "aws:cloudformation:logical-id"
},
{
"Value": "arn:aws:cloudformation:<REAL_ID>",
"Key": "aws:cloudformation:stack-id"
},
]
...
Other security groups don't have any tags.
Is it the only indicator? I mean, someone could easily remove tags form an SG created by CloudFormation.
As per the official documentation, in addition to any tags you define, AWS CloudFormation automatically creates the following stack-level tags with the prefix aws::
aws:cloudformation:logical-id
aws:cloudformation:stack-id
aws:cloudformation:stack-name
All stack-level tags, including automatically created tags, are propagated to resources that AWS CloudFormation supports. Currently, tags are not propagated to Amazon EBS volumes that are created from block device mappings.
--
This should be a good place to start with but since CF doesn't enforce the stack state so if someone deleted something manually then you would never know.
If I were you, I would export everything (supported) via Cloudformer and re-design the whole setup my way.
Another way:
You can pass PhysicalResourceId of a resource to describe_stack_resources and get the stack information if it belongs to a CF stack. This is an example:
cf = boto3.client('cloudformation')
cf.describe_stack_resources(PhysicalResourceId="i-0xxxxxxxxxxxxxxxx")
https://boto3.readthedocs.io/en/latest/reference/services/cloudformation.html#CloudFormation.Client.describe_stack_resources
I had the same issue. After no luck finding an answer I made a quick PowerShell script that will just look for a resource name in all of the stacks.
When CF was introduced the stacks didn't tag resources and even now I have issues with CloudFormation reliably tagging resources, there are still times it will tag one resource and not tag another even with the same resource type and in the same stack. In addition some resources like CloudWatch Alarms don't have tags.
$resourceName = "*MyResource*" #Part of the resource name, surrounded by asterisks (*)
$awsProfile = "Dev" #AWS Profile to use
$awsRegion = "us-east-1" #Region to query
Get-CFNStack -ProfileName $awsProfile -Region $awsRegion | Get-CFNStackResourceList -ProfileName $awsProfile -Region $awsRegion | Where-Object {$_.PhysicalResourceId -ilike $resourceName} | Select-Object StackName,PhysicalResourceId

Tag stack created by Codepipeline

Is it possible to add tags to stacks created by Codepipeline using Cloudformation as the Provider for Deployment?
As this documentation says you have a possibility to set tags for your stack in Template Configuration File. Note that end of the article illustrate an example where Configuration File has an Tags section with "Department" : "Marketing" key-value.

How to create a parent resource in AWS API Gateway?

When using the AWS Api-Gateway service, I'd like to add a "parent" resource without deleting and rebuilding the resource structure. Specifically, I'd like to change this:
resource/name
resource/name
And add a "parent" resource to it (v1) without deleting and remaking the two "resource/name" resources, like this:
/v1
/resource/name
/resource/name
If it requires use of the CLI, what would an example command look like?
UPDATE:
Thanks for the great answer Ka Hou Ieong. Here are some notes on implementing it:
rest-api-id : Put the api id here. You can look it up with this command: aws apigateway get-rest-apis
resource-id : Put the id of the resource you'd like to move here. You can look it up with this command: aws apigateway get-resources --rest-api-id API-ID-HERE
replace : Leave this; it's the operation.
/parentId : Leave this. It refers to the "key" of the value that you'll replace.
<new parent resourceId> : Replace this with the ID of the parent you'd like.
You can create a resource with path part "/v1", then re-parent these resources by using the CLI tool or SDK.
Example cli command to reparent the resource
aws apigateway update-resource \
--rest-api-id rest-api-id \
--resource-id resource-id \
--cli-input-json "{\"patchOperations\" : [
{
\"op\" : \"replace\",
\"path\" : \"/parentId\",
\"value\" : \"<new parent resourceId>\"
}
]}"
Here is the cli tool documentation: http://docs.aws.amazon.com/cli/latest/reference/apigateway/update-resource.html
Here is the API reference: http://docs.aws.amazon.com/apigateway/api-reference/link-relation/resource-update/