Cloudformation security group set group name - amazon-web-services

Using cloudformation SecurityGroup is possible set the GroupName or has to be provide by cloudformation?.
The final name format it´s pretty long and does not look nice, also is not a good match to use it for find it by command line.
I know I can use tags, but still don't understand why AWS don't allow us to add it, I guess because they´re lazy and they don't want to implement a validation.
Regards.

You can set the name for a SecurityGroup by adding a Tag with the key "Name", like this:
"MySecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Allow http",
"SecurityGroupIngress": [
{"IpProtocol": "tcp", "FromPort": "80", "ToPort": "80", "CidrIp": "0.0.0.0/0"}
],
"Tags": [
{"Key": "Name", "Value": "MySecurityGroup"},
]
}
},

[Updated Jun 26 2017]
As of Apr 28 2017, it is now possible to specify a custom name for an EC2 Security Group using CloudFormation, using the GroupName property on the AWS::EC2::SecurityGroup resource.
Thanks surenyonjan for the comment on this update.
[Original answer Dec. 23 2016] -
No, it is not currently possible to provide a custom name for an EC2 Security Group using CloudFormation.
According to the AWS::EC2::SecurityGroup resource documentation, there is no Name or GroupName property available. You can provide tags using the Tags property as an alternative, as you pointed out.
Recently, some CloudFormation resources have started supporting custom names via a Name property. A full list of supported resources is in the Name Type section of the documentation.
AWS::EC2::SecurityGroup is not one of the resources supporting custom names. As for why, presumably this is because this CloudFormation resource is an earlier implementation, created before custom names were supported by the service.
It's possible that AWS will eventually go back and update all of its existing CloudFormation resources with custom name support at some point, if enough users ask them to do so. If this is an important/critical feature for your use case, I'd recommend contacting their product/support teams with a feature request to help them make it higher priority.

The name of most resources is simply a type of special Tags with the Key Name, To edit this fields just add the tag to the template
mySecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: !Ref myVPC
GroupDescription: Security Group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: mySecurityGroup

Related

Cloudformation: "No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC"

I am trying to deploy an EC2 instance using Cloudformation but getting the following error:
No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC
despite having the vpc explicitly set on the security group:
"InstanceSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupName": "SG-AD-TSDB",
"GroupDescription" : "Enable SSH access via port 22",
"VpcId": "vpc-<private>",
"SecurityGroupIngress" : [ {
"IpProtocol" : "tcp",
"FromPort" : "22",
"ToPort" : "22",
"CidrIp" : { "Ref" : "SSHLocation"}
} ]
}
}
I have no clue what to do with this error.
I got the same error.
I don't know the real reason, though removing the default VPC and recreating it solved the issue in my case.
If you cannot remove the default VPC, then you should use Admin account to do that.
I believe GroupName is legacy prop used for old-fashion VPC. Just delete it, name field in SG listing seems to be copied from GroupDescription in my cloud.
As Marcin commented, I believe the problem is in the AWS::EC2::Instance declaration. I also had this error and only after adding SubnetId property to the NetworkInterfaces property of the instance I succeed to deploy the stack without errors. I added this property after I had encountered this clarification.
The full yaml code is:
---
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy a simple Amazon Linux Instance and allow SSH connectivity.
Parameters:
KeyName:
Description: EC2 Key Pair for SSH Access, you must have created these prior to
running this.
Type: AWS::EC2::KeyPair::KeyName
VpcId:
Description: 'Please insert one of your VPC ID. you can find this info in the
VPC console '
Type: AWS::EC2::VPC::Id
ImageId:
Description: 'Please insert an Image ID of the AMI you want to use. Leave the field unchanged to use the default Amazon Linux AMI'
Type: String
Default: ami-05ff5eaef6149df49
SubnetId:
Description: 'Please choose a Subnet Id'
Type: AWS::EC2::Subnet::Id
Resources:
SimpleInstance:
Type: AWS::EC2::Instance
Properties:
KeyName:
Ref: KeyName
InstanceType: t2.micro
ImageId: !Ref ImageId
NetworkInterfaces:
- GroupSet:
- Ref: SimpleInstanceSg
SubnetId:
Ref: SubnetId
AssociatePublicIpAddress: true
DeviceIndex: '0'
DeleteOnTermination: true
SimpleInstanceSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access via port 22
VpcId:
Ref: VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
The original code (without the SubnetId declaration) has taken from here. Note that even the original code does not include any GroupName declaration I had exactly the same error.
While deleting just provide the Security group Id.
GroupName (string) -- [EC2-Classic, default VPC] The name of the security group. You can specify either the security group name or the security group ID. For security groups in a nondefault VPC, you must specify the security group ID.
For reference see below is example, (Example 3 is for successful deletion)
import boto3
ec2Client=boto3.client('ec2', region_name='us-west-1')
sgName='vsm'
sgId='sg-03a4977aea20a2b6d'
##example 1- with SgId and SgName (FAILED)
response=ec2Client.delete_security_group(GroupId=sgId, GroupName=sgName)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 391, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 719, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (VPCIdNotSpecified) when calling the DeleteSecurityGroup operation: No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC.
##example 2- with SgName (FAILED)
response=ec2Client.delete_security_group(GroupName=sgName)
response
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 391, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 719, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (VPCIdNotSpecified) when calling the DeleteSecurityGroup operation: No default VPC for this user. GroupName is only supported for EC2-Classic and default VPC.
##example 3- with SgId (Successful)
response=ec2Client.delete_security_group(GroupId=sgId)
response
{'ResponseMetadata': {'RequestId': '3f2f2b56-d072-41ce-b89a-ccd576ce0189', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '3f2f2b56-d072-41ce-b89a-ccd576ce0189', 'cache-control': 'no-cache, no-store', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'content-type': 'text/xml;charset=UTF-8', 'content-length': '239', 'date': 'Fri, 14 Oct 2022 06:04:26 GMT', 'server': 'AmazonEC2'}, 'RetryAttempts': 0}}
Reference:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.delete_security_group

