Create AWS SG using python boto3 - python

I'm trying to create a security group within a specific vpc by passing the variables during the code execution but I get the following errors, when I run the following command with the variables.
./create_sg.py vpc-e79569b2 dev_test_sg testing tcp 22 22 0.0.0.0/0
An error occurred (InvalidVpcID.NotFound) when calling the CreateSecurityGroup operation: The vpc ID 'VPC_ID' does not exist
#!/usr/bin/env python
import sys
import boto3
from botocore.exceptions import ClientError
region = "us-west-1"
VPC_ID=sys.argv[0]
SECURITY_GROUP_NAME=sys.argv[1]
DESCRIPTION=sys.argv[2]
IP_PROTOCOL_1=sys.argv[3]
FROM_PORT_1=sys.argv[4]
TO_PORT_1=sys.argv[5]
CIDR_IP_1=sys.argv[6]
ec2 = boto3.client('ec2')
response = ec2.describe_vpcs()
vpc_id = 'VPC_ID'
try:
response = ec2.create_security_group(GroupName='SECURITY_GROUP_NAME',Description='DESCRIPTION',VpcId=vpc_id)
security_group_id = response['GroupId']
print('Security Group Created %s in vpc %s.' % (security_group_id, vpc_id))
data = ec2.authorize_security_group_ingress(
GroupId=security_group_id,
IpPermissions=[
{'IpProtocol': 'IP_PROTOCOL_1',
'FromPort': FROM_PORT_1,
'ToPort': TO_PORT_1,
'IpRanges': [{'CidrIp': 'CIDR_IP_1'}]}
])
print('Ingress Successfully Set %s' % data)
except ClientError as e:
print(e)
Please review the code and let me know if I need to change something in there to successfully create a security group.

This line is all wrong...
response = ec2.create_security_group(GroupName='SECURITY_GROUP_NAME',Description='DESCRIPTION',VpcId=vpc_id)
IMO it should be:
response = ec2.create_security_group(GroupName=SECURITY_GROUP_NAME,Description=DESCRIPTION,VpcId=VPC_ID)
Ok, here is the complete code with corrections made to the string literals:
#!/usr/bin/env python
import sys
import boto3
from botocore.exceptions import ClientError
region = "us-west-1"
VPC_ID=sys.argv[0]
SECURITY_GROUP_NAME=sys.argv[1]
DESCRIPTION=sys.argv[2]
IP_PROTOCOL_1=sys.argv[3]
FROM_PORT_1=sys.argv[4]
TO_PORT_1=sys.argv[5]
CIDR_IP_1=sys.argv[6]
ec2 = boto3.client('ec2')
response = ec2.describe_vpcs()
try:
response = ec2.create_security_group(GroupName=SECURITY_GROUP_NAME,Description=DESCRIPTION,VpcId=VPC_ID)
security_group_id = response['GroupId']
print('Security Group Created %s in vpc %s.' % (security_group_id, VPC_ID))
data = ec2.authorize_security_group_ingress(
GroupId=security_group_id,
IpPermissions=[
{'IpProtocol': IP_PROTOCOL_1,
'FromPort': int(FROM_PORT_1),
'ToPort': int(TO_PORT_1),
'IpRanges': [{'CidrIp': CIDR_IP_1}]}
])
print('Ingress Successfully Set %s' % data)
except ClientError as e:
print(e)

Try removing the quotes around 'VPC_ID':
vpc_id = VPC_ID

Related

AWS Lambda function signal success or failure of the execution

