Create Secrets Manager using CloudFormation but keeping values not visible - amazon-web-services

I have a CloudFormation template to create a Secret in Secrets Manager. My current template is similar to this (based on aws documentation https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-secret.html):
{
"Resources": {
"MyCredentials": {
"Type": "AWS::SecretsManager::Secret",
"Properties": {
"Name": "prod/web/api",
"Description": "",
"SecretString": "{
\"Client_id\":\"my_client_id\",
\"Client_secret\":\"a_super_secret_value\"
}"
}
}
}
}
My problem is that I can not use the GenerateSecretString property because the password is defined from an external organization so I can not change or create the value on my own and in this way the secret value can be viewed from the template in CloudFormation.
Is possible to achieve this or I need to create the secrets manually?

You can use AWS SSM Parameter, where the external organization has given permissions to add/update password there or someone in the team do the same.
Once the password is there, you read in your cloudformation template either via dynamic references like below,
The following example uses an ssm-secure dynamic reference to set the password for an IAM user to a secure string stored in Systems Manager Parameter Store. As specified, CloudFormation will use version 10 of the IAMUserPassword parameter for stack and change set operations.
"MyIAMUser": {
"Type": "AWS::IAM::User",
"Properties": {
"UserName": "MyUserName",
"LoginProfile": {
"Password": "{{resolve:ssm-secure:IAMUserPassword:10}}"
}
}
}
Or static reference something like below :
here Accessing the AvailabilityZone param stored in SSM.
"AvailabilityZone": {
"Description": "Amazon EC2 instance Availablity Zone",
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "AvailabilityZone"
}
More examples in Using AWS Systems Manager Parameter Store Secure String parameters in AWS CloudFormation templates

Related

aws cloudformation WAF geo location condition

Trying to create a cloud formation template to configure WAF with geo location condition. Couldnt find the right template yet. Any pointers would be appreciated.
http://docs.aws.amazon.com/waf/latest/developerguide/web-acl-geo-conditions.html
Unfortunately, the actual answer (as of this writing, July 2018) is that you cannot create geo match sets directly in CloudFormation. You can create them via the CLI or SDK, then reference them in the DataId field of a WAFRule's Predicates property.
Creating a GeoMatchSet with one constraint via CLI:
aws waf-regional get-change-token
aws waf-regional create-geo-match-set --name my-geo-set --change-token <token>
aws waf-regional get-change-token
aws waf-regional update-geo-match-set --change-token <new_token> --geo-match-set-id <id> --updates '[ { "Action": "INSERT", "GeoMatchConstraint": { "Type": "Country", "Value": "US" } } ]'
Now reference that GeoMatchSet id in the CloudFormation:
"WebAclGeoRule": {
"Type": "AWS::WAFRegional::Rule",
"Properties": {
...
"Predicates": [
{
"DataId": "00000000-1111-2222-3333-123412341234" // id from create-geo-match-set
"Negated": false,
"Type": "GeoMatch"
}
]
}
}
There is no documentation for it, but it is possible to create the Geo Match in serverless/cloudformation.
Used the following in serverless:
Resources:
Geos:
Type: "AWS::WAFRegional::GeoMatchSet"
Properties:
Name: geo
GeoMatchConstraints:
- Type: "Country"
Value: "IE"
Which translated to the following in cloudformation:
"Geos": {
"Type": "AWS::WAFRegional::GeoMatchSet",
"Properties": {
"Name": "geo",
"GeoMatchConstraints": [
{
"Type": "Country",
"Value": "IE"
}
]
}
}
That can then be referenced when creating a rule:
(serverless) :
Resources:
MyRule:
Type: "AWS::WAFRegional::Rule"
Properties:
Name: waf
Predicates:
- DataId:
Ref: "Geos"
Negated: false
Type: "GeoMatch"
(cloudformation) :
"MyRule": {
"Type": "AWS::WAFRegional::Rule",
"Properties": {
"Name": "waf",
"Predicates": [
{
"DataId": {
"Ref": "Geos"
},
"Negated": false,
"Type": "GeoMatch"
}
]
}
}
I'm afraid that your question is too vague to solicit a helpful response. The CloudFormation User Guide (pdf) defines many different WAF / CloudFront / R53 resources that will perform various forms of geo match / geo blocking capabilities. The link you provide seems a subset of Web Access Control Lists (Web ACL) - see AWS::WAF::WebACL on page 2540.
I suggest you have a look and if you are still stuck, actually describe what it is you are trying to achieve.
Note that the term you used: "geo location condition" doesn't directly relate to an AWS capability that I'm aware of.
Finally, if you are referring to https://aws.amazon.com/about-aws/whats-new/2017/10/aws-waf-now-supports-geographic-match/, then the latest Cloudformation User Guide doesn't seem to have been updated yet to reflect this.

How to pass a VPC's ID as a parameter to the Cluster.template to set as a default value?

