Cloudformation remove dashes from parameters - amazon-web-services

I'm trying to run a nested stack with the root stack that creates multiple resources including S3 buckets and a Cognito User Pool. The issue is:
S3 bucket name doesn't allow Capitalised letters.
Cognito Identity Pool name doesn't allow dashes -.
I want to name my resources with the same/similar name ${AWS::StackName}-then-some-string so they're recognised as parts of one application.
Is there a way to remove dashes from parameters inside cloudformation? I know I can use Fn::Split to split the string with - then use Fn::Select to select specific elements then Fn::Join but that will only work for a stack name with a certain amount of dashes -.
I can't find any resource anywhere on how to change the - to empty string or something else using some sort of function or regex.

You're nearly there - use Fn::Split and Fn::Join, no select needed.
SomeKey:
Fn::Join:
- ''
- Fn::Split:
- '-'
- !Ref YourParam
Split returns an array. Join takes a join string and an array of items to join. So just split on the hyphen/dash, then join the parts back together with an empty string, thereby eliminating the hyphens.

Related

CommaDelimitedList for ACM Subject Alternative Names

Writing a CFN for ACM, but don't know the difference between
CommaDelimitedList and List<CommaDelimitedList>
According to the aws doc
https://docs.amazonaws.cn/en_us/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
CommaDelimitedList
An array of literal strings that are separated by commas. The total number of strings should be one more than the total number of commas. Also, each member string is space trimmed.
For example, users could specify "test,dev,prod", and a Ref would result in ["test","dev","prod"].
So what is the difference between them
SubjectAlternativeName:
Type: List<CommaDelimitedList>
Description: Alternative sub-domain names that will be covered in your certificate.
So in the actual input when creating the resource, what should be the data for correct type?
Is below correct? for CommaDelimitedList or ?
Answer to my question:
They can be used interchangeably
List<CommaDelimitedList> and CommaDelimitedList
Also 'List<String>'
In term of the input for these types List<CommaDelimitedList> and CommaDelimitedList
Example as below

Azure blob storage regex pattern for user input validation

I’ve developed a function in PowerShell (.NET Framework) to retrieve data from any given Azure Blob Storage: so far, so good.
When it comes down to validate users’ input, unfortunately, I cannot rely on external modules or libraries such as the NameValidator Class of Azure SDK for .NET.
Nevertheless, the article Naming and Referencing Containers, Blobs, and Metadata goes into the details of naming rules and thus regex patterns might come to the rescue.
For Container Names I’ve came up with this, and it seems to fit:
(?=^.{3,63}$)(?!.*--)[^-][a-z0-9-]*[^-]
Container Names
A container name must be a valid DNS name, conforming to the following
naming rules:
Container names must start or end with a letter or number, and can contain only letters, numbers, and the dash (-) character.
Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in
container names.
All letters in a container name must be lowercase.
Container names must be from 3 through 63 characters long.
For Blob Names however I’m not able to get around the counting of path segments:
(?=^.{1,1024}$)(?<=^|\/)(\S*?)[^\.] (?=\/|$)
NB: the Azure Storage emulator has been deprecated and therefor out of scope.
Blob Names
A blob name must conforming to the following naming rules:
A blob name can contain any combination of characters.
A blob name must be at least one character long and cannot be more than 1,024 characters long, for blobs in Azure Storage.
The Azure Storage emulator supports blob names up to 256 characters long. For more information, see Use the Azure storage emulator for
development and testing.
Blob names are case-sensitive.
Reserved URL characters must be properly escaped.
The number of path segments comprising the blob name cannot exceed 254. A path segment is the string between consecutive delimiter characters (e.g., the forward slash '/') that corresponds to the name
of a virtual directory.
Note Avoid blob names that end with a dot (.), a forward slash (/), or a sequence or combination of the two. No path segments should end
with a dot (.).
The Blob service is based on a flat storage scheme, not a hierarchical scheme. However, you may specify a character or string delimiter within a blob name to create a virtual hierarchy. For example, the following list shows valid and unique blob names. Notice that a string can be valid as both a blob name and as a virtual directory name in the same container:
/a
/a.txt
/a/b
/a/b.txt
You can take advantage of the delimiter character when enumerating blobs.
NB: Just before asking this question, I’ve found this ones that answer what I’ve already solved on my own or use the aforementioned class:
Azure Container Name RegEx
How to validate Azure storage blob names
By the way, does anybody know which flavor of regex is used by PowerShell?
You need to use
^(?!.{1025})/?[^/]*[^/.](?:/[^/]*[^/.]){0,253}$
^(?=.{1,1024}$)/?[^/]*[^/.](?:/[^/]*[^/.]){0,253}$
See the regex demo.
Details:
^ - start of string
(?=.{1,1024}$) - the string should contain from 1 to 1024 chars
(?!.{1025}) - the string cannot contain more than 1025 chars
/? - an optional /
[^/]*[^/.] - zero or more chars other than / and then a char other than / and .
(?:/[^/]*[^/.]){0,253} - zero to 253 occurrences of / followed by zero or more chars other than / and then a char other than / and .
$ - end of string.

Regex Expression to replace email address domain, for users email address

I am trying to solve an email domain co-existence problem with Exchange online. Basically i need it so when a message is sent to one tenant (domain.com) and forwarded to another tenant (newdomain.com) - that the To and/or CC headers are replaced with the endpoint (newdomain.com) email addresses before they are delivered to the final destination.
For Example:
1) Gmail (or any) user sends and email to sally.sue#domain.com, MX is looked up for that domain, it is delivered to the Office 365 Tenant for domain.com
2) That same office 365 tenant, is set to forward emails to sally.sue#newdomain.com (different tenant)
3) When the message arrives to sally sue at newdomain.com and she hits "Reply All" the original sender AND her (sally.sue#domain.com) are added to the To: line in the email.
The way to fix that is to use Header Replacement with Proofpoint, which as mentioned below works on a single users basis. The entire question below is me trying to get it to work using RegEx (As thats the only solution) for a large number of users.
I need to convert the following users email address:
username#domain.com to username#newdomain.com
This has to be done using ProofPoint which is a cloud hosted MTA. They have been able to provide some sort of an answer but its not working.
Proofpoint support has suggested using this:
Header Name : To
Find Value : domain\.com$
Replace : newdomain\.com$ or just newdomain.com
Neither of the above work. In both cases the values are just completely ignored.
This seems to find the values:
Header Name : To
Find Value : \b[A-Z0-9._%-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b
Replace : $1#fake.com
But the above simply and only replaces the To: line (in the email) with the literal string: $1#fake.com
I would also need to be able to find lowercase and numbers in email addresses as well. i believe the above example only finds caps.
I need it do the following:
Header Name : To
Find Value : \b[A-Z0-9._%-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b (find users email address, domain)
Replace : user.name#newdomain.com
This is for a large number of users so there is no way to manually update or create separate rules for each user.
If i do create a individual rule, then it works as expected but as stated that requires manually typing out each user To: address And their new desired To: address.
This solution here almost worked: Regex to replace email address domains?
I have a couple of observations from general experience, although I have not worked with Office365 specifically.
First, a regex used for replacement usually needs to have a "capture group". This is often expressed with parentheses, as in:
match : \b([A-Z0-9._%-]+)#domain.com$
replacement : $1#newdomain.com
The idea is that the $1 in the replacement pattern is replaced with whatever was found within the () in the matching pattern.
Note that some regex engines use a different symbol for the replacement, so it might be \1#newdomain.com or some such. Note also that some regex engines need the parentheses escaped, so the matching pattern might be something like \b\([A-Z0-9._%-]+\)#domain.com$
Second, if you want to include - inside a "character class" set (that is, inside square brackets []), then the - should be first; otherwise it's ambiguous because - is also used for a range of characters. The regex engine in question might not care, but I suggest writing your matching pattern as:
\b([-A-Z0-9._%]+)#domain.com$
This way, the first - is unambiguously itself, because there is nothing before it to indicate the start of a range.
Third, for lowercase letters, it's easiest to just expand your character class set to include them, like so:
[-A-Za-z0-9._%]

AWS IAM - Safely concatenate generated Access Key ID and Secret Access Key

I want to concatenate my Access Key ID and Secret Access Key together so I can easily rotate the credentials with Azure Key Vault. I'm having trouble finding out which characters will not be used by either the generated Access Key ID or the Secret Access Key to keep them separated in the concatenated string. Is it safe to use a semicolon or a colon?
Edit: https://docs.aws.amazon.com/IAM/latest/APIReference/API_AccessKey.html indicates that the Access Key ID can contain any nonspace character, although I'm not sure if generated IDs are more limited in practice. Unfortunately, no guidelines are given for Secret Access Keys. Is a space a reasonable separator?
Amazon actually provide regular expressions for searching for access keys and secret access keys in this article, which we can use to tell what characters are used:
Search for access key IDs: (?<![A-Z0-9])[A-Z0-9]{20}(?![A-Z0-9]). In English, this regular expression says: Find me 20-character, uppercase, alphanumeric strings that don’t have any uppercase, alphanumeric characters immediately before or after.
Search for secret access keys: (?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=]). In English, this regular expression says: Find me 40-character, base-64 strings that don’t have any base 64 characters immediately before or after.
So letters and numbers in the access key and those plus the characters /+= could appear in the secret key. This means a semicolon or a colon would be safe choices for a separator.

Fast string matching algorithm with simple wildcards support

I need to match input strings (URLs) against a large set (anywhere from 1k-250k) of string rules with simple wildcard support.
Requirements for wildcard support are as follows:
Wildcard (*) can only substitute a "part" of a URL. That is fragments of a domain, path, and parameters. For example, "*.part.part/*/part?part=part&part=*". The only exception to this rule is in the path area where "/*" should match anything after the slash.
Examples:
*.site.com/* -- should match sub.site.com/home.html, sub2.site.com/path/home.html
sub.site.*/path/* -- should match sub.site.com/path/home.html, sub.site.net/path/home.html, but not sub.site.com/home.html
Additional requirements:
Fast lookup (I realize "fast" is a relative term. Given the max 250k rules, still fall within < 1.5s if possible.)
Work within the scope of a modern desktop (e.g. not a server implementation)
Ability to return 0:n matches given a input string
Matches will have rule data attached to them
What is the best system/algorithm for such as task? I will be developing the solution in C++ with the rules themselves stored in a SQLite database.
First of all, one of the worst performing searches you can do is with a wildcard at both ends of the string ".domain.com/path" -- and I think you're going to hit this case a lot. So my first recommendation is to reverse the order of the domains as they're stored in your DB: com.domain.example/path1/path2/page.html. That will allow you to keep things much more tidy and only use wildcards in "one direction" on the string, which will provide MUCH faster lookups.
I think John mentions some good points about how to do this all within your DB. If that doesn't work I would use a regex library in C++ against the list. I bet you'll get the best performance and most general regex syntax that way.
If I'm not mistaken, you can take string rule and break it up into domain, path, and query pieces, just like it's a URL. Then you can apply a standard wildcard matching algorithm with each of those pieces against the corresponding pieces from the URLs you want to test against. If all of the pieces match, the rule is a match.
Example
Rule: *.site.com/*
domain => *.site.com
path => /*
query => [empty]
URL: sub.site.com/path/home.html
domain => sub.site.com
path => /path/home.html
query => [empty]
Matching process:
domain => *.site.com matches sub.site.com? YES
path => /* matches /path/home.html? YES
query => [empty] matches [empty] YES
Result: MATCH
As you are storing the rules in a database I would store them already broken into those three pieces. And if you want uber-speed you could convert the *'s to %'s and then use the database's native LIKE operation to do the matching for you. Then you'd just have a query like
SELECT *
FROM ruleTable
WHERE #urlDomain LIKE ruleDomain
AND #urlPath LIKE rulePath
AND #urlQuery LIKE ruleQuery
where #urlDomain, #urlPath, and #urlQuery are variables in a prepared statement. The query would return the rules that match a URL, or an empty result set if nothing matches.