I created a aws lambda function and trying to integrate it with AWS Connect.
The lambda function resets the directory password. AWS Connect triggers the lambda function, the function reset the password and signal AWS Connect success or failed. How do I include signal in the code?
import logging
import json
import boto3
client = boto3.client('ds')
def lambda_handler(event, context):
response = reset_user_password()
return event
def reset_user_password():
response = client.reset_user_password(
DirectoryId='d-xxxxxxxxxx',
UserName='username',
NewPassword='Password'
)
Unclear what you mean by signal, but you can add visibility into the response or error message with something like this for your reset function:
def reset_user_password():
try:
response = client.reset_user_password(
DirectoryId='d-xxxxxxxxxx',
UserName='username',
NewPassword='Password'
)
print(response)
except Exception as e:
print(e)
response = str(e)
return response
Also, you are calling the reset function in the lambda handler before it is defined, which will throw an error. You need to update the code like this:
import logging
import json
import boto3
client = boto3.client('ds')
def reset_user_password():
try:
response = client.reset_user_password(
DirectoryId='d-xxxxxxxxxx',
UserName='username',
NewPassword='Password'
)
print(response)
except Exception as e:
print(e)
response = str(e)
return response
def lambda_handler(event, context):
response = reset_user_password()
return response

Retrieve secrets from AWS Secrets Manager in a Lambda function

I have been trying to use Secret Manager in the lambda function in AWS.
I am using Secret Manager to store my Redshift credentials and want to use the sample code given by the AWS Secret manager to retrieve the secret via the lambda function.
I have set up a Secret in secret manager which contains my redshift credentials (username, password)
I am trying to set up a lambda function which would get the secrets from Secret Manger: below is the sample code:
import boto3
import base64
from botocore.exceptions import ClientError
def lambda_handler(event, context):
def get_secret():
secret_name = "test/MySecret"
region_name = "eu-west-2"
# Create a Secrets Manager client
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name=region_name
)
try:
get_secret_value_response = client.get_secret_value(
SecretId = secret_name
)
except ClientError as e:
if e.response['Error']['Code'] == 'DecryptionFailureException':
# Secrets Manager can't decrypt the protected secret text using the provided KMS key.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'InternalServiceErrorException':
# An error occurred on the server side.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'InvalidParameterException':
# You provided an invalid value for a parameter.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'InvalidRequestException':
# You provided a parameter value that is not valid for the current state of the resource.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
elif e.response['Error']['Code'] == 'ResourceNotFoundException':
# We can't find the resource that you asked for.
# Deal with the exception here, and/or rethrow at your discretion.
raise e
else:
# Decrypts secret using the associated KMS CMK.
# Depending on whether the secret is a string or binary, one of these fields will be populated.
if 'SecretString' in get_secret_value_response:
secret = get_secret_value_response['SecretString']
else:
decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
I am getting the following errors whilst running the lambda function:
{
"errorMessage": "name 'secret_name' is not defined",
"errorType": "NameError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 22, in lambda_handler\n SecretId = secret_name\n"
]
}
I have defined the secret_name at the start of the lambda function but I am getting the secret_name' is not defined error. Any suggestions how i can fix the issue
So the thing is python cannot get the value of secret_name variable, the reason is it is under a function
def get_secret():
secret_name = "test/MySecret"
region_name = "eu-west-2"
So instead if you just use
secret_name = "test/MySecret" without the function part, the sample code should work
Add VersionStage Parameter in your code!
get_secret_value_response = client.get_secret_value(
SecretId = secret_name,VersionStage='AWSCURRENT')

S3 Default server side encryption on large number of buckets using Python boto3

