-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More examples #1
Comments
Hope you don't mind, I edited your comment to make the code sample more readable. So are you just asking me for a sample in PowerShell via the awscfn module for the |
So here's the awscfn fragment that would correspond to the whole sample you provided, I'm using the typed-resource notation, which helps me identify the resource-specific parameters via IntelliSense in something like the PowerShell ISE (or even the CLI). For the sake of completeness, I've even included the metadata generated by the CFN Designer, which you wouldn't normally have to put in there if you are sticking strictly to using this tool: Template -JSON -Description "Sample for issue #1 request" -JSON {
Res-EC2-VPC SampleVPC1 -Metadata @{
"AWS::CloudFormation::Designer" = @{
id = "e61f601f-0cbc-4e51-91af-1cd3a1069ca1"
}
}
Res-EC2-VPC SampleVPC2 -Metadata @{
"AWS::CloudFormation::Designer" = @{
id = "6edcdbde-97ff-402b-bf32-4bac177f2350"
}
}
Res-EC2-Subnet VPC1Subnet1 -VpcId (Fn-Ref SampleVPC1) -DependsOn SampleVPC1 -Metadata @{
"AWS::CloudFormation::Designer" = @{
id = "461c9c16-0ca3-4365-b37c-0bf5fb37bd67"
}
}
Res-EC2-Subnet VPC2Subnet1 -VpcId (Fn-Ref SampleVPC1) -DependsOn SampleVPC1 -Metadata @{
"AWS::CloudFormation::Designer" = @{
id = "461c9c16-0ca3-4365-b37c-0bf5fb37bd67"
}
}
} |
UPDATE: THIS IS WRONG, UPDATED IN LATER COMMENT BELOW! If you take out the unnecessary Designer meta data, it becomes more compact. Here's another sample that fills out your JSON fragment with a few property parameters to the resources you provided to make it a bit more real-world: Template -JSON -Description "Sample for issue #1 request" {
Res-EC2-VPC SampleVPC1 -CidrBlock 10.10.0.0/16 `
-InstanceTenancy dedicated `
-EnableDnsSupport $true `
-Tags @{
MyNote = "Production network"
}
Res-EC2-VPC SampleVPC2 -CidrBlock 10.20.0.0/16 `
-Tags @{
MyNote = "Development network"
}
Res-EC2-Subnet VPC1Subnet1 -DependsOn SampleVPC1 `
-VpcId (Fn-Ref SampleVPC1) `
-AvailabilityZone us-east-1a -CidrBlock 10.10.1.0/24 `
-Tags @{
MyNote = "Public VLAN (PROD)"
}
Res-EC2-Subnet VPC2Subnet1 -DependsOn SampleVPC2 `
-VpcId (Fn-Ref SampleVPC2) `
-AvailabilityZone 10.20.1.0/24 `
-Tags @{
MyNote = "Public VLAN (DEV)"
}
} And here's the corresponding JSON that's spit out if you just execute the template as-is (provided you gave it the {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Sample for issue #1 request",
"Resources": {
"SampleVPC1": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.10.0.0/16",
"EnableDnsSupport": true,
"InstanceTenancy": "dedicated",
"Tags": [
{
"Key": "MyNote",
"Value": "Production network"
}
]
}
},
"SampleVPC2": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.20.0.0/16",
"Tags": [
{
"Key": "MyNote",
"Value": "Development network"
}
]
}
},
"VPC1Subnet1": {
"Type": "AWS::EC2::Subnet",
"DependsOn": [
"SampleVPC1"
],
"Properties": {
"AvailabilityZone": "us-east-1a",
"CidrBlock": "10.10.1.0/24",
"Tags": [
{
"Key": "MyNote",
"Value": "Public VLAN (PROD)"
}
],
"VpcId": "System.Collections.Hashtable"
}
},
"VPC2Subnet1": {
"Type": "AWS::EC2::Subnet",
"DependsOn": [
"SampleVPC2"
],
"Properties": {
"AvailabilityZone": "10.20.1.0/24",
"Tags": [
{
"Key": "MyNote",
"Value": "Public VLAN (DEV)"
}
],
"VpcId": "System.Collections.Hashtable"
}
}
}
} |
In most cases, the properties that have a fixed list of values, such as the
|
Awesome, that makes a lot more sense. I don't particularly need the cloudformation designer metadata but it's a good example if I need to ever throw that kind of information against a resource. A few things though
Either way it's makes a lot more sense now using the |
Regarding (1) -- that's a great point, I never did update the version published to the gallery with the latest release. I'm working on some CI automations that should help keep this updated and more current. I'll be sure to publish the latest version to the gallery soon, as well as update to include the latest changes from the CloudFormation schema. |
Regarding (2) -- DOH! I messed up with the sample above, I mixed the "typed-resource" style and the raw cmdlet style. I'm providing the updated and corrected sample from above here: Template -JSON -Description "Sample for issue #1 request" {
Res-EC2-VPC SampleVPC1 -CidrBlock 10.10.0.0/16 {
Property InstanceTenancy dedicated
Property EnableDnsSupport $true
Tag MyNote "Production network"
}
Res-EC2-VPC SampleVPC2 -CidrBlock 10.20.0.0/16 {
Tag MyNote "Development network"
}
Res-EC2-Subnet VPC1Subnet1 -DependsOn SampleVPC1 {
Property VpcId (Fn-Ref SampleVPC1)
Property AvailabilityZone us-east-1a
Property CidrBlock 10.10.1.0/24
Tag MyNote "Public VLAN (PROD)"
}
Res-EC2-Subnet VPC2Subnet1 -DependsOn SampleVPC2 {
Property VpcId (Fn-Ref SampleVPC2)
Property AvailabilityZone 10.20.1.0/24
Tag MyNote "Public VLAN (DEV)"
}
} As you can see, this is more in keeping with the idea of a declarative DSV or mini-language. And here is the generated output: {
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Sample for issue #1 request",
"Resources": {
"SampleVPC1": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.10.0.0/16",
"InstanceTenancy": "dedicated",
"EnableDnsSupport": true,
"Tags": [
{
"Key": "MyNote",
"Value": "Production network"
}
]
}
},
"SampleVPC2": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "10.20.0.0/16",
"Tags": [
{
"Key": "MyNote",
"Value": "Development network"
}
]
}
},
"VPC1Subnet1": {
"Type": "AWS::EC2::Subnet",
"DependsOn": [
"SampleVPC1"
],
"Properties": {
"VpcId": {
"Ref": "SampleVPC1"
},
"AvailabilityZone": "us-east-1a",
"CidrBlock": "10.10.1.0/24",
"Tags": [
{
"Key": "MyNote",
"Value": "Public VLAN (PROD)"
}
]
}
},
"VPC2Subnet1": {
"Type": "AWS::EC2::Subnet",
"DependsOn": [
"SampleVPC2"
],
"Properties": {
"VpcId": {
"Ref": "SampleVPC2"
},
"AvailabilityZone": "10.20.1.0/24",
"Tags": [
{
"Key": "MyNote",
"Value": "Public VLAN (DEV)"
}
]
}
}
}
} |
Awesome! I appreciate your time helping me with this. I'm trying to keep the stack as generic as possible so it can be re-used as a working example in the repo's wiki or something. What I've got so far is: $trustrelationship = @'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
'@
$template = New-CfnTemplate -JSON -Description 'Sample for issue #1 request' -TemplateBlock {
Add-CfnEC2_VPCResource -ResourceName ProdVPC -CidrBlock 10.10.0.0/16 -PropertiesBlock {
Set-CfnResourceProperty -Name InstanceTenancy -Value default
Set-CfnResourceProperty -Name EnableDnsSupport -Value $true
Set-CfnResourceTag -TagKey Name -Value 'Production'
}
Add-CfnEC2_VPCResource -ResourceName DevVPC -CidrBlock 10.20.0.0/16 -PropertiesBlock {
Set-CfnResourceProperty -Name InstanceTenancy -Value default
Set-CfnResourceProperty -Name EnableDnsSupport -Value $true
Set-CfnResourceTag -TagKey Name -Value 'Development'
}
Add-CfnEC2_SubnetResource -ResourceName VPC1Subnet1 -DependsOn ProdVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName ProdVPC)
Set-CfnResourceProperty -Name AvailabilityZone -Value ap-southeast-2a
Set-CfnResourceProperty -Name MapPublicIpOnLaunch -Value $true
Set-CfnResourceProperty -Name CidrBlock -Value 10.10.1.0/24
Set-CfnResourceTag -TagKey Name -Value 'Public (PROD)'
}
Add-CfnEC2_SubnetResource -ResourceName VPC2Subnet1 -DependsOn DevVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName DevVPC)
Set-CfnResourceProperty -Name CidrBlock -Value 10.20.1.0/24
Set-CfnResourceProperty -Name AvailabilityZone -Value ap-southeast-2b
Set-CfnResourceTag -TagKey Name -Value 'Public (DEV)'
}
Add-CfnEC2_SubnetResource -ResourceName VPC1Subnet2 -DependsOn ProdVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName ProdVPC)
Set-CfnResourceProperty -Name AvailabilityZone -Value ap-southeast-2b
Set-CfnResourceProperty -Name MapPublicIpOnLaunch -Value $true
Set-CfnResourceProperty -Name CidrBlock -Value 10.10.2.0/24
Set-CfnResourceTag -TagKey Name -Value 'Private (PROD)'
}
Add-CfnEC2_SubnetResource -ResourceName VPC2Subnet2 -DependsOn DevVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName DevVPC)
Set-CfnResourceProperty -Name CidrBlock -Value 10.20.2.0/24
Set-CfnResourceProperty -Name AvailabilityZone -Value ap-southeast-2c
Set-CfnResourceTag -TagKey Name -Value 'Private (DEV)'
}
Add-CfnEC2_RouteTableResource -ResourceName ProdVPCPublicRouteTable -DependsOn ProdVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName ProdVPC)
Set-CfnResourceTag -TagKey Name -Value 'Public (PROD)'
}
Add-CfnEC2_RouteTableResource -ResourceName DevVPCPublicRouteTable -DependsOn DevVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName DevVPC)
Set-CfnResourceTag -TagKey Name -Value 'Public (DEV)'
}
Add-CfnEC2_RouteTableResource -ResourceName ProdVPCPrivateRouteTable -DependsOn ProdVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName ProdVPC)
Set-CfnResourceTag -TagKey Name -Value 'Private (PROD)'
}
Add-CfnEC2_RouteTableResource -ResourceName DevVPCPrivateRouteTable -DependsOn DevVPC -PropertiesBlock {
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName DevVPC)
Set-CfnResourceTag -TagKey Name -Value 'Private (DEV)'
}
Add-CfnEC2_SubnetRouteTableAssociationResource -ResourceName ProdVPCPublicRouteTableAssoc `
-DependsOn ProdVPCPublicRouteTable -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName ProdVPCPublicRouteTable)
Set-CfnResourceProperty -Name SubnetId -Value (Use-CfnRefFunction -LogicalName VPC1Subnet1)
}
Add-CfnEC2_SubnetRouteTableAssociationResource -ResourceName DevVPCPublicRouteTableAssoc `
-DependsOn DevVPCPublicRouteTable -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName DevVPCPublicRouteTable)
Set-CfnResourceProperty -Name SubnetId -Value (Use-CfnRefFunction -LogicalName VPC2Subnet1)
}
Add-CfnEC2_SubnetRouteTableAssociationResource -ResourceName ProdVPCPrivateRouteTableAssoc `
-DependsOn ProdVPCPrivateRouteTable -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName ProdVPCPrivateRouteTable)
Set-CfnResourceProperty -Name SubnetId -Value (Use-CfnRefFunction -LogicalName VPC1Subnet2)
}
Add-CfnEC2_SubnetRouteTableAssociationResource -ResourceName DevVPCPrivateRouteTableAssoc `
-DependsOn DevVPCPrivateRouteTable -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName DevVPCPrivateRouteTable)
Set-CfnResourceProperty -Name SubnetId -Value (Use-CfnRefFunction -LogicalName VPC2Subnet2)
}
Add-CfnEC2_InternetGatewayResource -ResourceName ProdVPCIGW -DependsOn ProdVPC -PropertiesBlock {
Set-CfnResourceTag -TagKey Name -Value 'Production'
}
Add-CfnEC2_InternetGatewayResource -ResourceName DevVPCIGW -DependsOn DevVPC -PropertiesBlock {
Set-CfnResourceTag -TagKey Name -Value 'Development'
}
Add-CfnEC2_VPCGatewayAttachmentResource -ResourceName ProdVPCIGWAttach -DependsOn ProdVPCIGW -PropertiesBlock {
Set-CfnResourceProperty -Name InternetGatewayId -Value (Use-CfnRefFunction -LogicalName ProdVPCIGW)
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName ProdVPC)
}
Add-CfnEC2_VPCGatewayAttachmentResource -ResourceName DevVPCIGWAttach -DependsOn DevVPCIGW -PropertiesBlock {
Set-CfnResourceProperty -Name InternetGatewayId -Value (Use-CfnRefFunction -LogicalName DevVPCIGW)
Set-CfnResourceProperty -Name VpcId -Value (Use-CfnRefFunction -LogicalName DevVPC)
}
Add-CfnEC2_EIPResource -ResourceName ProdVPCNGWEIP -Domain vpc
Add-CfnEC2_EIPResource -ResourceName DevVPCNGWEIP -Domain vpc
Add-CfnEC2_NatGatewayResource -ResourceName ProdVPCNGW -DependsOn ProdVPCNGWEIP -PropertiesBlock {
Set-CfnResourceProperty -Name AllocationId -Value (Use-CfnGetAttFunction -ResourceName ProdVPCNGWEIP `
-AttributeName AllocationId)
Set-CfnResourceProperty -Name SubnetId -Value (Use-CfnRefFunction -LogicalName VPC1Subnet2)
}
Add-CfnEC2_NatGatewayResource -ResourceName DevVPCNGW -DependsOn DevVPCNGWEIP -PropertiesBlock {
Set-CfnResourceProperty -Name AllocationId -Value (Use-CfnGetAttFunction -ResourceName DevVPCNGWEIP `
-AttributeName AllocationId)
Set-CfnResourceProperty -Name SubnetId -Value (Use-CfnRefFunction -LogicalName VPC2Subnet2)
}
Add-CfnEC2_RouteResource -ResourceName ProdVPCPublicRoute -DependsOn ProdVPCIGW -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName ProdVPCPublicRouteTable)
Set-CfnResourceProperty -Name DestinationCidrBlock -Value '0.0.0.0/0'
Set-CfnResourceProperty -Name GatewayId -Value (Use-CfnRefFunction -LogicalName ProdVPCIGW)
}
Add-CfnEC2_RouteResource -ResourceName DevVPCPublicRoute -DependsOn DevVPCIGW -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName DevVPCPublicRouteTable)
Set-CfnResourceProperty -Name DestinationCidrBlock -Value '0.0.0.0/0'
Set-CfnResourceProperty -Name GatewayId -Value (Use-CfnRefFunction -LogicalName DevVPCIGW)
}
Add-CfnEC2_RouteResource -ResourceName ProdVPCPrivateRoute -DependsOn ProdVPCNGW -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName ProdVPCPrivateRouteTable)
Set-CfnResourceProperty -Name DestinationCidrBlock -Value '0.0.0.0/0'
Set-CfnResourceProperty -Name NatGatewayId -Value (Use-CfnRefFunction -LogicalName ProdVPCNGW)
}
Add-CfnEC2_RouteResource -ResourceName DevVPCPrivateRoute -DependsOn DevVPCNGW -PropertiesBlock {
Set-CfnResourceProperty -Name RouteTableId -Value (Use-CfnRefFunction -LogicalName DevVPCPrivateRouteTable)
Set-CfnResourceProperty -Name DestinationCidrBlock -Value '0.0.0.0/0'
Set-CfnResourceProperty -Name NatGatewayId -Value (Use-CfnRefFunction -LogicalName DevVPCNGW)
}
Add-CfnIAM_RoleResource -ResourceName AutomationRole -AssumeRolePolicyDocument $trustrelationship -Path /
Add-CfnIAM_InstanceProfileResource -ResourceName AutomationRoleProfile -Path / -PropertiesBlock {
Set-CfnResourceProperty -Name Roles -Value (Use-CfnRefFunction -LogicalName AutomationRole)
}
}
#New-CFNStack -StackName Stack1 -TemplateBody $template -Capability CAPABILITY_IAM, CAPABILITY_NAMED_IAM
Update-CFNStack -StackName Stack1 -TemplateBody $template -Capability CAPABILITY_IAM, CAPABILITY_NAMED_IAM
$template | Out-File -FilePath C:\Temp\CFjson.txt The VPC stuff all deploys with no issues. What I'm trying to match give or take is the examples here: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html:
"RootInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ {
"Ref": "RootRole"
} ]
}
} Add-CfnIAM_InstanceProfileResource -ResourceName AutomationRoleProfile -Path / -Roles (Use-CfnRefFunction -LogicalName AutomationRole) Gets the closest but then has the same problem as above where it then attempts to output the hashtable "AutomationRoleProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [
"System.Collections.Hashtable"
]
}
} Any idea how I can get it to format the InstanceProfile to match the example? |
Here is the AwsCfn version of the first example (titled "IAM Role with Embedded Policy and Instance Profiles") from that link: Template -JSON {
Res-IAM-Role RootRole -AssumeRolePolicyDocument @{
Version = "2012-10-07"
Statement = @(
@{
Effect = "Allow"
Principal = @{
Service = @("ec2.amazonaws.com")
}
Action = @("sts:AssumeRole")
}
)
} -Path "/" -Policies @(
[ordered]@{
PolicyName = "root"
PolicyDocument = @{
Version = "2012-10-17"
Statement = @(
[ordered]@{
Effect = "Allow"
Action = "*"
Resource = "*"
}
)
}
}
)
Res-IAM-InstanceProfile RootInstanceProfile -Path "/" {
Property Roles @(
(Fn-Ref RootRole)
)
}
} And here is the JSON it produces: {
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"RootRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-07",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
}
]
}
},
"RootInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [
{
"Ref": "RootRole"
}
]
}
}
}
} Since the policy and policy document properties of the resource types are of type If the property types are more specific types, for example strings or ints or bools, then you need to use the nested property syntax as I have up above in the earlier comments, such as the following fragment which is equivalent to inline property syntax but uses nested properties instead: Template -JSON {
Res-IAM-Role RootRole {
Property AssumeRolePolicyDocument @{
Version = "2012-10-07"
Statement = @(
@{
Effect = "Allow"
Principal = @{
Service = @("ec2.amazonaws.com")
}
Action = @("sts:AssumeRole")
}
)
} |
Awesome. That makes sense now and works a treat. One last question (hopefully!). Maybe I'm looking in the wrong places but some things appear to be missing.
Add-CfnOutput -Description 'Outputs the ID of the Prod VPC' -OutputName ProdVPCOutput `
-Value (Use-CfnRefFunction -LogicalName ProdVPC) What I am doing is nesting stacks and what I need to do is export the VPCID and subnet ID's from the VPC stack then import them in to the EC2 stack but as far as I know I can do cross stack imports without the above. I'm going to guess it probably ties back to issue #2? The schema from http://vstoolkit.amazonwebservices.com/CloudFormationSchema/CloudFormationV1.schema has all of the above that I need. I assumed just throwing that in to the gen folder and running the generate scripts would be sufficient but there appears to be a bit more to it. |
You are correct, the current version is missing some of the recent enhancements to the CFN vocabulary. Some of these have only just recently been added to the V1 schema and I have not had time to incorporate them yet. However, AWS has just announced (just yesterday, actually) that they're publishing a machine-digestible CFN Resource Specification that defines the whole of the CFN vocabulary and I'm hoping with this change they'll be releasing timely updates. I'm working on digesting this new spec now so my plan is to have something updated very soon. In the meantime you can actually fallback to the generic Resource directive -- it does't offer the strict type-checking but it gives you a default way to add any resource that hasn't been explicitly defined into your CFN template. |
@theonlyway -- can I ask, what version of PowerShell are you using? |
It should be 5.1 |
Hi,
I've just recently started looking in to trying to create some cloudformation templates using PowerShell and stumbled over this module. On the surface it looks great but I'm having some issues trying to figure some of the stuff out.
Using the Cloudformation designer it's pretty easy to create resources and their discrepancies.
Example
Which ends up looking something like this
Are you able to give me some examples of how to get the module to generate the
"Ref": "SampleVPC2"
?Thanks
Anthony
The text was updated successfully, but these errors were encountered: