Cloud Formation example template for ElastiCache Redis Global Store - amazon-web-services

I tried to follow this document https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticache-globalreplicationgroup.html#cfn-elasticache-globalreplicationgroup-cacheparametergroupname, to create a global store for Redis in the ElastiCache. but I'm not able to achieve that. kindly share any examples related to this
RedisGlobalReplication:
Type: AWS::ElastiCache::GlobalReplicationGroup
Properties:
AutomaticFailoverEnabled: true
CacheNodeType: !Ref CacheNodeType
EngineVersion: !Ref RedisEngineVersion
GlobalNodeGroupCount: 1
CacheParameterGroupName: 'default.redis5.0'
GlobalReplicationGroupDescription: !Sub '${AWS::StackName}-Redis Global store'
GlobalReplicationGroupIdSuffix: !Ref 'AWS::StackName'
Members:
- ReplicationGroupRegion: 'ap-south-1'
Role: primary
RegionalConfigurations:
- ReplicationGroupId: '1'
ReplicationGroupRegion: 'ap-south-1'
ReshardingConfigurations:
- NodeGroupId: '1'
PreferredAvailabilityZones:
- ap-south-1a
- ap-south-1b

Related

Cloudformation Elasticache: "cannot be specified along with CacheSecurityGroupNames"

ERROR:
Properties [AZMode, CacheSubnetGroupName, SecurityGroupIds, PreferredAvailabilityZones, SnapshotArns, SnapshotRetentionLimit, SnapshotWindow, Tags] cannot be specified along with CacheSecurityGroupNames, please update your template to the latest version
Type: AWS::ElastiCache::CacheCluster
Properties:
Engine: redis
AZMode: single-az
EngineVersion: 5.0.6
CacheParameterGroupName: !Ref CacheParameterGroup
ClusterName: !Sub ${SystemName}-${Env}-elasticache
CacheNodeType: !Ref ElasticacheNodeType
NumCacheNodes: "1"
Port: 6379
PreferredMaintenanceWindow: !Ref MaintenanceWindow
PreferredAvailabilityZone: ap-northeast-1a
SnapshotRetentionLimit: !Ref SnapshotRetentionLimit
SnapshotWindow: !Ref SnapshotWindow
CacheSubnetGroupName: !Ref CacheSubnetGroup
CacheSecurityGroupNames:
- Fn::ImportValue: DevElasticacheSG
Whats the reason for above error in cloudformation?
CacheSecurityGroupNames can only be used when your cluster is not in VPC:
Use this parameter only when you are creating a cluster outside of an Amazon Virtual Private Cloud (Amazon VPC).
My guess is that maybe you wanted to use VpcSecurityGroupIds instead.

Unable to create a CoudFormation RDS template which provision new instance from point in time snapshots

