Pathid required (but not always) in CloudFormationProvisionedProduct - amazon-web-services

I am trying to build a CloudFormationProvisionedProduct. From the cli, no issue:
aws servicecatalog provision-product --product-id prod-123456abcd --provisioning-artifact-name 1.49 \
--provisioned-product-name whatisgoingon\
--provisioning-parameters '[{"Key":"Name","Value":"RStudioIngress-CFCLI"},{"Key":"Host","Value":"rstudio-cloudformedcli"},{"Key":"OriginHostname","Value":"rstudio-cf.alb.***"},{"Key":"ForwardOriginalHostHeader","Value":"true"},{"Key":"AuthType","Value":"SSO"},{"Key":"AccessByApimGw","Value":"false"},{"Key":"ApimEnabled","Value":"false"},{"Key":"AppRoles","Value":"[]"},{"Key":"GroupsOnly","Value":""}]'
This works perfectly fine.
When I run the same via cloudformation:
Ingress:
Properties:
#PathId: lpv2-***
ProductId: prod-123456abcd
ProvisionedProductName: whatisgoingon
ProvisioningArtifactName: "1.49"
ProvisioningParameters:
- Key: Name
Value: RStudioIngress-CFCLI
- Key: Host
Value: rstudio-cloudformedcli
- Key: OriginHostname
Value: rstudio-cf.alb.***
- Key: ForwardOriginalHostHeader
Value: "true"
- Key: AuthType
Value: SSO
- Key: AccessByApimGw
Value: "false"
- Key: ApimEnabled
Value: "false"
- Key: AppRoles
Value: "[]"
- Key: GroupsOnly
Value: ""
Type: AWS::ServiceCatalog::CloudFormationProvisionedProduct
I get: No launch paths found for resource. If I find the relevant path (aws servicecatalog list-launch-paths --product-id prod-123456abcd) and give it via PathId in the couldformation template, I get Invalid PathId. There is only one path anyway, so it should not be required.
Question:
Why is there a difference between the cli and cloudformation call, and how can I fix it?

Related

Use Gett Function inside Sub in cloudformation

I am trying to get the value of my RDS endpoint and use it as a value in a secret-manager I am creating.
I know how to get the endpoint in the outputs:
DB1ConnectionString:
Condition: Launch1Engine
Description: The First db Connection String
Value: {"Fn::GetAtt": ["RDSDBInstance1","Endpoint.Address"]}
But I can not use output inside my current stack, so I want to use the same way I got the Endpoint and use it in the secret manager.
This is what I tried:
DBStringSecret1:
Condition: Launch1Engine
Type: 'AWS::SecretsManager::Secret'
Properties:
Name: !Ref DBStringSecret1Name
SecretString: !Sub '{"repository":!GetAtt RDSDBInstance1.Endpoint.Address,"username":"MasterUsername","password":"${SafeMineDBPassword1}"}'
But I get a literal string as the "repository value and not the RDS endpoint,
Is there a way to use the "!GetAtt" inside the "!Sub"?
Or am I doing it all wrong and I can define a new parameter that will build the value I want using Join?
!Sub 'jdbc://{!GetAtt RDSDBInstance1.Endpoint.Address}:3306/<SCHEMA>?'
Expected result:
jdbc://endpoint:3306/?
You have to use join function in this case:
SecretString: !Join
- ''
- - '{"repository": "'
- !GetAtt RDSDBInstance1.Endpoint.Address
- '","username":"MasterUsername","password":"'
- !Ref SafeMineDBPassword1
- '"}'

Conditionally settings tags with IF not working in cloudformation template

I want to conditionally create a tag for a resource, not just change the value. The tag should or should not be created based on a condition.
I looked at the docs and from what I found this should work:
Tags:
- Key: "sometag"
Value: "sdfsdfsdfsdf"
- Key: "someOtherTag"
Value: "sdfsdfsdfsdf"
# Only apply this tag if InDevEnvironment is true
- !If
- InDevEnvironment
-
- Key: "shouldNotEvenExistIfInProd"
Value: "sdfsdfsdfsdfsdfsdfdsf"
- !Ref "AWS::NoValue
I get an error: Value of property Tags must be a list of objects
Cloudformation syntax has never been very intuitive to me, do I have the hyphen wrong or something?
I think the reason is that it does not work is due to indentation issues and non-needed double list use. I modified the code below:
Tags:
- Key: "sometag"
Value: "sdfsdfsdfsdf"
- Key: "someOtherTag"
Value: "sdfsdfsdfsdf"
- !If
- InDevEnvironment
- Key: "shouldNotEvenExistIfInProd"
Value: "sdfsdfsdfsdfsdfsdfdsf"
- !Ref "AWS::NoValue

Update AWS Athena workgroup using CloudFormation template

