cdk: Importing the output of an unrelated different stack - aws-cloudformation

Context:
I am making a new stack using cdk. This stack will use a vpc id that is an Output from a different stack in the same account, one which is not generated by cdk.
I am looking for the cdk equivalent of
Fn::ImportValue: ExportedName
in order to create a VPC in cdk which can then have resources attached to it.
I will then use that output to look up the VPC:
Vpc.fromVpcAttributes(this, "MyImportedVPC", VpcAttributes.builder()
.withVpcId(importedValue).build());
All the references I can find to importing values with cdk are about importing (or rather, not having to manually import) values defined in a stack which is also created by cdk. Am I missing something?

I was looking for Fn.importValue:
Fn.importValue("ExportedName")
List<String> availabilityZones = java.util.stream.Stream
.of("us-west-2a", "us-west-2b", "us-west-2c")
.collect(toList());
String privateSubnet1 = Fn.importValue("PrivateSubnet01");
String privateSubnet2 = Fn.importValue("PrivateSubnet02");
String privateSubnet3 = Fn.importValue("PrivateSubnet03");
List<String> privateSubnets = java.util.stream.Stream
.of(privateSubnet1, privateSubnet2, privateSubnet3)
.collect(toList());
VpcAttributes byId = VpcAttributes.builder()
.withVpcId(vpcId)
.withAvailabilityZones(availabilityZones)
.withPrivateSubnetIds(privateSubnets)
.build();
return Vpc.fromVpcAttributes(this, "ImportedVpc", byId);

Related

Parsing integers in serverless.yml to use MemoryDB's ClusterEndpoint.Port in Environment Variable

I'm creating a MemoryDB cluster for my serverless function, but the Port for the MemoryDB endpoint is an Integer, so when I try to set an environment variable to pass the endpoint URL to my function I get an error
Error:
Cannot resolve serverless.yml: Variables resolution errored with:
- Cannot resolve variable at "provider.environment.MEMORYDB_ENDPOINT": String value consist of variable which resolve with non-string value
Example serverless.yml file:
provider:
name: aws
# [...]
environment:
MEMORYDB_PORT: ${self:custom.MEMORYDB_PORT}
# [...]
custom:
MEMORYDB_PORT: !GetAtt MemoryDB.ClusterEndpoint.Port
I've tried with Fn::Join, Fn::Sub (plugin) and others but they all expect strings as arguments.
I'm not planning on using a custom port so I can always assume the default, however I feel like I'm missing some thing here.
Is there a way to parse integers in serverless/cloudformation somehow? Or at least convert that port into a string?
As far as I know serverless doesn't allow having functions in .yaml file, since that is just a declaration.
You could have a custom plugin: https://www.serverless.com/framework/docs/guides/plugins/custom-variables
It would looks something similar
export class MaxBatchingWindowIntParser {
public configurationVariablesSources: object;
public constructor() {
this.configurationVariablesSources = {
parseValue: {
resolve({ address }) {
return {
value: Number.parseInt(address, 10),
};
},
},
};
}
}

How to select and set a covering/covered annotation as a feature in RUTA

I have a Ruta rule that looks something like this, where dep is a DKPro imported Dependency type.
dep{}->{MyItem{->
SETFEATURE("Display", "displayedValue"),
SETFEATURE("Lemma", dep.Dependent.lemma.value),
SETFEATURE("Parent", dep.Governor)};};
The first two actions work. The problem I have is in the third action SETFEATURE("Parent", dep.Governor). dep.Governor returns a Token type but my feature requires another type that happens to share the same location as the Governor. In other words I want my own type, not dep.Governor, that has already annotated that governing word.
I am unsure how to recover an annotation (my annotation) that occupies the same space as the dep.Governor. Ideally I would like to recover it as a variable so that I can reuse it for other features to do something like this.
a:MyItem [that overlaps dep.Governor]
dep{}->{MyItem{->SETFEATURE("Parent", a)};};
Here is a more precise example
d:dep.Dependency{->
MyItem,
MyItem.Display = "Ignore",
MyItem.Lemma = d.Dependent.lemma.value,
MyItem.LanguageParent = d,
};
The line MyItem.LanguageParent = d produces this Ruta error
Trying to access value of feature "type.MyItem:LanguageParent" as "type.MyItem", but range of feature is "de.tudarmstadt.ukp.dkpro.core.api.syntax.type.dependency.Dependency"
I am sure there is a cleaner way than this, but for now, I am converting the type using a block function and saving it into an annotation variable.
BLOCK(ConvertTokenToMyItem) Token{IS(MyItem)} {
varMyItem:MyItem;
}
Then I use it
d:dep.Dependency{->
MyItem,
MyItem.Display = "Ignore",
MyItem.Lemma = d.Dependent.lemma.value,
MyItem.LanguageParent = varMyItem,
};

How to use asynchronously subnet id in pulumi which is know after 'VirtualNetwork' object created?

