I'm new to cloudformation- I have manual created EC2 instance2 and another EC2 instance1 using cloudformation sample yaml file.
I want to add the manually created instance2 using "import existing resource" option.
but i'm getting below error-
You have modified resources [MyInstance] in your template that are not being imported. Update, create or delete operations cannot be executed during import operations.
below is the yaml file
AWSTemplateFormatVersion: "2010-09-09"
Metadata:
Generator: "former2"
Description: ""
Resources:
EC2Instance:
Type: "AWS::EC2::Instance"
Properties:
ImageId: "ami-0742b4e673072006f"
InstanceType: "t2.micro"
AvailabilityZone: !GetAtt EC2Instance2.AvailabilityZone
Tenancy: "default"
SubnetId: "subnet-09ec4c74f9226b0a5"
EbsOptimized: false
SecurityGroupIds:
- "sg-0ba5c892cb4456045"
SourceDestCheck: true
BlockDeviceMappings:
-
DeviceName: "/dev/xvda"
Ebs:
Encrypted: false
VolumeSize: 8
SnapshotId: "snap-097c45e6d3c6e0d1b"
VolumeType: "gp2"
DeleteOnTermination: true
HibernationOptions:
Configured: false
EnclaveOptions:
Enabled: false
EC2Instance2:
Type: "AWS::EC2::Instance"
DeletionPolicy: "Retain"
Properties:
ImageId: "ami-05fa00d4c63e32076"
InstanceType: "t2.micro"
KeyName: "ThisIsTestKeyPair"
AvailabilityZone: !Sub "${AWS::Region}a"
Tenancy: "default"
SubnetId: "subnet-09ec4c74f9226b0a5"
EbsOptimized: false
SecurityGroupIds:
- "sg-0847c55c903c6b01d"
SourceDestCheck: true
BlockDeviceMappings:
-
DeviceName: "/dev/xvda"
Ebs:
Encrypted: false
VolumeSize: 8
SnapshotId: "snap-0834d7afbcb68e0b7"
VolumeType: "gp2"
DeleteOnTermination: true
Tags:
-
Key: "Name"
Value: "EC-manual-for-CF-testing"
HibernationOptions:
Configured: false
EnclaveOptions:
Enabled: false
You can't create/updated resources in CFN at the same time as you import other resources. You have to do it one, by one:
Remove EC2Instance2 from your template and deploy EC2Instance
Add EC2Instance and import the second instance.
Related
How do I add a reference to the latest version number of the launch template in the auto-scaling group? The launch template and auto scaling group are in separate files as the launch template is used by other autoscaling groups as well. Can Fn::GetAtt and Ref be used here to refer to another resource located in a separate file? If so, how can I use it? The end goal is when I make an update to the launch template, the autoscaling group should automatically refer to the latest launch template.
Note - I am creating the launch template completely separate before creating the auto-scaling group. It works this way, but I would like the auto-scaling group to refer to the latest launch template. It currently defaults to version 1.
launch_template.yaml
---
AWSTemplateFormatVersion: '2010-09-09'
Resources:
LaunchTemplate:
Type: 'AWS::EC2::LaunchTemplate'
Properties:
LaunchTemplateName: testtemplate
LaunchTemplateData:
IamInstanceProfile:
Arn: >-
arn:aws:iam::blah
ImageId: ami-12345
InstanceRequirements:
InstanceGenerations:
- current
MemoryMiB:
Min: 8192
VCpuCount:
Min: 2
Max: 4
BlockDeviceMappings:
- Ebs:
VolumeSize: 16
VolumeType: gp2
DeleteOnTermination: true
Encrypted: true
DeviceName: /dev/xvda
Monitoring:
Enabled: true
KeyName: testkey
SecurityGroupIds:
- sg-1234
PrivateDnsNameOptions:
HostnameType: ip-name
InstanceInitiatedShutdownBehavior: terminate
autoscaling_group.yaml
---
Resources:
testautoscalinggroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: test-autoscaling-group
MaxSize: '2'
MinSize: '1'
DesiredCapacity: '1'
VPCZoneIdentifier:
- subnet-1234
TargetGroupARNs:
- Ref: targetgroup
MixedInstancesPolicy:
InstancesDistribution:
OnDemandAllocationStrategy: lowest-price
LaunchTemplate:
LaunchTemplateSpecification:
LaunchTemplateName: testtemplate
Tags:
- Key: Cluster
Value: test
PropagateAtLaunch: true
dynamicscalingpolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AutoScalingGroupName:
Ref: testautoscalinggroup
PolicyType: TargetTrackingScaling
TargetTrackingConfiguration:
DisableScaleIn: false
PredefinedMetricSpecification:
PredefinedMetricType: ASGAverageCPUUtilization
TargetValue: 30
targetgroup:
Type: 'AWS::ElasticLoadBalancingV2::TargetGroup'
Properties:
HealthCheckEnabled: true
HealthCheckIntervalSeconds: 30
HealthCheckProtocol: TCP
HealthCheckTimeoutSeconds: 10
HealthyThresholdCount: 3
Name: testtargetgroup
Protocol: TCP_UDP
Port: 53
UnhealthyThresholdCount: 3
VpcId: vpc-1234
I have an AutoScale and a LaunchConfig that I created earlier. I want to replace AMI ID with Cloudformation in LaunchConfig. How can I do that ?
I wonder if there is any sample template that will be a reference for me?
Simple example you can find : https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig.html#aws-properties-as-launchconfig--examples
---
AWSTemplateFormatVersion: 2010-09-09
Parameters:
LatestAmiId:
Description: Region specific image from the Parameter Store
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
InstanceType:
Description: Amazon EC2 instance type for the instances
Type: String
AllowedValues:
- t3.micro
- t3.small
- t3.medium
Default: t3.micro
Resources:
myLaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: !Ref LatestAmiId
SecurityGroups:
- Ref: "myEC2SecurityGroup"
InstanceType:
Ref: "InstanceType"
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 30
VolumeType: "gp3"
- DeviceName: /dev/sdm
Ebs:
VolumeSize: 100
DeleteOnTermination: "false"
I have an instance created with cloudformation like below:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ServerAMI
InstanceType: !Ref ServerInstanceType
KeyName: !Ref KeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 30
NetworkInterfaces:
- AssociatePublicIpAddress: 'false'
DeleteOnTermination: 'true'
DeviceIndex: '0'
GroupSet:
- Ref: ServerSecurityGroup
SubnetId: !Ref SubnetID
Tags:
- { Key: Name, Value: !Ref AWS::StackName }
My root volume in this case is created at 30GB. If I try increase this root volume size by setting the VolumeSize value then my ec2 instance is terminated and recreated.
Yet in the console I am able to increase the size of my root volume without recreation of my instance.
Is there any work around for this in order to prevent ec2 instance from being terminated when trying to increase root volume size via cloudformation?
Edit:
Here is a small test stack I'm using to test this again. Deployed once, then change VolumeSize and redeploy - it wants to replace the instance:
AWSTemplateFormatVersion: '2010-09-09'
Description: Test stack for a single ec2 instance
Parameters:
ServerAMI:
Type: String
Default: ami-096f43ef67d75e998
ServerInstanceType:
Type: String
Default: t2.small
DefaultVPCID:
Type: String
SubnetID:
Type: String
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ServerAMI
InstanceType: !Ref ServerInstanceType
KeyName: !Ref KeyName
BlockDeviceMappings:
- DeviceName: /dev/xvda #Linux
Ebs:
VolumeSize: 30
NetworkInterfaces:
- AssociatePublicIpAddress: 'false'
DeleteOnTermination: 'true'
DeviceIndex: '0'
GroupSet:
- Ref: ServerSecurityGroup
SubnetId: !Ref SubnetID
Tags:
- { Key: Name, Value: !Ref AWS::StackName }
ServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Webserver security group
VpcId: !Ref DefaultVPCID
SecurityGroupIngress:
- { IpProtocol: tcp, FromPort: '22', ToPort: '22', CidrIp: '127.0.0.1/32', Description: 'Test Instance' }
Unfortunately, I don't believe you can - per the CloudFormation documentation:
After the instance is running, you can modify only the DeleteOnTermination parameter for the attached volumes without interrupting the instance. Modifying any other parameter results in instance replacement.
I tried to deploy a new EC2 instance in cloud formation but I am getting the error "Service: AmazonEC2; Status Code: 400; Error Code: Unsupported"
This is my code:
AWSTemplateFormatVersion: "2010-09-09"
Description: vm stack
Resources:
VMParameter:
Type: AWS::SSM::Parameter
Properties:
Name: Testing
Type: "String"
Value: !Ref VMerr
Description: The ID of the created VM
VMerr:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: us-east-1a
InstanceType: 't2.micro'
ImageId: ami-007a607c4abd192db
KeyName: pemtest
EbsOptimized: True
SubnetId: subnet-0ec24f346062f4527
SecurityGroupIds:
- sg-092f790dccf3ed4d3
BlockDeviceMappings:
- DeviceName: "/dev/sdm"
Ebs:
VolumeType: "io1"
Iops: "200"
DeleteOnTermination: "false"
VolumeSize: "20"
- DeviceName: "/dev/sdk"
NoDevice: {}
Always make sure to pick the right AMI for the selected instance type. The AMI you specified is arm64 based. Therefore it is not suitable (unsupported) to run on an t2.micro.
For an automation one can also you the public Systems Manager Parameter Stores:
https://aws.amazon.com/blogs/compute/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/
I'm using CloudFormation to create an EC2 instance. What I am trying to achieve is only assign a private IP. No public IP. Everything gets created fine and it creates a DNS entry for the private IP, but it also creates a public IP. How can I tell it to not create a public IP. Here is my template. The vpc_id and subnet_id is on a private network.
AWSTemplateFormatVersion: '2010-09-09'
Description: 'AWS CloudFormation template for creating riskInternalElk instance with DNS record'
Parameters:
Resources:
InstanceSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: "{{security_group_name}}"
GroupDescription: "{{security_group_name}}"
VpcId: "{{vpc_id}}"
SecurityGroupIngress:
{% for item in security_group_ingress %}
- IpProtocol: "{{item.protocol}}"
FromPort: "{{item.from_port}}"
ToPort: "{{item.to_port}}"
CidrIp: "{{item.cidr_ip}}"
{% endfor %}
NetworkInterface:
Type: AWS::EC2::NetworkInterface
Properties:
SubnetId: "{{subnet_id}}"
Description: "{{subnet_description}}"
GroupSet:
- !Ref InstanceSecurityGroup
SourceDestCheck: true
Tags:
- Key: Network
Value: Web
EC2Instance:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: "Name"
Value: "{{instance_name}}"
ImageId: "{{image_id}}"
InstanceType: "{{instance_type}}"
KeyName: "{{key_name}}"
NetworkInterfaces:
- NetworkInterfaceId: !Ref NetworkInterface
DeviceIndex: 1
BlockDeviceMappings:
- DeviceName: "{{device_name}}"
Ebs:
VolumeType: "gp2"
VolumeSize: "{{volume_size}}"
Encrypted: true
DeleteOnTermination: false
DnsRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: "{{hosted_zone_name}}"
Comment: "DNS name for risk internal ec2 instance."
Name: "{{host_name}}"
Type: A
TTL: '60'
ResourceRecords:
- !GetAtt EC2Instance.PrivateIp
You can specify the information in the EC2:Instance resource set for the NetworkInterfaces differently to have it deviate from the subnets setting for assigning a public IP.
Specifically set the AssociatePublicIpAddress to "False" and move your NetworkInterface resource to be in-line like this:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: "Name"
Value: "{{instance_name}}"
ImageId: "{{image_id}}"
InstanceType: "{{instance_type}}"
KeyName: "{{key_name}}"
NetworkInterfaces:
- AssociatePublicIpAddress: false <--- This should do it
DeleteOnTermination: false
DeviceIndex: 0
SubnetId: "{{subnet_id}}"
Description: "{{subnet_description}}"
GroupSet:
- !Ref InstanceSecurityGroup
SourceDestCheck: true
BlockDeviceMappings:
- DeviceName: "{{device_name}}"
Ebs:
VolumeType: "gp2"
VolumeSize: "{{volume_size}}"
Encrypted: true
DeleteOnTermination: false
You control the assignment of public IP addresses to EC2 instances thru the subnet configuration. The subnet defines MapPublicIpOnLaunch. This also means that the subnet must be part of your cloudformation stack.
If you are using Auto Scaling, then you have the option AssociatePublicIpAddress in AWS::AutoScaling::LaunchConfiguration
AWS::EC2::Subnet
AWS::AutoScaling::LaunchConfiguration
Check the Subnet for the setting, "Auto-assign public IPv4 address".
Change it by going to the VPC Console and selecting the Subnet-->Actions-->"Modify auto-assign IP settings".