Hi Iam trying to turn on default s3 encryption on all my buckets in an account using python boto3 script see below.
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client('s3')
response = s3.list_buckets()
for bucket in response['Buckets']:
enc = s3.get_bucket_encryption(Bucket=bucket['Name'])
s3.put_bucket_encryption(
Bucket=bucket['Name'],
ServerSideEncryptionConfiguration={
'Rules': [
{
'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'AES256'
}
},
]
}
)
But i am struggling with my code which is not working
gives error
File "apply.py", line 10, in <module>
enc = s3.get_bucket_encryption(Bucket=bucket['Name'])
File "/Users/hhaqqani/Library/Python/2.7/lib/python/site-packages/botocore/client.py", line 272, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Users/hhaqqani/Library/Python/2.7/lib/python/site-packages/botocore/client.py", line 576, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ServerSideEncryptionConfigurationNotFoundError) when calling the GetBucketEncryption operation: The server side encryption configuration was not found
You are passing the wrong bucket name. Change Bucket=enc to Bucket=bucket['Name'] in your call to put_bucket_encryption.
Note also that the call to get_bucket_encryption will throw an exception if the bucket does not actually have encryption configured. While that might seem odd, that's the way it works (see boto3/issues/1899 for more details). So, to handle this potential exception:
SSECNF = 'ServerSideEncryptionConfigurationNotFoundError'
try:
bucket = client.get_bucket_encryption(Bucket=bucket['Name'])
# check current encryption here, if it's not what you want then update it
# check bucket['ServerSideEncryptionConfiguration']['Rules']
except client.exceptions.ClientError as e:
if e.response['Error']['Code'] == SSECNF:
s3.put_bucket_encryption(...)
else:
print("Unexpected error: %s" % e)
Please see below fixed code thanks #jarmod for quick help.
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client('s3')
response = s3.list_buckets()
client = boto3.client('s3')
SSECNF = 'ServerSideEncryptionConfigurationNotFoundError'
for bucket in response['Buckets']:
try:
bucket = client.get_bucket_encryption(Bucket=bucket['Name'])
# check current encryption here, if it's not what you want then update it
# check bucket['ServerSideEncryptionConfiguration']['Rules']
except client.exceptions.ClientError as e:
if e.response['Error']['Code'] == SSECNF:
s3.put_bucket_encryption(Bucket=bucket['Name'],
ServerSideEncryptionConfiguration={
'Rules': [
{
'ApplyServerSideEncryptionByDefault': {
'SSEAlgorithm': 'AES256'
}
},
]
})
else:
print("Unexpected error: %s" % e)
```

Kubernetes: How do I get all pods in a namespace using the python api?

I am using python to access my cluster. The only thing I came across, that is close is list_namespaced_pod, which does not give me the actual names of the pods.
As stated in the comments, you can access all information in the metadata of each pod in the list of pod items returned by the API call.
Here is an example:
def get_pods():
v1 = client.CoreV1Api()
pod_list = v1.list_namespaced_pod("example")
for pod in pod_list.items:
print("%s\t%s\t%s" % (pod.metadata.name,
pod.status.phase,
pod.status.pod_ip))
You would have already found the sol. for getting pod name I am posting here one more.
Below you can get pod from a namespace with particular regex (regex = if you want to search specific pod with some pattern).
Also you can check if a specific pod Exists or not with below fn.
from kubernetes import config , client
from kubernetes.client import Configuration
from kubernetes.client.api import core_v1_api
from kubernetes.client.rest import ApiException
from kubernetes.stream import stream
import re
pod_namespace = "dev_staging"
pod_regex = "log_depl"
try:
config.load_kube_config()
c = Configuration().get_default_copy()
except AttributeError:
c = Configuration()
c.assert_hostname = False
Configuration.set_default(c)
core_v1 = core_v1_api.CoreV1Api()
def get_pod_name(core_v1,pod_namespace,pod_regex):
ret = core_v1.list_namespaced_pod(pod_namespace)
for i in ret.items:
#print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))
pod_name=i.metadata.name
if re.match(pod_regex, pod_name):
return pod_name
def check_pod_existance(api_instance,pod_namespace,pod_name):
resp = None
try:
resp = api_instance.read_namespaced_pod(name=pod_name,namespace=pod_namespace)
except ApiException as e:
if e.status != 404:
print("Unknown error: %s" % e)
exit(1)
if not resp:
print("Pod %s does not exist. Create it..." % pod_name)
You can call your Functions as:
pod_name=get_pod_name(core_v1,pod_namespace,pod_regex)
check_pod_existance(core_v1,pod_namespace,pod_name)

Error in retrieving public dns name of ec2 instance

I am trying to retrieve public dns name of an ec2 instance.
Here is my python3 script.
import sys
import boto3
from botocore.exceptions import ClientError
instance_id = "i-03e7f6391a0f523ee"
action = 'ON'
ec2 = boto3.client('ec2')
if action == 'ON':
# Do a dryrun first to verify permissions
try:
ec2.start_instances(InstanceIds=[instance_id], DryRun=True)
except ClientError as e:
if 'DryRunOperation' not in str(e):
raise
# Dry run succeeded, run start_instances without dryrun
try:
response = ec2.start_instances(InstanceIds=[instance_id], DryRun=False)
print(response)
except ClientError as e:
print(e)
else:
# Do a dryrun first to verify permissions
try:
ec2.stop_instances(InstanceIds=[instance_id], DryRun=True)
except ClientError as e:
if 'DryRunOperation' not in str(e):
raise
# Dry run succeeded, call stop_instances without dryrun
try:
response = ec2.stop_instances(InstanceIds=[instance_id], DryRun=False)
print(response)
except ClientError as e:
print(e)
instance = ec2.Instance('i-1234567890123456')
while instance.state['Name'] not in ('running', 'stopped'):
sleep(5)
print("the instance is initializing")
#pubdns=instance.PublicDnsName
#print ("public dns name"+pubdns)
def get_name(inst):
client = boto3.client('ec2')
response = client.describe_instances(InstanceIds = [inst[0].instance_id])
foo = response['Reservations'][0]['Instances'][0]['NetworkInterfaces'][0]['Association']['PublicDnsName']
return foo
foo = get_name(instance_id)
print (foo)
If I use
ec2 = boto3.client('ec2')
in the above code, I get the following error:
AttributeError: 'EC2' object has no attribute 'Instance'
and if I use
ec2 = boto3.resource('ec2')
then I get this error instead:
AttributeError: 'ec2.ServiceResource' object has no attribute 'start_instances'
what I want to do is to be able to connect to an ec2 instance and retrieve its publicdns name.
I have changed the code now based on below suggestions
import sys
import boto3
instance_id = "i-03e7f6391a0f523ee"
action = 'ON'
ec2 = boto3.client('ec2')
#instance = ec2.resource('ec2').instance(instance_id)
if action == 'ON':
response = ec2.start_instances(InstanceIds=[instance_id], DryRun=False)
else:
response = ec2.stop_instances(InstanceIds=[instance_id], DryRun=False)
print(response)
def get_name(inst):
client = boto3.client('ec2')
response = client.describe_instances(InstanceIds = [inst[0].instance_id])
foo = response['Reservations'][0]['Instances'][0]['NetworkInterfaces'][0]['Association']['PublicDnsName']
return foo
foo = get_name(instance_id)
print (foo)
but now I get error
in get_name
response = client.describe_instances(InstanceIds = [inst[0].instance_id])
AttributeError: 'str' object has no attribute 'instance_id'
You're conflating two ideas in one.
boto3.client creates an object through which you look up resources like ec2.
Once you have a resource, you can begin to manipulate it.
Use
ec2 = boto3.client('ec2')
and then
instance = ec2.resource('ec2').instance(instance_id)
The second looks up your ec2 instance from the ec2 resource, not the boto3 ec2 client.
Here is a working code in case any one hits here in future I am posting it.This will print public DNS name of all of your instances after switching them on and then shutdown them.
import boto3
from pprint import pprint
ec2=boto3.client('ec2')
response=ec2.describe_instances()
print (response)
instancelist = []
for reservation in (response["Reservations"]):
for instance in reservation["Instances"]:
instancelist.append(instance["InstanceId"])
print (instancelist)
action ='ON'
if action == 'ON':
response = ec2.start_instances(InstanceIds=instancelist, DryRun=False)
ec2client = boto3.resource('ec2')
#response = ec2client.describe_instances()
instances = ec2client.instances.filter(Filters=[{'Name': 'instance-state-name', 'Values': ['running','stopped']}])
ids = []
for instance in instances:
print(instance.id, instance.instance_type)
ids.append(instance.id)
resp=ec2.describe_network_interfaces();
print ("printing pub dns name")
print(resp['NetworkInterfaces'][0]['Association']['PublicDnsName'])
ec2client.instances.filter(InstanceIds=ids).stop()

Categories

Resources