With CDK is it possible to modify the default subnets after they have been created? - amazon-vpc

I've created a VPC like this
vpc = new Vpc(theStack, vpcName,
VpcProps.builder()
.cidr("10.0.0.0/16")
.build());
In eu-west-1, by default I get 3 public and 3 private subnets. The private subnets will have a NAT Gateway.
Now, we're trying to remove the NAT Gateways (because of cost), so I tried this
vpc = new Vpc(theStack, vpcName,
VpcProps.builder()
.maxAzs(3)
.cidr("10.0.0.0/16")
.subnetConfiguration(List.of(
SubnetConfiguration.builder()
.subnetType(SubnetType.PUBLIC)
.name("Public")
.cidrMask(24)
.build(),
SubnetConfiguration.builder()
.subnetType(SubnetType.ISOLATED)
.name("Private")
.cidrMask(24)
.build()))
.build());
Creating this in a fresh stack works fine. I get a VPC with the same subnets as before and no NAT GW:s. But, running this to modify the VPC created above, results in name clashes.
Is there some way I can get cdk/cloudformation to understand that I want to modify the existing private subnets and not create new ones?

I double-checked the subnets that where created without specifying the subnets. The cdir-mask was /19 not /24 like i entered in the second version.
So, changing the cidrMask to 19 works fine. Now CloudFormation doesn't create new subnets and deletes the NAT Gateways.

Related

Assign Domain Name For Same IP, Different Nodeports Minikube

I'm trying to set up a local environment for microservices using minikube. My cluster consists of 4 pods and the minikube ip for all 4 of them are the same. However, each service runs on a unique nodeport.
EG: 172.42.159.12:12345 & 172.42.159.12:23456
Ingress generates them as
http://172.42.159.12:12345
http://172.42.159.12:23456
http://172.42.159.12:34567
http://172.42.159.12:45678
They all work fine when using the ip to access them, and they work fine when using a loadbalancer and deploying a cloud environment.
But I want this to work on my minikube, and I can't use the ../etc/hosts to assign domain names for each service ecause it does not accept the nodeports being passed in.
Any help on this is really appreciated.
so I found a solution for this.
The only way to do it is with a third-party app called Fiddler.
How To:
Download And Run Fiddler
Open Fiddler => Rules => Customize Rules
Scroll down to find static function OnBeforeRequest(oSession: Session)
Pass in
if (oSession.HostnameIs("your-domain.com")){
oSession.bypassGateway = true;
oSession["x-overrideHost"] = "minikube_ip:your_port";
}
Save File

timeout errors from Lambda when trying to access an Amazon RDS DB instance