What does the secret have to contain for `AWS::RDS::DBProxy AuthFormat`

To create an AWS::RDS::DBProxy using CloudFormation, you need to provide a SecretsManager Secret as the authentication method. In the below example, it's the secret pointed to by BootstrapProxySecretArn:
Resources:
TestDBProxy:
Type: AWS::RDS::DBProxy
Properties:
DBProxyName: !Ref ProxyName
EngineFamily: MYSQL
RoleArn:
!Ref BootstrapSecretReaderRoleArn
Auth:
- {AuthScheme: SECRETS, SecretArn: !Ref BootstrapProxySecretArn, IAMAuth: DISABLED}
VpcSubnetIds:
But the CloudFormation docs don't explain what this secret needs to contain. Is it a secret containing the password for that database username?
The templates for different databases for secrete manager are here. For MySQL it would be:
{
"engine": "mysql",
"host": "<required: instance host name/resolvable DNS name>",
"username": "<required: username>",
"password": "<required: password>",
"dbname": "<optional: database name. If not specified, defaults to None>",
"port": "<optional: TCP port number. If not specified, defaults to 3306>"
}
Alternatively, you can always use AWS console to create the secret automatically for you for your database, and inspect its structure which then you can re-use in CloudFormation.

How to create an AWS SFTP server with internet-facing VPC endpoint with Cloudformation?

I am able to create an SFTP Server (AWS Transfer Family) inside a VPC with an internet-facing Endpoint on AWS console as described here: https://docs.aws.amazon.com/transfer/latest/userguide/create-server-in-vpc.html
VPC endpoint type access selection
Now, I need to replicate that very same creation in a CloudFormation template and don't know how to do it (if possible). According to what I see in https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-transfer-server-endpointdetails.html and in the corresponding CDK docs https://docs.aws.amazon.com/cdk/api/latest/docs/#aws-cdk_aws-transfer.CfnServer.EndpointDetailsProperty.html, there seems not to be a was to set the "access" property value.
All the examples I've come across use a PUBLIC endpoint (in contrast to a VPC one). Here's the snipped I'm working on:
"Resources": {
"ftpserver": {
"Type": "AWS::Transfer::Server",
"DependsOn": "sftpEIP1",
"Properties": {
"EndpointDetails": {
"SubnetIds": [
{
"Ref": "sftpSubnet1"
}
],
"VpcId": {
"Ref": "sftpVPC"
}
},
"EndpointType": "VPC",
"Protocols": [
"SFTP"
],
"Tags": [
{
"Key": "KeyName",
"Value": "ValueName"
}
]
}
}
},
...
}
Since there is no way to set the access type in CloudFormation, the endpoint ends up created as "Internal" instead of "Internet-facing" which is what I need.
Is there any way around this or should I just change it manually (AWS console) after every deployment?
You need to associate Elastic IPs and define the security group.
Notice because the Elastic IPs can only be added after the server is created, it takes sometime to complete, CloudFormation actually creates the server with internal only, stops the server, adds the Elastic IPs, it starts again with elastic IPs and internet facing and then stack is completed.
Example with the CF template below works as expected.
Description: Test CF with FTP server
Resources:
ElasticIP1:
Type: AWS::EC2::EIP
ElasticIP2:
Type: AWS::EC2::EIP
ElasticIP3:
Type: AWS::EC2::EIP
FTPServer:
Type: AWS::Transfer::Server
Properties:
EndpointDetails:
AddressAllocationIds:
- !GetAtt ElasticIP1.AllocationId
- !GetAtt ElasticIP2.AllocationId
- !GetAtt ElasticIP3.AllocationId
SecurityGroupIds:
- sg-0c4184c3f5da91d4a
SubnetIds:
- subnet-0546e2c78cebd0a60
- subnet-0114560b841c91de7
- subnet-0af8fb5fae5472862
VpcId: vpc-07daf77a355f5a8e8
EndpointType: VPC
Protocols:
- SFTP

