Terraform: Create AWS Lightsail instance from snapshot - amazon-web-services

Given the Terraform documentation on AWS Lightsail, I can construct a brand new Lightsail instance as follows.
resource "aws_lightsail_instance" "my_ls_instance" {
name = "my_ls"
availability_zone = "us-east-1b"
blueprint_id = "ubuntu_18_04"
bundle_id = "2xlarge_2_0"
key_pair_name = "MyKeyName"
}
It is possible to create a Lightsail instance from a Lightsail snapshot using Terraform?

No, it's not. Right now Terraform can only create instances based on Lightsail blueprints.

You can, however create an instance from snapshot in python3 /w boto3. Let me include my code:
#######
import boto3
client = boto3.client('lightsail')
response = client.create_instances_from_snapshot(
instanceNames=[
'myitblog',
],
availabilityZone='us-east-1a',
instanceSnapshotName='MYITBLOG_https',
bundleId='nano_2_0',
)
response = client.attach_static_ip(
staticIpName='StaticIp-1',
instanceName='myitblog'
)

Related

Restoring an RDS Instance to a backup/snapshot

I'm trying to RESTORE an RDS instance to one of it's previous backups/snapshots, but when I follow the provided instructions by Amazon it CREATES a new instance from the backup instead of restoring the existing one.
I would like to just restore the db to an existing state because I have an EC2 instance pointing to it (managed through a Load Balancer) that I'd prefer to not have to go in and point to the new RDS.
How can I restore an RDS instance back to a previous point in time AND NOT create a new instance from the backup/snapshot
Restore to new RDS instance. Then rename or original rds server to something else and apply change immediately. Once the change is processed (2-3 min), rename the restore instance to the same name as the original rds and apply immediately.
RDS dns name within single account only varies by initial part, which is taken from the RDS instance name.
Short answer is you can't:
You can't restore from a DB snapshot to an existing DB instance; a new
DB instance is created when you restore.
from here:
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_RestoreFromSnapshot.html
If you have terraform experience, I found this to be the most reproducible way of restoring from snapshots.
resource "aws_db_instance" "prod" {
allocated_storage = 10
engine = "mysql"
engine_version = "5.6.17"
instance_class = "db.t2.micro"
name = "mydb"
username = "foo"
password = "bar"
db_subnet_group_name = "my_database_subnet_group"
parameter_group_name = "default.mysql5.6"
}
data "aws_db_snapshot" "latest_prod_snapshot" {
db_instance_identifier = aws_db_instance.prod.id
most_recent = true
}
# Use the latest production snapshot to create a dev instance.
resource "aws_db_instance" "dev" {
instance_class = "db.t2.micro"
name = "mydbdev"
snapshot_identifier = data.aws_db_snapshot.latest_prod_snapshot.id
lifecycle {
ignore_changes = [snapshot_identifier]
}
}
From the terraform documentation.

How to list AWS tagged Hosted Zones using ResourceGroupsTaggingAPI boto3