I have 2 templates those I have taken from the AWS::Athena::WorkGroup - AWS CloudFormation documentation.
The first template athena_create.yaml works as expected. The second template needs to modify the workgroup created in the first template. But I get an error:
MyCustomWorkGroup already exists in stack
arn:aws:cloudformation:us-east-1:XXX:stack/a1/7cc670a0-8d19-11ea-872c-12217e59f19f
Here is the code. create template works correctly.
athena_create.yaml
Resources:
MyAthenaWorkGroup:
Type: AWS::Athena::WorkGroup
Properties:
Name: MyCustomWorkGroup
Description: My WorkGroup
State: ENABLED
Tags:
- Key: "key1"
Value: "value1"
- Key: "key2"
Value: "value2"
WorkGroupConfiguration:
BytesScannedCutoffPerQuery: 200000000
EnforceWorkGroupConfiguration: false
PublishCloudWatchMetricsEnabled: false
RequesterPaysEnabled: true
ResultConfiguration:
OutputLocation: s3://path/to/my/bucket/
athena_update.yaml
Resources:
MyAthenaWorkGroup:
Type: AWS::Athena::WorkGroup
Properties:
Name: MyCustomWorkGroup
Description: My WorkGroup Updated
State: DISABLED
Tags:
- Key: "key1"
Value: "value1"
- Key: "key2"
Value: "value2"
WorkGroupConfigurationUpdates:
BytesScannedCutoffPerQuery: 10000000
EnforceWorkGroupConfiguration: true
PublishCloudWatchMetricsEnabled: true
RequesterPaysEnabled: false
ResultConfigurationUpdates:
EncryptionConfiguration:
EncryptionOption: SSE_S3
OutputLocation: s3://path/to/my/bucket/updated/
The update template mentioned above does not work as expected.
The reason for the error is that the two templates were used to create two independent stacks. This didn't work because they two Athena WorkGroups of same Name: MyCustomWorkGroup.
The correct way to perform create and update the MyCustomWorkGroup is as follows:
Create a stack using athena_create.yaml file.
Once the stack is created, use its Update option to upload athena_update.yaml which is going to update the stack.

How to get the ARN of an SSM Document in CloudFormation?

I have a CloudFormation template that creates an AWS::Events::Rule and an AWS::SSM::Document. I need to provide a list of Targets for the SSM::Rule, but each target expects an ARN:
mySSMDocument:
Type: AWS::SSM::Document
Properties:
DocumentType: 'Command'
Content:
schemaVersion: '2.2'
description: "Code that will be run on EC2"
mainSteps:
- action: "aws:runShellScript"
name: runShellScript
inputs:
runCommand:
- 'Some command to execute'
myEventRule:
Type: AWS::Events::Rule
Properties:
Description: "A description for the Rule."
EventPattern:
source:
- "aws.autoscaling"
detail-type:
- "EC2 Instance-terminate Lifecycle Action"
detail:
AutoScalingGroupName:
- !Ref 'someAutoScalingGroupInThisTemplate'
RoleArn: 'some role ARN'
State: "ENABLED"
Targets:
- Id: "some-unique-id"
Arn: <-- This is the value that I need to fill in.
RunCommandParameters:
RunCommandTargets:
- Key: "tag: Name"
Values:
- 'The name of the EC2 machine'
I think that I need to replace the <-- This is the value that I need to fill in. with the ARN of mySSMDocument, but I don't see any way to retrieve this value from within the template itself. The documentation does not specify any GetAtt functionality on SSM::Document that allows to get the ARN. Anyone know how to solve this issue?
This is ARN pattern of Document
arn:${Partition}:ssm:${Region}:${Account}:document/${DocumentName}
example:
arn:aws:ssm:us-east-2:12345678912:document/demoooo
You can use Ref function to get name of document, then Sub to create final ARN
refer: https://docs.aws.amazon.com/IAM/latest/UserGuide/list_awssystemsmanager.html#awssystemsmanager-resources-for-iam-policies
!Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:document/${mySSMDocument}
You can produce the ARN format for AWS::SSM::Document using the return Value for AWS::SSM::Document, the Pseudo Parameters for Partition, Region, and AccountId, and the Sub intrinsic function

Multiple tag groups for CodeDeploy in Cloudformation in YAML

I'm having a hard time trying to figure out how to add multiple tag groups for CodeDeploy in Cloudformation via YAML.
Here is a example in JSON for Mutiple tag groups with single tag for ec2TagFilters. I know how to create multiple tags in the same tag group, but I can't seem to figure out how to create multiple tag groups using YAML.
Can someone help?
Thank you.
When you're having problems converting between JSON and YAML, you should use tools like this website to help you. I plugged in the documentation you reference, and this is what I got:
ec2TagSetList:
- - Key: KEY_AND_VALUE
Type: Name
Value: AppVersion-ABC
- - Key: KEY_AND_VALUE
Type: Region
Value: North
- - Key: KEY_AND_VALUE
Type: Type
Value: t2.medium
The AWS Documentation is really frustrating here...
First, case is inconsistent across documentation:
"ec2TagSetList" they frequently start with lowercase in documentation (which is incorrect)
"Ec2TagSetList" is what you want to use
That said, there is even more inconsistency where the documentation above is just wrong with the syntax...
This is the correct syntax for a single tag group:
ResourceNameHere:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
...
Ec2TagSet:
Ec2TagSetList:
- Ec2TagGroup:
- Type: KEY_AND_VALUE
Key: "Tag1Key"
Value: "Tag1Value"
- Type: KEY_AND_VALUE
Key: "Tag2Key"
Value: "Tag2Value"
...
If you want to configure multiple tag groups just add another Ec2TagGroup:
ResourceNameHere:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
...
Ec2TagSet:
Ec2TagSetList:
- Ec2TagGroup:
- Type: KEY_AND_VALUE
Key: "Tag1Key"
Value: "Tag1Value"
- Type: KEY_AND_VALUE
Key: "Tag2Key"
Value: "Tag2Value"
- Ec2TagGroup:
- Type: KEY_AND_VALUE
Key: "Tag3Key"
Value: "Tag3Value"
- Type: KEY_AND_VALUE
Key: "Tag4Key"
Value: "Tag4Value"
...