Logging for public hosted zone Route53 - aws-cloudformation

I'm trying to set up the logging for a public hosted zone on Route53 AWS. the template looks like this:
Resources:
HostedZonePublic1:
Type: AWS::Route53::HostedZone
Properties:
HostedZoneConfig:
Comment: !Join ['', ['Hosted zone for ', !Ref 'DomainNamePublic' ]]
Name: !Ref DomainNamePublic
QueryLoggingConfig:
CloudWatchLogsLogGroupArn: !GetAtt Route531LogGroup.Arn
Route531LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: Route531-AWSLogGroup
RetentionInDays: 7
But when I try to launch the stack I'm getting the following message:
The ARN for the CloudWatch Logs log group is invalid. (Service: AmazonRoute53; Status Code: 400; Error Code: InvalidInput; Request ID: 6c02db60-ef62-11e8-bce8-d14210c1b0cd)
Anybody an idea what could be wrong with this setup?
merci A

I encountered the same issue. The CloudWatch logs log group needs to be created in a specific region to be valid.
See following:
You must create the log group in the us-east-1 region.
You must use the same AWS account to create the log group and the hosted zone that you want to configure query logging for.
When you create log groups for query logging, we recommend that you use a consistent prefix.
You can find the full documentation here.

Related

AWS sam template extraneous key that should be valid