I am trying to retrieve all the AWS resources tagged using the boto3 ResourceGroupsTaggingAPI, but I can't seem to retrieve the Hosted Zones which have been tagged.
tagFilters = [{'Key': 'tagA', 'Values': 'a'}, {'Key': 'tagB', 'Values': 'b'}]
client = boto3.client('resourcegroupstaggingapi', region_name = 'us-east-2')
paginator = self.client.get_paginator('get_resources')
page_list = paginator.paginate(TagFilters = tagFilters)
# filter and get iterable object arn
# Refer filtering with JMESPath => http://jmespath.org/
arns = page_list.search("ResourceTagMappingList[*].ResourceARN")
for arn in arns:
print(arn)
I noticed through the Tag Editor in the AWS Console (which I guess is using the ResourceGroupsTaggingAPI) when the region is set to All the tagged Hosted zones can be retrieved (since global) while when a specific region is set the tagged Hosted Zones are not shown in the results. Is there a way to set the boto3 client region to all?, or is there another way to do this?
I have already tried
client = boto3.client('resourcegroupstaggingapi')
which returns an empty result
(https://console.aws.amazon.com/resource-groups/tag-editor/find-resources?region=us-east-1)
You need to iterate it over all regions,
ec2 = boto3.client('ec2')
region_response = ec2.describe_regions()
#print('Regions:', region_response['Regions'])
for this_region_info in region_response['Regions']:
region = this_region_info["RegionName"]
my_config = Config(
region_name = region
)
client = boto3.client('resourcegroupstaggingapi', config=my_config)

Launching EC2 in multiple regions using boto3

I am using below code to launch EC2 instance
import boto3
client = boto3.client('ec2',region_name='us-east-1')
resp = client.run_instances(ImageId='ami-01e3b8c3a51e88954',
InstanceType='t2.micro',
MinCount=1,MaxCount=1)
for instance in resp['Instances']:
print(instance['InstanceId'])
This code is working.But my requirement now is to launch the instance in multiple regions at a time.
Can anyone suggest how to achieve this ?
First, you would need to find the ami ID's for each region. AMI's are not cross-region, therefore, for each region you should find the AMI ID's.
Then you would do something like:
import boto3
regions = {
'us-east-1': 'ami-01e3b8c3a51e88954',
'eu-west-1': 'ami-XXXXXXXXXXXXXXXXX',
}
for region in regions:
region_client = boto3.client('ec2', region_name=region)
resp = region_client.run_instances(ImageId=regions[region],
InstanceType='t2.micro',
MinCount=1, MaxCount=1)
for instance in resp['Instances']:
print(instance['InstanceId'])

Is there anyway to fetch tags of a RDS instance using boto3?

rds_client = boto3.client('rds', 'us-east-1')
instance_info = rds_client.describe_db_instances( DBInstanceIdentifier='**myinstancename**')
But the instance_info doesn't contain any tags I set in the RDS instance. I want to fetch the instances that has env='production' in them and want to exclude env='test'. Is there any method in boto3 that fetched the tags as well?
Only through boto3.client("rds").list_tags_for_resource
Lists all tags on an Amazon RDS resource.
ResourceName (string) --
The Amazon RDS resource with tags to be listed. This value is an Amazon Resource Name (ARN). For information about creating an ARN, see Constructing an RDS Amazon Resource Name (ARN) .
import boto3
rds_client = boto3.client('rds', 'us-east-1')
db_instance_info = rds_client.describe_db_instances(
DBInstanceIdentifier='**myinstancename**')
for each_db in db_instance_info['DBInstances']:
response = rds_client.list_tags_for_resource(
ResourceName=each_db['DBInstanceArn'],
Filters=[{
'Name': 'env',
'Values': [
'production',
]
}])
Either use a simple exclusion over the simple filter, or you can dig through the documentation to build complicated JMESPath filter using
paginators.
Notes : AWS resource tags is not a universal implementation. So you must always refer to the boto3 documentation.
Python program will show you how to list all rds instance, there type and status.
list_rds_instances.py
import boto3
#connect ot rds instance
client = boto3.client('rds')
#rds_instance will have all rds information in dictionary.
rds_instance = client.describe_db_instances()
all_list = rds_instance['DBInstances']
print('RDS Instance Name \t| Instance Type \t| Status')
for i in rds_instance['DBInstances']:
dbInstanceName = i['DBInstanceIdentifier']
dbInstanceEngine = i['DBInstanceClass']
dbInstanceStatus = i['DBInstanceStatus']
print('%s \t| %s \t| %s' %(dbInstanceName, dbInstanceEngine, dbInstanceStatus))
Important Note: While working with boto3 you need to setup your credentials in two files ~/.aws/credentials and ~/.aws/config
~/.aws/credentials
[default]
aws_access_key_id=<ACCESS_KEY>
aws_secret_access_key=<SECRET_KEY>
~/.aws/config
[default]
region=ap-south-1

boto3: Create a instance with an instanceprofile/ IAM Role

I want to write a script that starts servers for me and does the setup. It should:
Create two S3-Buckets and set its CORS (solved)
Create a ec2 server based on an image
give this server access to that bucket
What I have found so far is how to create the bucket and how to create the instance itself:
##see http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#ec2
aws = boto3.Session(profile_name="myProfile")
s3 = aws.resource('s3', region_name='my-region-1')
bucket = s3.create_bucket(
Bucket='my-cool-bucket',
#...
)
#...
ec2 = aws.resource('ec2', region_name='my-region-1')
ec2.create_instances(
ImageId="my-ami-image-id",
MinCount=1, # I want exactly 1 server
MaxCount=1,
KeyName='my-ssh-key',
SecurityGroupIds=['my-security-group'],
UserData=myStartupScript, # script that will start when server starts
InstanceType='t2.nano',
SubnetId="my-subnet-id",
DisableApiTermination=True,
PrivateIpAddress='10.0.0.1',
#...
)
but how do I now create the Role for that server and give that role access to the bucket?
I have found the way to create the InstanceProfile:
https://boto3.readthedocs.io/en/latest/reference/services/iam.html#IAM.ServiceResource.create_instance_profile
instance_profile = iam.create_instance_profile(
InstanceProfileName='string',
Path='string'
)
You will need to:
Create an InstanceProfile
Associate a Role to the Instance Profile
Launch the instance(s) with the IamInstanceProfile parameter
Create a role named Test-emr-instance-role, then you can use this code to create an instance profile and attach a role to the instance profile.
session = boto3.session.Session(profile_name='myProfile')
iam = session.client('iam')
instance_profile = iam.create_instance_profile (
InstanceProfileName ='Test-emr-instance-profile'
)
response = iam.add_role_to_instance_profile (
InstanceProfileName = 'Test-emr-instance-profile',
RoleName = 'Test-emr-instance-role'
)