I am trying to find a way to set default VPCs, Subnets and Security Groups in the Cluster.template JSON file.
Is there a way to pass an existing VPC ( or Subnet/Security group) as a parameter to the template using the "Ref" built-in?
This Obviously dones't work:
"Parameters": {
"VpcId": {
"Type": "AWS::EC2::VPC::Id",
"Default": { "Ref" : "vpc-123456789" },
....
}
To inject a VPC id into your template I would do the following. First remove your default value.
"Parameters": {
"VpcId": {
"Type": "AWS::EC2::VPC::Id"
....
}
Next place the value you want to set VpcId to inside a parameters.json file and when you perform a create-stack or update-stack using your cloudformation use the parameters file as the input.
parameters.json
[
{
"ParameterKey": "VpcId",
"ParameterValue": "vpc-123456789"
}
]
Multi-valued Parameters
If you had a parameter that takes a list of values you could represent it as follows
"PrivateEC2Subnets": {
"Type": "CommaDelimitedList",
"Description": "List of private subnets to run your EC2 instances inside. Note that they must be in the same availability zone that your ELB is configured for. May require you to manually create a private subnet with a specific AZ if your VPC isnt auto-configured."
},
Then in your external parameters file pass in a comma separated list like so
{
"ParameterKey": "PrivateEC2Subnets",
"ParameterValue": "subnet-9934670a544,subnet-d74ea349f"
},
For more information on the different parameter types see the AWS doc http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html but beware, people have reported issues when trying to represent lists of complex datatypes in external parameters files. To my knowledge, only CommaDelimitedList works if you want to pass the values in from another json file outside your cloudformation template.
I found out that it's really much simpler than I thought... this worked:
"Parameters": {
"VpcId": {
"Type": "List<AWS::EC2::VPC::Id>",
"Default": "vpc-123456789,vpc-987654123" ,
....
}

Parameter validation failed: parameter value for parameter name <some parameter> does not exist

Any suggestions why this AWS CloudFormation keeps rolling back?
{
"Description" : "Single Instance",
"Resources" : {
"EC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"ImageId" : "ami-b73b63a0",
"InstanceType" : "t2.micro",
"KeyName" : "aws-key-here",
"Tags" : [
{
"Key" : "Name",
"Value" : "test"
}
],
"SubnetId" : {
"Fn::Select" : [ "0", { "Ref" : "Subnets" } ]
}
}
}
},
"Parameters": {
"Subnets": {
"Type": "List<AWS::EC2::Subnet::Id>",
"Description": "The list of SubnetIds, for at least two Availability Zones in the region in your Virtual Private Cloud (VPC)"
}
}
}
The specific error seems to be about the Subnets Ref:
Parameter validation failed: parameter value for parameter name Subnets does not exist. Rollback requested by user.
I have already created 1 valid Subnet in my AWS Management Console and tested that it works when spinning up an EC2 Instance manually.
Or is there a way of debugging this / getting more detailed output?
The Subnets Parameter in your template has a type List<AWS::EC2::Subnet::Id>, which requires a reference to a list of valid Subnet IDs. The error you are seeing means that you passed at least one invalid Subnet ID to the Subnet parameter.
If you're deploying your stack from the AWS CLI using aws cloudformation create-stack, you need to pass a valid parameter value using the --parameters ParameterKey=Subnets,ParameterValue=subnet-12345678 option.
If you're deploying from the Management Console, you need to specify stack parameters using the provided dialog, and select a Subnet ID from the drop-down list.
I faced the same problem. In my case I created the Key with name "mykey" in Mumbai Region. But when I actually started creating a Cloud Formation Infrastructure I changed the region to US-East. Now in my Cloud Formation Infrastructure I provided the name of Key as "mykey". Now the problem is the key "mykey" was created in Mumbai Region.
Hence I create the Key once again in "US-East" region and my problem vanished.
Regards
Hitesh
In my case it was a problem on credentials key and access key. My default values were another accounts one and I was trying to create a stack on a wrong account.

How can we reuse configured AMI in the same template with the same userdata configs

I have created instance using cloudformation template, configured it with userdata configuration and powershell dsc. I have created AMI for this instance so that next time it speeds up my stack creation.
Now how can i use the this AMI in that same template so it bypass all the configurations & installation done on instance and directly sends success signal to waithandler.
I am trying this in my template but it is failing.
Thanks in Advance,
Lokesh Jangir
It sounds like you need a check in your user data to see if everything is already configured, and if it is, then you just stop and send the notification instead of setting it back up again.
Ultimately, it sounds like it'd be easier to have two templates - one to create the AMI, and one to re-use it in other settings. The second template could take the AMI ID as a parameter so that it is more flexible and can be used with different AMIs as you create them.
1. To use your AMI id in the cloudformation template, start with adding a parameter, so that you can easily change it:
`
"Parameters": {
...
"amiId": {
"Type": "String",
"Default": "ami-073bb070",
"AllowedPattern": "[a-zA-Z0-9\\-]*",
"Description": "Only [a-zA-Z0-9\\-]* allowed."
},
...
}
2. Use that param in a LaunchConfig:
`
"aLaunchConfig": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Properties": {
"ImageId": { "Ref" : "amiId" },
...
3. or use it directly in an EC2 instance:
`
"someEC2": {
"Type": "AWS::EC2::Instance",
"Properties": {
"ImageId": { "Ref" : "amiId" },

How to get username in AWS Cloudformation template file?

I have resources defined in my Cloudformation template file with tags defined like so:
"Properties": {
"Tags": [
{ "Key": "Environment", "Value": {"Ref": "Environment"}},
{ "Key": "Hello", "Value": "World"}
]
}
My IAM username is my.name. I would like to add a key named Creator to the Tags property with value my username (my.name). Moreover, I need this value to reflect the username of whoever runs this Cloudformation template. How can I do it?
I am not aware of any way of referencing the IAM username directly from the template JSON.
However, you can use get-user to get the username (either using the CLI or one of the SDKs), and then pass it on to CloudFormation as a parameter, or, if you are creating the template JSON programmatically, just insert it directly.
You should pass the user ID as a parameter on the create-template API call and add it to the tags using Fn::Join. Cloudformation won't do this for you.