I've trying to write a CloudFormation to provision a new RDS instance from the point in time snapshot an existing RDS DB.
However, I came to know that you can't specify db-name when you provide a snapshot in CloudFormation template and thus it will always restore it to the original DB.
I have got this article for the same on aws blogs, though I'm looking if there is any out of the box solution for the same.
Edit 1
RDS snippet from my Cloud Formation
Resources:
MyDB:
Type: AWS::RDS::DBInstance
Properties:
DBName: Fn::If ["UseDbSnapshot", !Ref AWS:NoValue, !Ref MyDBName]
DBSecurityGroups:
- !Ref MyDbSecurityByEC2SecurityGroup
- !Ref MyDbSecurityByCIDRIPGroup
AllocatedStorage: 20
DBInstanceClass: db.m1.small
Engine: MySQL
MasterUsername: root
MasterUserPassword: password
DBSnapshotIdentifier: Fn::If ["UseDbSnapshot", !Ref DBSnapshotIdentifier, !Ref AWS::NoValue]
DeletionPolicy: Snapshot
What can I try to fix this?
You have to keep in mind, that a couple of RDS properties (such as MasterUsername) are not customizable when you want to restore from snapshot. The AWS documentation says:
If you specify the SourceDBInstanceIdentifier or DBSnapshotIdentifier property, don't specify this property. The value is inherited from the source DB instance or snapshot.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html
So just omit those parameters like this:
Parameters:
DBSnapshotIdentifier:
Description: 'Optional identifier for the DB cluster snapshot from which you want to restore'
Type: String
Default: ''
Conditions:
HasDBSnapshotIdentifier: !Not [!Equals [!Ref DBSnapshotIdentifier, '']]
Resources:
DBInstance:
Type: AWS::RDS::DBInstance
Properties:
...
DBSnapshotIdentifier: !If [HasDBSnapshotIdentifier, !Ref DBSnapshotIdentifier, !Ref 'AWS::NoValue']
KmsKeyId: !If [HasDBSnapshotIdentifier, !Ref 'AWS::NoValue', !If [HasEncryption, !Ref KmsKey, !Ref 'AWS::NoValue']]
MasterUsername: !If [HasDBSnapshotIdentifier, !Ref 'AWS::NoValue', !Ref MasterUsername]
MasterUserPassword: !If [HasDBSnapshotIdentifier, !Ref 'AWS::NoValue', !Ref MasterPassword]
StorageEncrypted: !If [HasDBSnapshotIdentifier, !Ref 'AWS::NoValue', !If
...

Creating a VPC Interface Endpoint for SQS in Cloud Formation

I was wondering if it is possible to create a Resource in my CloudFormation file to create a VPC Endpoint for SQS. I was able to do this for SQS and DynamoDB, but I believe it is because they were Gateway endpoints.
For now I have defined my SQS resource as:
SQSEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal: '*'
Action:
- 'sqs:*'
Resource:
- '*'
ServiceName: !Join
- ''
- - com.amazonaws.
- !Ref 'AWS::Region'
- .sqs
SubnetIds:
- !Ref PrivateSubnet
- !Ref PublicSubnet
VpcId: !Ref 'VPC'
VpcEndpointType: Interface
Though, when I try to create the stack I get the error:
It seems like it is possible from reading this blog post from AWS. Though I can't find any examples or documentation. Any ideas?
So to sum it all up:
SQSEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Join
- ''
- - com.amazonaws.
- !Ref 'AWS::Region'
- .sqs
SubnetIds:
- !Ref PrivateSubnet
VpcId: !Ref 'VPC'
VpcEndpointType: Interface
SecurityGroupIds:
- !Ref PrivateSubnetInstanceSG # has to allow traffic from your VPC
PrivateDnsEnabled: true
Background
I figured it out, for DynamoDB and S3, which use Gateway Endpoints, the PolicyDocument property has to be defined. For all other services, This doesn't need to be defined. So for SQS first I thought all that is needed is:
SQSEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
ServiceName: !Join
- ''
- - com.amazonaws.
- !Ref 'AWS::Region'
- .sqs
SubnetIds:
- !Ref PrivateSubnet
- !Ref PublicSubnet
VpcId: !Ref 'VPC'
VpcEndpointType: Interface
But that still wasn't working, even though the interface endpoint was setup, I had to:
set the PrivateDnsEnabled property to true so that you can use the AWS CLI as the AWS CLI uses the public endpoint, and setting the PrivateDnsEnabled allows the private endpoint to automatically be mapped to the public one
set the SecurityGroupsIds to have a security group that allows Inbound traffic from your VPC. If this instance set, the default security group is used and it only allows inbound traffic from sources that have the default security group, meaning that SQS won't be able to send traffic back to your instance

CodeDeploy does not deploy to new ASG group because of CloudFormation resources creation order

I am trying to develop an entire AWS architecture by usin CloudFormation only, however I am having some issues with the integration of CodeDeploy with CloudFormation and AutoScaling Group.
The problem is that, since I need to associate the CodeDeploy DeploymentGroup to an AutoScaling Group in order for the auto-deployment to work, CloudFormation recognizes the group as being required before creating the deployment group.
What happens is that the ASG gets created, instances start to spin up BEFORE the deployment group has been created, which means that these instances will never get deployed. I tried to think of a Lambda function to forcefully deploy these instances, however the problems persists because the CodeDeploy Deployment Group will still not be available yet most likely, or if it was, it's not reliable.
This problem only occurs when the stack is created for the first time.
This is my CloudFormation template:
[...]
UpdateApiAutoscalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName:
Fn::Join:
- ''
- - !ImportValue UpdateApiCodeDeployApplication
- -autoscaling-group
- !Ref Environment
DesiredCapacity: !Ref MinimumApiAmount
HealthCheckGracePeriod: 30
HealthCheckType: ELB
LaunchConfigurationName: !Ref UpdateApiAutoscalingLaunchConfiguration
TargetGroupARNs:
- !Ref UpdateApiTargetGroup
MaxSize: !Ref MaximumApiAmount
MinSize: !Ref MinimumApiAmount
VPCZoneIdentifier:
- Fn::Select:
- 0
- !Split
- ","
- Fn::ImportValue:
!Sub "PrivateSubnets-${Environment}"
Tags:
- Key: Environment
Value: !Ref Environment
PropagateAtLaunch: true
- Key: CompanySshAccess
Value: 1
PropagateAtLaunch: true
- Key: Application
Value: update-api
PropagateAtLaunch: true
# Defines how the Update API servers should be provisioned in the scaling group.
UpdateApiAutoscalingLaunchConfiguration:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
AssociatePublicIpAddress: false
IamInstanceProfile: !Ref UpdateApiInstanceRole
ImageId: !FindInMap [Api, Image, !Ref Environment]
InstanceType: !FindInMap [Api, InstanceType, !Ref Environment]
LaunchConfigurationName: !Sub 'update-api-launchconfig-${Environment}'
SecurityGroups:
- Fn::ImportValue: !Sub 'InternalBastionSecurityGroupId-${Environment}'
- !GetAtt LoadBalancerProtectedSecurityGroup.GroupId
UpdateApiCodeDeploymentGroup:
Type: AWS::CodeDeploy::DeploymentGroup
Properties:
DeploymentGroupName: !Ref Environment
DeploymentConfigName: "atleast-one-instance-online"
ServiceRoleArn: !Ref CodeDeployServiceRoleArn # TODO: create CodeDeployServiceRole using CloudFormation
ApplicationName: !ImportValue UpdateApiCodeDeployApplication
LoadBalancerInfo:
ElbInfoList:
- Name: !GetAtt UpdateApiLoadBalancer.LoadBalancerName
DeploymentStyle:
DeploymentOption: !FindInMap [Api, DeploymentStyleOption, !Ref Environment]
DeploymentType: !FindInMap [Api, DeploymentStyleType, !Ref Environment]
AutoScalingGroups:
- !Ref UpdateApiAutoscalingGroup
[...]

Cannot create a cross region unencrypted read replica from encrypted source

I am trying to create a read replica in west region for an RDS data base in east through cloud formation template.
I am getting an error:
Cannot create a cross region unencrypted read replica from encrypted source.
However, I have tried to provide kms key id and marked CopyTagsToSnapshot as true . Here is how my cloud formation looks like:
Resources:
MyDB:
Type: AWS::RDS::DBInstance
Properties:
SourceDBInstanceIdentifier: !Ref ReadReplicaURL
AllocatedStorage: !Ref DBAllocatedStorage
CopyTagsToSnapshot: true
DBSubnetGroupName: !Ref DBSubnetGroup
VPCSecurityGroups:
- !Ref DBSG1
KmsKeyId: !Ref DBEncryptionKey
StorageEncrypted: true
DBInstanceClass: !Ref DBInstanceClass
DBInstanceIdentifier: !Ref DBInstanceIdentifier
Iops: !Ref DBIops
MonitoringInterval: !Ref DBMonitoringInterval
Engine: !Ref Engine
MonitoringRoleArn: !Ref DBMonitoringRoleARN
Port: !Ref DBPort
PreferredMaintenanceWindow: !Ref DBPreferredMaintenanceWindow
StorageType: io1
Answer I got from AWS rep:
Unfortunately, creation of encrypted RDS cross-region read replicas is not possible through CloudFormation currently. There is an active feature request to implement this functionality to which I have added your voice. Once the feature is implemented, it will be announced on this page:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/ReleaseHistory.html