CloudFormation AWS::CertificateManager::Certificate automated certificate validation

According the AWS docs at here and here I should be able to automate a certificate creation and validation using cloudformation. Apparently when you specify a HostedZoneId in the DomainValidationOptions, it is supposed to create the required DNS record to complete the validation (at least that is what it seems from the very vague documentation). My CF template for the cert looks like this:
Resources:
MyAPICert:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: xxxx.dev.mydomain.io
DomainValidationOptions:
- DomainName: mydomain.io
HostedZoneId: /hostedzone/Z03XXXXXXXXXXXX
ValidationMethod: DNS
'mydomain.io' (changed of course) was registered using AWS as registrar as the documents say must be the case for automated validation to work.
This template above is included in a serverless.yml as a resource. However, when I deploy, the stack creation is just stuck waiting for the DNS record - i.e. it does not add the required CNAME entry as I understand it is supposed to do and as such the stack is stuck.
Has anyone gotten this feature to work?
And, yes, I know about the 3rd party custom resources that try to do the same thing, I don't want to use them if CF is supposed to do this natively now.
I hit the same issue. You need to specify the full domain name including the host in the DomainValidationOptions DomainName parameter, and just specify the hosted zone id:
Resources:
MyAPICert:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: xxxx.dev.mydomain.io
DomainValidationOptions:
- DomainName: xxxx.dev.mydomain.io
HostedZoneId: Z03XXXXXXXXXXXX
ValidationMethod: DNS
In my testing, the Route53 validation record was added about a minute after running the stack, and the domain successfully validated itslef after about 15 minutes.
If this is stuck as in progress for a long time, it could be that you are using a Private Hosted Zone when you need to use the Public one. Probably you don't use a private CA.
That process should take 2-3 minutes, not more than that.
I just deployed the below template to CloudFormation and it successfully created the validation DNS records and authorised the certificate.
If you were to pass the parameters SiteDnsZoneName=mydomain.io. and SiteDnsZoneId=ABCDEFGHIJKLMNOPQRSTU it would create a SAN cert that covers both mydomain.io and *.mydomain.io
{
"Description": "Deploy wildcard SAN cert inc bare domain. (Must deploy cert to us-east-1 for CloudFront)",
"Parameters": {
"SiteDnsZoneName": {
"Type": "String",
"MinLength": 4,
"Description": "DNS Zone",
"Default": "example.com"
},
"SiteDnsZoneId": {
"Type": "String",
"MinLength": 8,
"Description": "DNS Zone Id",
"Default": "ABCDEFGHIJKLMNOPQRSTU"
}
},
"Resources": {
"SiteCertificate": {
"Type": "AWS::CertificateManager::Certificate",
"Properties": {
"DomainName": {
"Fn::Join": [
".",
[
"*",
{
"Ref": "SiteDnsZoneName"
}
]
]
},
"SubjectAlternativeNames": [
{
"Ref": "SiteDnsZoneName"
}
],
"DomainValidationOptions": [
{
"DomainName": {
"Ref": "SiteDnsZoneName"
},
"HostedZoneId": {
"Ref": "SiteDnsZoneId"
}
}
],
"ValidationMethod": "DNS"
}
}
}
}
Note: If you want to use a cert in CloudFront you have to deploy the cert in us-east-1.
Note 2: Route53 needs to be hosting your DNS Zone, but theres no requirement on AWS being the registrar. Your domain can be registered with any provider, so long as you use the AWS name servers provided by Route53 when you add the zone.

How to add source_security_group_id in Security Group?

Hi I am trying to create security group in AWS CDK. when I try to create Ingress rule, I want to specify source_security_group_id. I created security group as below.
mws_vpc_sg = ec2.SecurityGroup(self,"securitygroupname",
description="EC2 Services Security Group",
security_group_name="securitygroupname",
vpc=vpc
);
Then I want to add ingress rules as below.
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: "80"
ToPort: "80"
SourceSecurityGroupId: !Ref MerchWebServicesLoadBalancerSecurityGroup
Can someone help me to write same template using aws cdk?
According to the documentation, there's a method belonging to ec2.SecurityGroup called add_ingress_rule which takes a "Peer" and a "Connection" as arguments. These being another Security Group and a Port
So you can try something like this
my_sg = ec2.SecurityGroup(self, "securitygroupone",
description="EC2 Services Security Group",
security_group_name="securitygroupone",
vpc=vpc
)
my_sg_two = ec2.SecurityGroup(self, "securitygrouptwo",
description="EC2 Services Security Group with Ingress from securitygroupone",
security_group_name="securitygrouptwo",
vpc=vpc
)
my_sg_two.add_ingress_rule(my_sg, 8080)
https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_ec2/SecurityGroup.html#aws_cdk.aws_ec2.SecurityGroup.add_ingress_rule