I am writing a Python app to run as lambda function and want to connect to an RDS DB instance without making it publicly accessible.
The RDS DB instance was already created under the default VPC with security group "sg-abcd".
So I have:
created a lambda function under the same default VPC
created a role with the following permission AWSLambdaVPCAccessExecutionRole and assigned it to the lambda function as in https://docs.aws.amazon.com/lambda/latest/dg/services-rds-tutorial.html
set sg-abcd as the lambda function's security group
added sg-abcd as source in the security group's inbound rules
added the CIDR range of the lambda function's subnet as source in the security group's inbound rules
However, when I invoke the lambda function it times out.
I can connect to the RDS DB from my laptop (after setting my IP as source in the sg's inbound rules), so I now that it is not an authentication problem. Also, for the RDS DB "Publicly Accessible" is set to "Yes".
Here's part of the app's code (where I try to connect):
rds_host = "xxx.rds.amazonaws.com"
port = xxxx
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name
logger = logging.getLogger()
logger.setLevel(logging.INFO)
try:
conn = psycopg2.connect(host=rds_host, database=db_name, user=name, password=password, connect_timeout=20)
except psycopg2.Error as e:
logger.error("ERROR: Unexpected error: Could not connect to PostgreSQL instance.")
logger.error(e)
sys.exit()
I really can't understand what I am missing. Any suggestion is welcomed, please help me figure it out!
Edit: the inbound rules that I have set look like this:
Security group rule ID: sgr-123456789
Type Info: PostgreSQL
Protocol Info: TPC
Port range Info: 5432
Source: sg-abcd OR IP or CIDR range
This document should help you out. Just make sure to get the suggestions for your specific scenario, whether the lambda function and the RDS instance are in the same VPC or not.
In my case I have the lambda function and the RDS instance in the same VPC and also both have the same subnets and SGs. But just make sure to follow the instructions in that document for the configurations needed for each scenario.

Is there a way to not allocate an elastic IP (EIP) when creating a VPC using aws-cdk

I'm using the following code to create subnets that will be imported by another stack and used for a dedicated EFS VPC. If I don't create a PUBLIC subnet I get errors on creation. However the side effect is this code allocates an elastic IP address and I don't want one allocated, they are a precious resource.
How do I get rid of the elastic IP address? None of the methods allow you get anything that has an EIP attribute or method:
const fileSystemVpc = new ec2.Vpc(this, 'vpcForEfs', {
subnetConfiguration: [
{
cidrMask: 20,
name: 'nfsisolated',
subnetType: ec2.SubnetType.ISOLATED,
},
{
cidrMask: 20,
name: 'nfsprivate',
subnetType: ec2.SubnetType.PRIVATE,
},
{
cidrMask: 20,
name: 'nfspublic',
subnetType: ec2.SubnetType.PUBLIC,
},
],
});
If I comment out the PUBLIC section I get the following error on creation:
If you configure PRIVATE subnets in 'subnetConfiguration', you must also
configure PUBLIC subnets to put the NAT gateways into (got
[{"cidrMask":20,"name":"nfsisolated","subnetType":"Isolated"},
{"cidrMask":20,"name":"nfsprivate","subnetType":"Private"}].
Relevant issues that don't solve the problem but are similar:
https://github.com/aws/aws-cdk/issues/1305
https://github.com/aws/aws-cdk/issues/3704
This is the commit that added that check: https://github.com/aws/aws-cdk/commit/9a96c37b225b135c9afbf523ed3fbc67cba5ca50
Essentially if CDK wasn't stopping you with that message it would fail when CloudFormation tried to deploy the stack.
Here is more info from AWS on it as well: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html
You can see the description of the ticket that was referenced in it and the AWS docs, if whatever you want to put in the PRIVATE subnets doesn't require internet access you should be using ISOLATED instead. This is because a PRIVATE subnet requires a NatGateway and a NatGateway is required to exist in a PUBLIC subnet with an elastic IP. Again, if you don't require outbound access to the internet from your PRIVATE subnet just use ISOLATED

Cannot Delete an AWS VPC

I want to delete an AWS VPC which I don't know how it came into existence. When I try to delete it in AWS Console, it says:
We could not delete the following VPC (vpc-0a72ac71) Network interface
'eni-ce2a0d10' is currently in use. (Service: AmazonEC2; Status Code:
400; Error Code: InvalidParameterValue; Request ID:
821d8a6d-3d9b-4c24-b372-314ea9b18b23)
As it mentions "AmazonEC2" in the error message, I suspected there might be some EC2 instances residing in this VPC. So I went into EC2 dashboard but found no EC2 exist there. However, I found there are two security groups associated with this vpc. So I decided to delete them hoping that's the cause of the error. But when I tried to do so, I got this message:
As the message says, these security groups are associated with some network interfaces. Therefore, I decided to 'Detach' those but I got this error message:
Error deleting network interfaces eni-ce2a0d10: You do not have
permission to access the specified resource. eni-0b7ff712: You do not
have permission to access the specified resource.
But I'm the root user so I assume I should be able to do whatever I want to do except if the resource is made by aws itself or another root account.
I know somewhere this network interface is being used but it will be very time-consuming to go through each aws service and check that.
I've already checked AWS RDS service and no instance or rds subnet is made.
I've already checked this question and this with no luck.
I found the root cause of this issue.
Short Answer:
That VPC was created solely for the WorkDocs service instance. So AWS was preventing me to delete its VPC and any of its dependent services and pieces.
How I figured it out:
First, I noticed something interesting has been written in the 'Description' column of the 'undeletable' Network Interfaces (you can see them in the last OP's figure):
"AWS created network interface for directory d-90672d6b72."
From "directory", I suspected that this might have something do to with AWS Directory Service. So I went to this service and noticed there is a directory associated with the VPC:
So I tried to remove this directory but I got this error message:
Error - Directory cannot be deleted This directory still has
authorized applications, and cannot be deleted.  To delete this
directory, complete all of the following steps: • Delete the WorkDocs
site attached to this directory.
 
Therefore, I went to AWS WorkDocs Service and found it and deleted it:
So now the directory is also deleted (circled in red), I went back to delete those network interfaces. However I realized that they are vanished! (I guess Amazon removed them on its own). I went to VPC service to see whether I'm now able to delete the VPC. Guess what? That VPC was vanished too!
Now I understand what was happening. That VPC was created solely for the WorkDocs service instance. I wish Amazon was more transparent about it.
As a more generic answer to the "Error deleting network interface" issue, it happens when a network interface was created automatically for a higher-level AWS resource.
The Generic solution is to manage the network interface in the higher level resource directly such as WorkDocs or EFS.
In my case it happened when I wanted to delete a security group assigned to network interfaces created by an EFS volume.
So I went in the EFS console and removed the security group from the EFS.

Query on DNS & connect to existing vm

In my current code base, when i create a VM, DNS name is being dynamically set as same as the instance name. For example, consider if my VM name is "anandInstance", DNS name of the name is being generated as "anandInstance.cloudapp.net". Is there a way to change the DNS name like "dns1.cloudapp.net" during the creation thru REST API??
"Connect to existing VM" , is it possible to achieve this option through REST call? In case "connect to existing.." option , we are getting a list of vms/services to choose and VM is getting created successfully. How to achieve the same using API.
Thanks
In my current code base, when i create a VM, DNS name is being
dynamically set as same as the instance name. For example, consider if
my VM name is "anandInstance", DNS name of the name is being generated
as "anandInstance.cloudapp.net". Is there a way to change the DNS name
like "dns1.cloudapp.net" during the creation thru REST API??
I don't think it is possible. Imagine what a nightmare in the portal would become if you were able to do so? How would you link a Cloud Service (whatever.cloudapp.net) to an actual deployment (MyDemoVm123). However you can use your own domain and have CNAME records pointing to your "want-to-change-for-some-reason.cloudapp.net" (frankly I surely think that soon we will use even longer names)
"Connect to existing VM" , is it possible to achieve this option
through REST call?
Connection to a VM is essentially opening a RDP session. If it a windows VM, you can try using the Download RDP file API call. Once you get the file, just start it with "process.start". If it is linux VM, just start SSH client on port 22 (or one you have defined) from the Cloud Service DNS name you have.
UPDATE
From the azure portal,for stand alone machineoption, we are able to give the dns name with deafult cloudoneapp.net. How to do the same
through the rest api call.any specfic paramter is there to specify the
same?
When you are using the REST API, you first create a Cloud Service (still named hosted service in the REST API) where your machine will be hosted. Here you give the name for that hosted service (the dns name with deafult cloudoneapp.net). Then you call the Create Virtual Machine Deployment API action.
In case "connect to existing.." option , we are getting a list of vms/services to choose and VM is getting created successfully. How to
achieve the same using API.
When you want to get list of all VMs, just get a list of all Hosted Services, then get properties of each and make a guess whether it is a VM or a Cloud Service (maybe by querying for Properties of each service). I don't see a direct access to the list of Virtual Machines. But as this feature being PREVIEW, things might change in the future.
Hope my answer is clear?