Trying to create a dataset and template in a bitbucket pipeline using aws sam and it returns the error
Model validation failed (#: extraneous key [DataSourceArn] is not permitted
I've tried
xxxxDataset:
Type: AWS::QuickSight::DataSet
Properties:
AwsAccountId: !Ref "AWS::AccountId"
Name: !Sub 'xxxxDataset${PlatformParameter}'
ImportMode: 'DIRECT_QUERY'
PhysicalTableMap:
RelationalTable:
Catalog: 'AwsDataCatalog'
DataSourceArn: !Sub 'arn:aws:quicksight:${RegionParameter}:${AWS::AccountId}:datasource/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
and
xxxxDataset:
Type: AWS::QuickSight::DataSet
Properties:
AwsAccountId: !Ref "AWS::AccountId"
Name: !Sub 'xxxxDataset${PlatformParameter}'
ImportMode: 'DIRECT_QUERY'
S3Source:
DataSourceArn: !Sub 'arn:aws:quicksight:${RegionParameter}:${AWS::AccountId}:datasource/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
both give the same error while DataSourceArn is a valid key according to the documentation. I'm referring to cloudformation doc https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-dataset.html but there may be differences with aws-sam for which I haven't found quicksight documentation...
Thanks any help appreciated

For ECS deployment group, ec2TagFilters can not be specified

When creating a AWS::CodeDeploy::DeploymentGroup in CloudFormation, I get this error, even though I have no EC2TagFilters in my script:
For ECS deployment group, ec2TagFilters can not be specified (Service: AmazonCodeDeploy; Status Code: 400; Error Code: InvalidEC2TagException; Request ID: af5c3f68-6033-4df0-9f6f-ecd064ad6b7b; Proxy: null)
CodeDeploymentGroupDev:
Type: AWS::CodeDeploy::DeploymentGroup
DependsOn:
- CodeDeployApplication
Properties:
ApplicationName: !Ref ApplicationName
DeploymentConfigName: CodeDeployDefault.AllAtOnce
DeploymentGroupName: !Sub "${ApplicationName}-Dev"
DeploymentStyle:
DeploymentType: IN_PLACE
OnPremisesTagSet:
OnPremisesTagSetList:
- OnPremisesTagGroup:
- Key: !Ref OnPremisesTagKey
Type: KEY_AND_VALUE
Value: !Ref OnPremisesTagValue
ServiceRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/CodeDeployServiceRole'
Is AWS::CodeDeploy::DeploymentGroup not implemented correctly in CloudFormation?
I can see that you are using OnPremisesTagSet which mean you should already register on-premises instances with CodeDeploy, see https://docs.aws.amazon.com/codedeploy/latest/userguide/instances-on-premises.html.
If you are using Ec2 then you need to use Ec2TagSet instead of OnPremisesTagSet.
This occurred because my corresponding AWS::CodeDeploy::Application was not configured correctly (not in original post, but shown below). I was attempting an onprem deploy using a registered agent. I had ECS for the compute platform, but it should have been Server:
CodeDeployApplication:
Type: AWS::CodeDeploy::Application
Properties:
ApplicationName: !Ref ApplicationName
ComputePlatform: Server // Allowed values: ECS | Lambda | Server
It worked, after I fixed that.

Get attribute of EC2 created via LaunchConfiguration

I would like to get the PrivateIP attribute of EC2s that i create via LaunchConfiguration.
I need that attribute so that i can assign a type A dns record to the instance for other purposes.
Here is my code:
Resources:
webLaunchConfig:
Type: 'AWS::AutoScaling::LaunchConfiguration'
Properties:
ImageId: !Ref webEc2AMI
InstanceType: !Ref ec2WebInstanceType
SecurityGroups: !Ref webEc2SG
UserData:
'Fn::Base64': !Sub >
#!/bin/bash -xe
apt update -y
dnsWebServerName:
Type: 'AWS::Route53::RecordSet'
Properties:
HostedZoneId: !Ref hostedZoneId
Comment: DNS name for my db server.
Name: !Ref dnsWebServerNamePar
Type: A
TTL: '900'
ResourceRecords:
- !GetAtt webLaunchConfig.PrivateIp
... and when i try to launch it i get this error:
Template contains errors.: Template error: resource webLaunchConfig
does not support attribute type PrivateIp in Fn::GetAtt
... indicating me that what i am trying to do is not supported. Though there must be a way to achieve this.
Do you know how to do it? Or a workaround for this?
Sadly you can't do this. AWS::AutoScaling::LaunchConfiguration is only a blueprint of an instance to be launched. Thus it does not provide information about instance PrivateIp. The get the PrivateIp you have to actually launch the instance.
To do so you have to use AWS::EC2::Instance. However AWS::EC2::Instance does not support launching from ``AWS::AutoScaling::LaunchConfiguration. So either you have to change your LaunchConfigurationintoLaunchTemplateor just create instance directly usingAWS::EC2::Instance` rather then any templates.

AWS CloudFormation function call fails: Fn::ImportValue must not depend on any resources, imported values, or Fn::GetAZs

I have a cloud formation template (mainVPC) that creates few Subnets in a VPC and exports the subnets with names "PrivateSubnetA", "PrivateSubnetB" ...
I have a different cloud formation template that creates DBSubnetGroup. I want to use "PrivateSubnetA", "PrivateSubnetB" as default values if user does not provide data. CloundFormation does not support imported values in parameters. So I put some default value (XXXX) and had a condition section to see if the user has provided some input
Conditions:
userNotProvidedSubnetA: !Equals
- !Ref PrivateSubnetA
- XXXX
userNotProvidedSubnetB: !Equals
- !Ref PrivateSubnetB
- XXXX
This helps me in figuring out if the user has provided data. Now I want to use default values, if the user has not provided values, else use user-provided values.
below is code for that
DBSubnetGroup:
Type: 'AWS::RDS::DBSubnetGroup'
Properties:
DBSubnetGroupDescription: RDS Aurora Cluster Subnet Group
SubnetIds:
- !If
- userNotProvidedSubnetA
- Fn::ImportValue:
!Sub '${fmMainVpc}-PrivateSubnetA'
- !Ref PrivateSubnetA
- !If
- userNotProvidedSubnetB
- Fn::ImportValue:
!Sub '${fmMainVpc}-PrivateSubnetB'
- !Ref PrivateSubnetB
This fails with the error "Template error: the attribute in Fn::ImportValue must not depend on any resources, imported values, or Fn::GetAZs".
ImportValue is not used anywhere else in the template.
Is there a way for using exported values as default values ( the default values cannot be hardcoded, they come as exported values from a run of another stack), while providing an option for the users to provide their own values (to create resources).
Thanks.
This can also be caused by having a reference inside Fn::ImportValue to a parameter be misnamed. For example, if I have the following parameter NetworkStackName defined and I mis-reference it in the Fn::ImportValue statement (as NetworkName), I will get this error. I would need to change the NetworkName to match the value in Parameters, NetworkStackName to fix the error.
Parameters:
NetworkStackName:
Type: String
Default: happy-network-topology
Resources:
MySQLDatabase:
Type: AWS::RDS::DBInstance
Properties:
Engine: MySQL
DBSubnetGroupName:
Fn::ImportValue:
!Sub "${NetworkName}-DBSubnetGroup"
I had a problem where I needed to get my artifact bucket name from my prerequisite stack, I tried this:
Fn::ImportValue:
- 'arn:aws:s3:::${ArtifactStore}/*'
turns out you can do this and it will work. Hope his helps someone out one day!
- !Sub
- 'arn:aws:s3:::${BucketName}/*'
- BucketName : !ImportValue 'ArtifactStore'
Currently, Cloudformation didn't support dynamic default value. It's not possible to have a dynamic default value for CloudFormation. As the template has not executed at the time all parameters are being collected. However, you can use SSM parameter for as the workaround, something like below.
Parameters
PagerDutyUrl:
Type: AWS::SSM::Parameter::Value<String>
Description: The Pagerduty url
Going back to your current cloudformation, I am thinking that value ${fmMainVpc} might not be initialized correctly.
I'm my case, I had the follow resource:
# removed for brevity
Subnets:
- !ImportValue: parent-stack-subnet-a
- !ImportValue: parent-stack-subnet-b
I forgot to remove the : when changing the syntax from Fn::ImportValue to the shorthand !ImportValue. Confusing error message, but removing the : resolved it because that was incorrect usage on my part.

Add AWS::Route53::RecordSet DnsRecord to a serverless Cloudfront Distribution

I found this on how to associate a route53 dns record with a S3 bucket in a serverless.yml file.
I've tried to adapt that to the case of deploying a cloudfront distrib
DnsRecord:
Type: "AWS::Route53::RecordSet"
Properties:
AliasTarget:
DNSName: <cloudfrontdistribution id>
HostedZoneId: Z21DNDUVLTQW6Q
HostedZoneName: ${self:custom.appFQDN}.
Name:
Ref: WebAppCloudFrontDistribution
Type: 'CNAME'
but am struggling with how to get the distribution id as a ref rather than a fixed string.
How would I do this?
To set up an AliasTarget, you actually just need to provide the CloudFront DNS name for the DNSName parameter, not the distribution ID. You can do this with:
!GetAtt WebAppCloudFrontDistribution.DomainName
I'm assuming that WebAppCloudFrontDistribution is the logical ID of an AWS::CloudFront::Distribution resource in your template and not a parameter. If this is actually a parameter, just set the value of the parameter to the DNS name listed for the distribution in the AWS console dashboard for CloudFront.
There are some other things you'll need to fix in your template:
HostedZoneName should be the name of the Route53 hosted zone, not the FQDN you want to use. Personally, I prefer to use the HostedZoneId property for AWS::Route53::RecordSet resources instead since it's clearer what the meaning of this property is, but to each their own. (Note: HostedZoneId property for the AWS::Route53::RecordSet resource should be the HostedZoneId for YOUR hosted zone, not the same value as the AliasTarget HostedZoneId.)
Name should be the DNS name that you want to be a CNAME for the CloudFront distribution resource.
I know it's a bit weird, but with alias targets, you have to set the type to either "A" (for IPv4) or "AAAA" (IPv6). I recommend doing both - you can do this by creating a duplicate of your AWS::Route53::RecordSet resource but set type to "AAAA" instead of "A".
Finally, note that in order for this to work, you will also need to make sure to add the FQDN as an alternate name for the CloudFront distribution resource - you can set this using the "Aliases" property of the "DistributionConfig" property of the distribution resource in your template, or by configuring this manually for the distribution settings in the AWS console if you're not creating the resource in this template.
I struggled to create a AWS::Route53::RecordSet with CloudFormation producing unspecific, unhelpful error messages of the type "The resource failed to create". The key for me was to use HostedZoneId rather than HostedZoneName to specify the parent "hosted zone". This is what I ended up with:
NaaaaaComDNSEntry:
Type: 'AWS::Route53::RecordSet'
DependsOn: NaaaaaComCloudFront
Properties:
AliasTarget:
DNSName: !GetAtt NaaaaaComCloudFront.DomainName
# For CloudFront, HostedZoneId is always Z2FDTNDATAQYW2, see:
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html#cfn-route53-aliastarget-hostedzoneid
HostedZoneId: Z2FDTNDATAQYW2
# HostedZoneId is for ID for 'naaaaa.com.'; In theory its valid to use `HostedZoneName` OR `HostedZoneId`
# but in practice the recordset always failed to create if I used `HostedZoneName`
HostedZoneId: ZABCDEFGHIJK5M
Name: 'www.naaaaa.com.'
Type: 'A'
This is what my working config looks like in serverless templates:
DnsRecord:
Type: "AWS::Route53::RecordSet"
Properties:
AliasTarget:
DNSName:
Fn::GetAtt:
- CloudFrontDistribution
- DomainName
# Looks like it is always the same for CloudFront distribs.
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
# https://docs.aws.amazon.com/general/latest/gr/rande.html#cf_region
HostedZoneId: ${self:custom.zoneId}
HostedZoneName: ${self:custom.secondLevelDomain}.
Name: ${self:custom.appFQDN}
Type: 'A'
And
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
...
Aliases:
- ${self:custom.appFQDN}
Also courtesy of an example by Tom McLaughlin:
https://github.com/ServerlessOpsIO/serverless-zombo.com/blob/master/serverless.yml