How to correctly use 'apply' in order to build 'ip_configurations' list using subnet id known after virtual network created ? Below gives AttributeError: 'VirtualNetwork' object has no attribute 'subnet_id'
virtual_network = azure.network.VirtualNetwork(vnet_name, name=vnet_name, resource_group_name=resource_group.name,
address_spaces=test_vnet['addr'], subnets=test_vnet['subnets'], location=resource_group.location)
ip_configurations = [{ "name": "ip-cfg", "subnet_id": virtual_network.subnet_id.apply(lambda subnet_id: virtual_network.subnets[0].id),
"privateIpAddressAllocation": "Dynamic" }]
First of all, I recommend you using a separate Subnet resource, e.g
vnet = network.VirtualNetwork(
vnet_name,
resource_group_name=resource_group.name,
address_spaces=["10.0.0.0/16"])
subnet = network.Subnet(
"subnet",
resource_group_name=resource_group.name,
address_prefix="10.0.2.0/24",
virtual_network_name=vnet.name,
enforce_private_link_endpoint_network_policies="false")
# subnet.id
You can find an example here.
If you define subnets inside VirtualNetwork, you can access ID by looking at the id property of the first item in subnets output (virtual_network.subnets[0].id).

Inner looping with Terraform

Using the Terraform (v0.9.6) GitHub Provider, how can one separately assign multiple distinct issue labels to a list of GitHub repositories while using one resource?
With another language I'd probably write something along the lines of:
for i in repos {
for j in tags[i] {
make tag j on repo i
}
}
In this example below I am adding multiple tags to a single repository. The map keys are the repos, and the values are a list of strings.:
variable "issue-labels" {
type = "map"
default = {
"repo_0" = "tag1, tag2, tag3"
"repo_1" = "tag4"
"repo_2" = "tag5, tag6"
}
}
resource "github_issue_label" "issue_labels" {
count = "${length(split(", ", join(", ", lookup(issue-labels, "my-repo"))))}"
repository = "my-repo"
name = "${element(split(", ", join(", ", lookup(issue-labels, "my-repo"))), count.index)}"
color = "FFFFFF"
}
Currently seeking an answer to what feels like an inner loop in terraform. Either finding some way to iterate through the repositories and make multiple resource counts for each, or a workaround involving interpolation to assign the right repo when we iterate through the total number of labels.
Using list variables and other complex structures to "abstract away" resources is not idiomatic and tends to lead to configuration that is hard to read and maintain.
The idiomatic style is to manage repetitive constructs using multiple instances of a child module.
For example, one can make a subdirectory called repository that contains a repository.tf file such as the following:
variable "name" {
}
variable "labels" {
type = "list"
}
# can instead use github_team_repository here if appropriate
resource "github_repository" "this" {
name = "${var.name}"
# ...
}
resource "github_issue_label" "all" {
count = "${length(var.labels)}"
repository = "${var.name}"
name = "${var.labels[count.index]}"
color = "FFFFFF"
}
Now in the root module, rather than using variables to define the set of repositories, one can instead instantiate this resource once for each repository:
module "foo_repo" {
source = "./repository"
name = "foo"
labels = ["tag1", "tag2", "tag3"]
}
module "bar_repo" {
source = "./repository"
name = "bar"
labels = ["tag4"]
}
module "baz_repo" {
source = "./repository"
name = "baz"
labels = ["tag5", "tag6"]
}
With this style, the settings for each repository are kept together in a single module block each, thus making them easy to read and update. Adding a new repository is done by adding a new module block.
This style also allows removing a single repository without disturbing all of the ones after it, since the module states are stored by the module name rather than by index into a a list.
The general recommendation here is that count should be used sparingly, and that it's usually better to write config explicitly rather than generate it via variables. The result is often easier to read and maintain, and easier to adapt over time as requirements change.

Create OpportunityProduct using REST

I'm trying to create a new OpportunityProduct using this rest call:
XRMServices/2011/OrganizationData.svc/OpportunityProductSet
{"ProductId":"ef71ce8e-1ef3-e211-b252-984be17c47e4","Quantity":123,"ProductDescription":"Added from code - TEST123","OpportunityId":"8bdb3525-7274-e311-a90b-6c3be5be5f78"}
The call returns:
The request should be a valid top-level resource object.
This indicates that my arguments is not correct. I see to possible reasons for this:
I'm missing some required properties (How can I figure out which is required?)
It is not possible to do using rest
(both guids are returned via other call and should be correct)
Any help would be great!
Thanks
Larsi
For lookup references to other entities you need to specify both the GUID and the type. You also need to include the UOM when creating an Opportunity Product based on an existing Product. Your object should look something like this:
var entity = {};
entity.Quantity = parseFloat(4).toFixed(2);
entity.OpportunityId = {
Id: '69BB2236-B57F-E311-BB6D-6C3BE5A881A4',
LogicalName: 'opportunity'
};
entity.ProductId = {
Id: 'C8138483-DF81-E311-B542-6C3BE5A8362C',
LogicalName: 'product'
};
entity.UoMId = {
Id: 'BE0FB859-7E90-4B3E-B501-3AB3CD4DC8FC',
LogicalName: 'uom'
};